1 use crate::ffi::c_void;
3 use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
4 use crate::sys::hermit::abi;
5 use crate::sys::mutex::Mutex;
6 use crate::time::Duration;
8 // The implementation is inspired by Andrew D. Birrell's paper
9 // "Implementing Condition Variables with Semaphores"
17 unsafe impl Send for Condvar {}
18 unsafe impl Sync for Condvar {}
21 pub const fn new() -> Condvar {
22 Condvar { counter: AtomicUsize::new(0), sem1: ptr::null(), sem2: ptr::null() }
25 pub unsafe fn init(&mut self) {
26 let _ = abi::sem_init(&mut self.sem1 as *mut *const c_void, 0);
27 let _ = abi::sem_init(&mut self.sem2 as *mut *const c_void, 0);
30 pub unsafe fn notify_one(&self) {
31 if self.counter.load(SeqCst) > 0 {
32 self.counter.fetch_sub(1, SeqCst);
33 abi::sem_post(self.sem1);
34 abi::sem_timedwait(self.sem2, 0);
38 pub unsafe fn notify_all(&self) {
39 let counter = self.counter.swap(0, SeqCst);
41 abi::sem_post(self.sem1);
44 abi::sem_timedwait(self.sem2, 0);
48 pub unsafe fn wait(&self, mutex: &Mutex) {
49 self.counter.fetch_add(1, SeqCst);
51 abi::sem_timedwait(self.sem1, 0);
52 abi::sem_post(self.sem2);
56 pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
57 panic!("wait_timeout not supported on hermit");
60 pub unsafe fn destroy(&self) {
61 let _ = abi::sem_destroy(self.sem1);
62 let _ = abi::sem_destroy(self.sem2);