1 // From https://www.remlab.net/op/futex-misc.shtml 2 //TODO: improve implementation 3 4 use crate::platform::{types::*, Pal, Sys}; 5 use super::AtomicLock; 6 use core::sync::atomic::Ordering; 7 8 pub struct Semaphore { 9 lock: AtomicLock, 10 } 11 12 impl Semaphore { 13 pub const fn new(value: c_int) -> Self { 14 Self { 15 lock: AtomicLock::new(value), 16 } 17 } 18 19 pub fn post(&self) { 20 self.lock.fetch_add(1, Ordering::Relaxed); 21 self.lock.notify_one(); 22 } 23 24 pub fn wait(&self) { 25 let mut value = 1; 26 27 loop { 28 match self.lock.compare_exchange_weak( 29 value, 30 value - 1, 31 Ordering::Acquire, 32 Ordering::Relaxed 33 ) { 34 Ok(ok) => return, 35 Err(err) => { 36 value = err; 37 } 38 } 39 40 if value == 0 { 41 self.lock.wait_if(0); 42 value = 1; 43 } 44 } 45 } 46 } 47