1use core::sync::atomic::AtomicU32;
2
3use crate::errno::EINVAL;
4use crate::synch::futex::{self as synch, Flags};
5use crate::time::timespec;
6
7#[hermit_macro::system]
14#[unsafe(no_mangle)]
15pub unsafe extern "C" fn sys_futex_wait(
16 address: *mut u32,
17 expected: u32,
18 timeout: *const timespec,
19 flags: u32,
20) -> i32 {
21 if address.is_null() {
22 return -EINVAL;
23 }
24
25 let address = unsafe { &*(address as *const AtomicU32) };
26 let timeout = if timeout.is_null() {
27 None
28 } else {
29 match unsafe { timeout.read().into_usec() } {
30 Some(usec) if usec >= 0 => Some(usec as u64),
31 _ => return -EINVAL,
32 }
33 };
34 let Some(flags) = Flags::from_bits(flags) else {
35 return -EINVAL;
36 };
37
38 synch::futex_wait(address, expected, timeout, flags)
39}
40
41#[hermit_macro::system]
47#[unsafe(no_mangle)]
48pub unsafe extern "C" fn sys_futex_wake(address: *mut u32, count: i32) -> i32 {
49 if address.is_null() {
50 return -EINVAL;
51 }
52
53 synch::futex_wake(address as *const AtomicU32, count)
54}