rustix_futex_sync/
futex_condvar.rs1use core::sync::atomic::{AtomicU32, Ordering::Relaxed};
6use super::wait_wake::{futex_wait, futex_wake, futex_wake_all};
7use core::time::Duration;
8use super::generic::RawMutex;
9use super::lock_api::RawMutex as _;
10
11#[repr(transparent)]
12pub struct Condvar<const SHM: bool> {
13 futex: AtomicU32,
17}
18
19impl<const SHM: bool> Condvar<SHM> {
20 #[inline]
21 pub const fn new() -> Self {
22 Self { futex: AtomicU32::new(0) }
23 }
24
25 pub fn notify_one(&self) {
29 self.futex.fetch_add(1, Relaxed);
30 futex_wake::<SHM>(&self.futex);
31 }
32
33 pub fn notify_all(&self) {
34 self.futex.fetch_add(1, Relaxed);
35 futex_wake_all::<SHM>(&self.futex);
36 }
37
38 pub unsafe fn wait(&self, mutex: &RawMutex<SHM>) {
39 self.wait_optional_timeout(mutex, None);
40 }
41
42 pub unsafe fn wait_timeout(&self, mutex: &RawMutex<SHM>, timeout: Duration) -> bool {
43 self.wait_optional_timeout(mutex, Some(timeout))
44 }
45
46 unsafe fn wait_optional_timeout(&self, mutex: &RawMutex<SHM>, timeout: Option<Duration>) -> bool {
47 let futex_value = self.futex.load(Relaxed);
49
50 mutex.unlock();
52
53 let r = futex_wait::<SHM>(&self.futex, futex_value, timeout);
56
57 mutex.lock();
59
60 r
61 }
62}