1use core::{
2 cell::UnsafeCell,
3 mem::MaybeUninit,
4 sync::atomic::{AtomicU32 as AtomicUint, Ordering},
5};
6
7#[derive(Debug)]
10pub struct Waitval<T> {
11 state: AtomicUint,
12 value: UnsafeCell<MaybeUninit<T>>,
13}
14
15unsafe impl<T: Send + Sync> Send for Waitval<T> {}
16unsafe impl<T: Send + Sync> Sync for Waitval<T> {}
17
18impl<T> Waitval<T> {
19 #[allow(clippy::new_without_default)]
20 pub const fn new() -> Self {
21 Self {
22 state: AtomicUint::new(0),
23 value: UnsafeCell::new(MaybeUninit::uninit()),
24 }
25 }
26
27 pub unsafe fn post(&self, value: T) {
30 unsafe { self.value.get().write(MaybeUninit::new(value)) };
31 self.state.store(1, Ordering::Release);
32 crate::sync::futex_wake(&self.state, i32::MAX);
33 }
34
35 pub fn wait(&self) -> &T {
36 while self.state.load(Ordering::Acquire) == 0 {
37 crate::sync::futex_wait(&self.state, 0, None);
38 }
39
40 unsafe { (*self.value.get()).assume_init_ref() }
41 }
42}