diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 4b92fc2c4b7894262bf500161ac9e6d0a00cf125..3c94ef972e65dc156450077c6a44fc50f0151824 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -207,8 +207,8 @@ impl Pal for Sys { e(unsafe { syscall!(FTRUNCATE, fildes, length) }) as c_int } - fn futex(addr: *mut c_int, op: c_int, val: c_int) -> c_int { - unsafe { syscall!(FUTEX, addr, op, val, 0, 0, 0) as c_int } + fn futex(addr: *mut c_int, op: c_int, val: c_int, val2: usize) -> c_int { + unsafe { syscall!(FUTEX, addr, op, val, val2, 0, 0) as c_int } } fn futimens(fd: c_int, times: *const timespec) -> c_int { diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs index 73f32b1a1566521ce82bc84aa4fabdc97009c426..66cae57e81ff9184b0dbc6f6fc0949d93d769133 100644 --- a/src/platform/pal/mod.rs +++ b/src/platform/pal/mod.rs @@ -69,7 +69,7 @@ pub trait Pal { fn ftruncate(fildes: c_int, length: off_t) -> c_int; - fn futex(addr: *mut c_int, op: c_int, val: c_int) -> c_int; + fn futex(addr: *mut c_int, op: c_int, val: c_int, val2: usize) -> c_int; fn futimens(fd: c_int, times: *const timespec) -> c_int; diff --git a/src/platform/pte.rs b/src/platform/pte.rs index a7f2d86239dbabdf04586ef2417d1e1b3c06af33..b10744b838bdd9d15c0f95aa533a5a0ef43d4d38 100644 --- a/src/platform/pte.rs +++ b/src/platform/pte.rs @@ -346,8 +346,15 @@ pub unsafe extern "C" fn pte_osSemaphorePend( handle: pte_osSemaphoreHandle, pTimeout: *mut c_uint, ) -> pte_osResult { - //TODO: pTimeout - (*handle).wait(); + let timeout_opt = if ! pTimeout.is_null() { + let timeout = *pTimeout as i64; + let tv_sec = timeout / 1000; + let tv_nsec = (timeout % 1000) * 1000000; + Some(timespec { tv_sec, tv_nsec }) + } else { + None + }; + (*handle).wait(timeout_opt.as_ref()); PTE_OS_OK } @@ -356,7 +363,7 @@ pub unsafe extern "C" fn pte_osSemaphoreCancellablePend( handle: pte_osSemaphoreHandle, pTimeout: *mut c_uint, ) -> pte_osResult { - //TODO + //TODO: thread cancel pte_osSemaphorePend(handle, pTimeout) } diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 59b137a1390538fcc44870c30b355d35c5adec0c..c1f36feea0629a284ae3fb6ef11738101c28e487 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -446,13 +446,13 @@ impl Pal for Sys { e(syscall::ftruncate(fd as usize, len as usize)) as c_int } - fn futex(addr: *mut c_int, op: c_int, val: c_int) -> c_int { + fn futex(addr: *mut c_int, op: c_int, val: c_int, val2: usize) -> c_int { match unsafe { syscall::futex( addr as *mut i32, op as usize, val as i32, - 0, + val2, ptr::null_mut(), ) } { diff --git a/src/sync/mod.rs b/src/sync/mod.rs index 430abd5b783e341adeced608ac5d7f3c004077cc..dee4ac1831e0451f22fa1ea099645e9b045be41f 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -8,6 +8,7 @@ pub use self::{ semaphore::Semaphore, }; +use crate::header::time::timespec; use crate::platform::{types::*, Pal, Sys}; use core::{ cell::UnsafeCell, @@ -37,22 +38,25 @@ impl AtomicLock { } } pub fn notify_one(&self) { - Sys::futex(unsafe { &mut *self.atomic.get() }.get_mut(), FUTEX_WAKE, 1); + Sys::futex(unsafe { &mut *self.atomic.get() }.get_mut(), FUTEX_WAKE, 1, 0); } pub fn notify_all(&self) { Sys::futex( unsafe { &mut *self.atomic.get() }.get_mut(), FUTEX_WAKE, c_int::max_value(), + 0 ); } - pub fn wait_if(&self, value: c_int) { + pub fn wait_if(&self, value: c_int, timeout_opt: Option<×pec>) { Sys::futex( unsafe { &mut *self.atomic.get() }.get_mut(), FUTEX_WAIT, value, + timeout_opt.map_or(0, |timeout| timeout as *const timespec as usize) ); } + /// A general way to efficiently wait for what might be a long time, using two closures: /// /// - `attempt` = Attempt to modify the atomic value to any @@ -103,7 +107,7 @@ impl AtomicLock { // wait informed us that we might be done waiting mark_long(self) != AttemptStatus::Desired { - self.wait_if(long); + self.wait_if(long, None); } previous = attempt(self); diff --git a/src/sync/semaphore.rs b/src/sync/semaphore.rs index aba5aff6689962f768c911ab395f8edfbd0b3390..0827541f5778cbc28b5a50cc395b364570211581 100644 --- a/src/sync/semaphore.rs +++ b/src/sync/semaphore.rs @@ -2,6 +2,7 @@ //TODO: improve implementation use super::AtomicLock; +use crate::header::time::timespec; use crate::platform::{types::*, Pal, Sys}; use core::sync::atomic::Ordering; @@ -21,7 +22,7 @@ impl Semaphore { self.lock.notify_one(); } - pub fn wait(&self) { + pub fn wait(&self, timeout_opt: Option<×pec>) { let mut value = 1; loop { @@ -38,7 +39,7 @@ impl Semaphore { } if value == 0 { - self.lock.wait_if(0); + self.lock.wait_if(0, timeout_opt); value = 1; } }