// From https://www.remlab.net/op/futex-misc.shtml //TODO: improve implementation use super::AtomicLock; use crate::platform::{types::*, Pal, Sys}; use core::sync::atomic::Ordering; pub struct Semaphore { lock: AtomicLock, } impl Semaphore { pub const fn new(value: c_int) -> Self { Self { lock: AtomicLock::new(value), } } pub fn post(&self) { self.lock.fetch_add(1, Ordering::Relaxed); self.lock.notify_one(); } pub fn wait(&self) { let mut value = 1; loop { match self.lock.compare_exchange_weak( value, value - 1, Ordering::Acquire, Ordering::Relaxed, ) { Ok(ok) => return, Err(err) => { value = err; } } if value == 0 { self.lock.wait_if(0); value = 1; } } } }