message: Use futex again for semaphore
diff: @@ -13,7 +13,6 @@ pub struct Semaphore {
  lock: AtomicLock,
  }
  -//TODO: fix to use futex again
  impl Semaphore {
  pub const fn new(value: c_int) -> Self {
  Self {
  @@ -23,10 +22,12 @@ impl Semaphore {
  pub fn post(&self, count: c_int) {
  self.lock.fetch_add(count, Ordering::SeqCst);
  + self.lock.notify_all();
  }
  - pub fn try_wait(&self) -> Result<(), ()> {
  - let mut value = self.lock.load(Ordering::SeqCst);
  + pub fn wait(&self, timeout_opt: Option<&timespec>) -> Result<(), ()> {
  + loop {
  + let value = self.lock.load(Ordering::SeqCst);
  if value > 0 {
  match self.lock.compare_exchange(
  value,
  @@ -34,22 +35,14 @@ impl Semaphore {
  Ordering::SeqCst,
  Ordering::SeqCst
  ) {
  - Ok(_) => Ok(()),
  - Err(_) => Err(())
  - }
  - } else {
  - Err(())
  - }
  - }
  -
  - pub fn wait(&self, timeout_opt: Option<&timespec>) -> Result<(), ()> {
  -
  - loop {
  - match self.try_wait() {
  - Ok(()) => {
  + Ok(_) => {
  + // Acquired
  return Ok(());
  }
  - Err(()) => ()
  + Err(_) => ()
  + }
  + // Try again (as long as value > 0)
  + continue;
  }
  if let Some(timeout) = timeout_opt {
  let mut time = timespec::default();
  @@ -57,10 +50,26 @@ impl Semaphore {
  if (time.tv_sec > timeout.tv_sec) ||
  (time.tv_sec == timeout.tv_sec && time.tv_nsec >= timeout.tv_nsec)
  {
  + //Timeout happened, return error
  return Err(())
  + } else {
  + // Use futex to wait for the next change, with a relative timeout
  + let mut relative = timespec {
  + tv_sec: timeout.tv_sec,
  + tv_nsec: timeout.tv_nsec,
  + };
  + while relative.tv_nsec < time.tv_nsec {
  + relative.tv_sec -= 1;
  + relative.tv_nsec += 1_000_000_000;
  + }
  + relative.tv_sec -= time.tv_sec;
  + relative.tv_nsec -= time.tv_nsec;
  + self.lock.wait_if(value, Some(&relative));
  }
  + } else {
  + // Use futex to wait for the next change, without a timeout
  + self.lock.wait_if(value, None);
  }
  - Sys::sched_yield();
  }
  }
  }
  