wasmer_wasix/syscalls/wasix/
futex_wake_all.rs

1use super::*;
2use crate::syscalls::*;
3
4/// Wake up all threads that are waiting on futex_wait on this futex.
5///
6/// ## Parameters
7///
8/// * `futex` - Memory location that holds a futex that others may be waiting on
9#[instrument(level = "trace", skip_all, fields(futex_idx = field::Empty, woken = field::Empty), ret)]
10pub fn futex_wake_all<M: MemorySize>(
11    mut ctx: FunctionEnvMut<'_, WasiEnv>,
12    futex_ptr: WasmPtr<u32, M>,
13    ret_woken: WasmPtr<Bool, M>,
14) -> Result<Errno, WasiError> {
15    WasiEnv::do_pending_operations(&mut ctx)?;
16
17    let env = ctx.data();
18    let memory = unsafe { env.memory_view(&ctx) };
19    let state = env.state.deref();
20
21    let pointer: u64 = futex_ptr.offset().into();
22    //Span::current().record("futex_idx", pointer);
23
24    let mut woken = false;
25    let woken = {
26        let mut guard = state.futexs.lock().unwrap();
27        if let Some(futex) = guard.futexes.remove(&pointer) {
28            for waker in futex.wakers {
29                if let Some(waker) = waker.1 {
30                    waker.wake();
31                }
32            }
33            tracing::trace!("wake_all (hit) on {pointer}");
34            true
35        } else {
36            tracing::trace!("wake_all (miss) on {pointer}");
37            true
38        }
39    };
40    //Span::current().record("woken", woken);
41
42    let woken = match woken {
43        false => Bool::False,
44        true => Bool::True,
45    };
46    wasi_try_mem_ok!(ret_woken.write(&memory, woken));
47    Ok(Errno::Success)
48}