From 9789af36f08a88ef20eca23b654bbad49dc11e29 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Wed, 7 Jan 2026 00:07:50 +0700 Subject: [PATCH] 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