From 8576b997596788ad3fd18d2c7231886de274a2cb Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Mon, 4 Apr 2022 20:23:29 -0600 Subject: [PATCH] Add timeout to futex_wait calls --- src/platform/linux/mod.rs | 4 ++-- src/platform/pal/mod.rs | 2 +- src/platform/pte.rs | 13 ++++++++++--- src/platform/redox/mod.rs | 4 ++-- src/sync/mod.rs | 10 +++++++--- src/sync/semaphore.rs | 5 +++-- 6 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 4b92fc2c4..3c94ef972 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 73f32b1a1..66cae57e8 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 a7f2d8623..b10744b83 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 59b137a13..c1f36feea 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 430abd5b7..dee4ac183 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 aba5aff66..0827541f5 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; } } -- GitLab