semaphore.rs 1.0 KB

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