wasmer_wasix/syscalls/wasix/
futex_wake.rs1use super::*;
2use crate::syscalls::*;
3
4#[instrument(level = "trace", skip_all, fields(futex_idx = field::Empty, woken = field::Empty), ret)]
12pub fn futex_wake<M: MemorySize>(
13 mut ctx: FunctionEnvMut<'_, WasiEnv>,
14 futex_ptr: WasmPtr<u32, M>,
15 ret_woken: WasmPtr<Bool, M>,
16) -> Result<Errno, WasiError> {
17 WasiEnv::do_pending_operations(&mut ctx)?;
18
19 let env = ctx.data();
20 let memory = unsafe { env.memory_view(&ctx) };
21 let state = env.state.deref();
22
23 let pointer: u64 = futex_ptr.offset().into();
24 Span::current().record("futex_idx", pointer);
25
26 let mut woken = false;
27 let woken = {
28 let mut guard = state.futexs.lock().unwrap();
29 if let Some(futex) = guard.futexes.get_mut(&pointer) {
30 let first = futex.wakers.keys().copied().next();
31 if let Some(id) = first {
32 if let Some(Some(w)) = futex.wakers.remove(&id) {
33 w.wake();
34 }
35 }
36 if futex.wakers.is_empty() {
37 guard.futexes.remove(&pointer);
38 }
39 tracing::trace!("wake(hit) on {pointer}");
40 true
41 } else {
42 tracing::trace!("wake(miss) on {pointer}");
43 true
44 }
45 };
46 Span::current().record("woken", woken);
47
48 let woken = match woken {
49 false => Bool::False,
50 true => Bool::True,
51 };
52 wasi_try_mem_ok!(ret_woken.write(&memory, woken));
53
54 Ok(Errno::Success)
55}