message: Fix semaphore deadlocks
diff: @@ -6,9 +6,14 @@ use syscall;
  use platform::types::{c_int, c_uint, c_void};
  +pub struct Semaphore {
  + lock: i32,
  + count: i32,
  +}
  +
  type pte_osThreadHandle = usize;
  type pte_osMutexHandle = *mut i32;
  -type pte_osSemaphoreHandle = *mut i32;
  +type pte_osSemaphoreHandle = *mut Semaphore;
  type pte_osThreadEntryPoint = unsafe extern "C" fn(params: *mut c_void) -> c_int;
  #[repr(C)]
  @@ -151,7 +156,7 @@ pub unsafe extern "C" fn pte_osThreadCheckCancel(handle: pte_osThreadHandle) ->
  pub unsafe extern "C" fn pte_osThreadSleep(msecs: c_uint) {
  let tm = syscall::TimeSpec {
  tv_sec: msecs as i64 / 1000,
  - tv_nsec: (msecs as i32 % 1000) * 1000,
  + tv_nsec: (msecs % 1000) as i32 * 1000000,
  };
  let mut rmtp = mem::uninitialized();
  let _ = syscall::nanosleep(&tm, &mut rmtp);
  @@ -265,7 +270,10 @@ pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle semHandle, uns
  #[no_mangle]
  pub unsafe extern "C" fn pte_osSemaphoreCreate(initialValue: c_int, pHandle: *mut pte_osSemaphoreHandle) -> pte_osResult {
  - *pHandle = Box::into_raw(Box::new(initialValue));
  + *pHandle = Box::into_raw(Box::new(Semaphore {
  + lock: 0,
  + count: initialValue,
  + }));
  PTE_OS_OK
  }
  @@ -277,21 +285,26 @@ pub unsafe extern "C" fn pte_osSemaphoreDelete(handle: pte_osSemaphoreHandle) ->
  #[no_mangle]
  pub unsafe extern "C" fn pte_osSemaphorePost(handle: pte_osSemaphoreHandle, count: c_int) -> pte_osResult {
  - if intrinsics::atomic_xadd(handle, 1) <= 0 {
  - while match syscall::futex(handle, syscall::FUTEX_WAKE, 1, 0, ptr::null_mut()) {
  - Ok(waiters) => waiters < 1,
  - Err(err) => return PTE_OS_GENERAL_FAILURE,
  - } {
  - syscall::sched_yield();
  - }
  - }
  + let semaphore = &mut *handle;
  + pte_osMutexLock(&mut semaphore.lock);
  + intrinsics::atomic_xadd(&mut semaphore.count, 1);
  + pte_osMutexUnlock(&mut semaphore.lock);
  PTE_OS_OK
  }
  #[no_mangle]
  pub unsafe extern "C" fn pte_osSemaphorePend(handle: pte_osSemaphoreHandle, pTimeout: *mut c_uint) -> pte_osResult {
  - if intrinsics::atomic_xsub(handle, 1) < 0 {
  - let _ = syscall::futex(handle, syscall::FUTEX_WAIT, *handle, 0, ptr::null_mut());
  + //TODO: pTimeout
  + let semaphore = &mut *handle;
  + let mut acquired = false;
  + while ! acquired {
  + pte_osMutexLock(&mut semaphore.lock);
  + if intrinsics::atomic_load(&mut semaphore.count) > 0 {
  + intrinsics::atomic_xsub(&mut semaphore.count, 1);
  + acquired = true;
  + }
  + pte_osMutexUnlock(&mut semaphore.lock);
  + let _ = syscall::sched_yield();
  }
  PTE_OS_OK
  }
  