From b063aadaa5854e845ed01a1d4c1bf730ec67c79b Mon Sep 17 00:00:00 2001 From: Wildan M Date: Tue, 6 Jan 2026 23:32:15 +0700 Subject: [PATCH 1/3] Release pthread cond workaround, simplify --- src/sync/cond.rs | 41 +++++------------------------------------ 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/src/sync/cond.rs b/src/sync/cond.rs index 58b16c3eb4..321afa4ea6 100644 --- a/src/sync/cond.rs +++ b/src/sync/cond.rs @@ -90,32 +90,14 @@ impl Cond { _ => return Err(Errno(EINVAL)), }; - match self.wait_inner(mutex, Some(&relative)) { - Err(Errno(ETIMEDOUT)) => { - // TODO: this is a workaround that SYS_FUTEX returns ETIMEDOUT but actually it signaled in time - let mut monotonic = timespec::default(); - unsafe { clock_gettime(CLOCK_MONOTONIC, &mut monotonic) }; - - if timespec::subtract(relative, monotonic).is_some() { - Ok(()) - } else { - Err(Errno(ETIMEDOUT)) - } - } - r => r, - } + self.wait_inner(mutex, Some(&relative)) } pub fn timedwait(&self, mutex: &RlctMutex, timeout: ×pec) -> Result<(), Errno> { // TODO: The clock can be other than CLOCK_REALTIME depends on CondAttr self.clockwait(mutex, timeout, CLOCK_REALTIME) } fn wait_inner(&self, mutex: &RlctMutex, timeout: Option<×pec>) -> Result<(), Errno> { - self.wait_inner_generic( - || mutex.unlock(), - || mutex.lock(), - |timeout| mutex.lock_with_timeout(timeout), - timeout, - ) + self.wait_inner_generic(|| mutex.unlock(), || mutex.lock(), timeout) } pub fn wait_inner_typedmutex<'lock, T>( &self, @@ -132,7 +114,6 @@ impl Cond { newguard = Some(lock.lock()); Ok(()) }, - |_| unreachable!(), None, ) .unwrap(); @@ -143,7 +124,6 @@ impl Cond { &self, unlock: impl FnOnce() -> Result<()>, lock: impl FnOnce() -> Result<()>, - lock_with_timeout: impl FnOnce(×pec) -> Result<()>, deadline: Option<×pec>, ) -> Result<(), Errno> { // TODO: Error checking for certain types (i.e. robust and errorcheck) of mutexes, e.g. if the @@ -151,20 +131,9 @@ impl Cond { let current = self.cur.load(Ordering::Relaxed); self.prev.store(current, Ordering::Relaxed); - unlock(); - - let futex_r = match deadline { - Some(deadline) => { - let r = crate::sync::futex_wait(&self.cur, current, Some(&deadline)); - lock_with_timeout(deadline)?; - r - } - None => { - let r = crate::sync::futex_wait(&self.cur, current, None); - lock()?; - r - } - }; + unlock()?; + let futex_r = crate::sync::futex_wait(&self.cur, current, deadline); + lock()?; match futex_r { super::FutexWaitResult::Waited => Ok(()), From ba4d789f6ea81de67709b4bbdb7b16ee67ff2779 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Tue, 6 Jan 2026 23:33:00 +0700 Subject: [PATCH 2/3] Calculate pthread_mutex_timedlock clock --- src/header/pthread/mutex.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/header/pthread/mutex.rs b/src/header/pthread/mutex.rs index 92cacffb41..33311aeaf5 100644 --- a/src/header/pthread/mutex.rs +++ b/src/header/pthread/mutex.rs @@ -1,6 +1,9 @@ use super::*; -use crate::error::Errno; +use crate::{ + error::Errno, + header::errno::{EINVAL, ENOMEM, ETIMEDOUT}, +}; // PTHREAD_MUTEX_INITIALIZER is defined in bits_pthread/cbindgen.toml @@ -72,9 +75,25 @@ pub unsafe extern "C" fn pthread_mutex_setprioceiling( #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_timedlock( mutex: *mut pthread_mutex_t, - timespec: *const timespec, + abstime: *const timespec, ) -> c_int { - e((&*mutex.cast::()).lock_with_timeout(&*timespec)) + // convert REALTIME_CLOCK to MONOTONIC_CLOCK + + let relative = { + let mut realtime = timespec::default(); + unsafe { clock_gettime(CLOCK_REALTIME, &mut realtime) }; + let mut monotonic = timespec::default(); + unsafe { clock_gettime(CLOCK_MONOTONIC, &mut monotonic) }; + let Some(delta) = timespec::subtract(*abstime.clone(), realtime) else { + return e(Err(Errno(ETIMEDOUT))); + }; + let Some(relative) = timespec::add(monotonic, delta) else { + return e(Err(Errno(ENOMEM))); + }; + relative + }; + + e((&*mutex.cast::()).lock_with_timeout(&relative)) } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_trylock(mutex: *mut pthread_mutex_t) -> c_int { From 9789af36f08a88ef20eca23b654bbad49dc11e29 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Wed, 7 Jan 2026 00:07:50 +0700 Subject: [PATCH 3/3] Put timespec convert into common fn --- src/header/pthread/mutex.rs | 23 ++++++++--------------- src/header/time/mod.rs | 16 +++++++++++++++- src/sync/cond.rs | 21 +++++---------------- src/sync/semaphore.rs | 25 +++++-------------------- 4 files changed, 33 insertions(+), 52 deletions(-) diff --git a/src/header/pthread/mutex.rs b/src/header/pthread/mutex.rs index 33311aeaf5..0ea0233a17 100644 --- a/src/header/pthread/mutex.rs +++ b/src/header/pthread/mutex.rs @@ -2,7 +2,10 @@ use super::*; use crate::{ error::Errno, - header::errno::{EINVAL, ENOMEM, ETIMEDOUT}, + header::{ + errno::{EINVAL, ENOMEM, ETIMEDOUT}, + time::{CLOCK_MONOTONIC, CLOCK_REALTIME, timespec_realtime_to_monotonic}, + }, }; // PTHREAD_MUTEX_INITIALIZER is defined in bits_pthread/cbindgen.toml @@ -77,24 +80,14 @@ pub unsafe extern "C" fn pthread_mutex_timedlock( mutex: *mut pthread_mutex_t, abstime: *const timespec, ) -> c_int { - // convert REALTIME_CLOCK to MONOTONIC_CLOCK - - let relative = { - let mut realtime = timespec::default(); - unsafe { clock_gettime(CLOCK_REALTIME, &mut realtime) }; - let mut monotonic = timespec::default(); - unsafe { clock_gettime(CLOCK_MONOTONIC, &mut monotonic) }; - let Some(delta) = timespec::subtract(*abstime.clone(), realtime) else { - return e(Err(Errno(ETIMEDOUT))); - }; - let Some(relative) = timespec::add(monotonic, delta) else { - return e(Err(Errno(ENOMEM))); - }; - relative + let relative = match timespec_realtime_to_monotonic(*abstime) { + Ok(relative) => relative, + Err(err) => return e(Err(err)), }; e((&*mutex.cast::()).lock_with_timeout(&relative)) } + #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_trylock(mutex: *mut pthread_mutex_t) -> c_int { e((&*mutex.cast::()).try_lock()) diff --git a/src/header/time/mod.rs b/src/header/time/mod.rs index 2a90455105..cb3b2c668d 100644 --- a/src/header/time/mod.rs +++ b/src/header/time/mod.rs @@ -7,7 +7,7 @@ use crate::{ error::{Errno, ResultExt}, fs::File, header::{ - errno::{EFAULT, EOVERFLOW}, + errno::{EFAULT, ENOMEM, EOVERFLOW, ETIMEDOUT}, fcntl::O_RDONLY, signal::sigevent, stdlib::getenv, @@ -848,3 +848,17 @@ const fn blank_tm() -> tm { tm_zone: ptr::null_mut(), } } + +pub(crate) fn timespec_realtime_to_monotonic(abstime: timespec) -> Result { + let mut realtime = timespec::default(); + unsafe { clock_gettime(CLOCK_REALTIME, &mut realtime) }; + let mut monotonic = timespec::default(); + unsafe { clock_gettime(CLOCK_MONOTONIC, &mut monotonic) }; + let Some(delta) = timespec::subtract(abstime, realtime) else { + return Err(Errno(ETIMEDOUT)); + }; + let Some(relative) = timespec::add(monotonic, delta) else { + return Err(Errno(ENOMEM)); + }; + Ok(relative) +} diff --git a/src/sync/cond.rs b/src/sync/cond.rs index 321afa4ea6..8e132b7ddd 100644 --- a/src/sync/cond.rs +++ b/src/sync/cond.rs @@ -5,7 +5,7 @@ use crate::{ header::{ errno::{EINVAL, ENOMEM, ETIMEDOUT}, pthread::*, - time::{CLOCK_MONOTONIC, CLOCK_REALTIME, clock_gettime, timespec}, + time::{CLOCK_MONOTONIC, CLOCK_REALTIME, timespec, timespec_realtime_to_monotonic}, }, platform::types::clockid_t, }; @@ -69,24 +69,13 @@ impl Cond { timeout: ×pec, clock_id: clockid_t, ) -> Result<(), Errno> { - // adjusted timeout similar in semaphore.rs - let relative = match clock_id { // FUTEX expect monotonic clock CLOCK_MONOTONIC => timeout.clone(), - CLOCK_REALTIME => { - let mut realtime = timespec::default(); - unsafe { clock_gettime(CLOCK_REALTIME, &mut realtime) }; - let mut monotonic = timespec::default(); - unsafe { clock_gettime(CLOCK_MONOTONIC, &mut monotonic) }; - let Some(delta) = timespec::subtract(timeout.clone(), realtime) else { - return Err(Errno(ETIMEDOUT)); - }; - let Some(relative) = timespec::add(monotonic, delta) else { - return Err(Errno(ENOMEM)); - }; - relative - } + CLOCK_REALTIME => match timespec_realtime_to_monotonic(timeout.clone()) { + Ok(relative) => relative, + Err(err) => return Err(err), + }, _ => return Err(Errno(EINVAL)), }; diff --git a/src/sync/semaphore.rs b/src/sync/semaphore.rs index 54b2691f0f..00908cc9b7 100644 --- a/src/sync/semaphore.rs +++ b/src/sync/semaphore.rs @@ -2,7 +2,7 @@ //TODO: improve implementation use crate::{ - header::time::{CLOCK_MONOTONIC, CLOCK_REALTIME, clock_gettime, timespec}, + header::time::{CLOCK_MONOTONIC, CLOCK_REALTIME, timespec, timespec_realtime_to_monotonic}, platform::types::{c_uint, clockid_t}, }; @@ -63,27 +63,12 @@ impl Semaphore { let relative = match clock_id { // FUTEX expect monotonic clock CLOCK_MONOTONIC => timeout.clone(), - CLOCK_REALTIME => { - let mut realtime = timespec::default(); - unsafe { clock_gettime(CLOCK_REALTIME, &mut realtime) }; - - let mut monotonic = timespec::default(); - unsafe { clock_gettime(CLOCK_MONOTONIC, &mut monotonic) }; - - let Some(delta) = timespec::subtract(timeout.clone(), realtime) else { - //Timeout happened - return Err(()); - }; - - let Some(relative) = timespec::add(monotonic, delta) else { - return Err(()); - }; - - relative - } + CLOCK_REALTIME => match timespec_realtime_to_monotonic(timeout.clone()) { + Ok(relative) => relative, + Err(_) => return Err(()), + }, _ => return Err(()), }; - crate::sync::futex_wait(&self.count, value, Some(&relative)); } else { // Use futex to wait for the next change, without a timeout