2
0

semaphore.rs 993 B

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