|  | @@ -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
 | 
	
		
			
				|  |  |  }
 |