From c7a79bb036b42f96b7379b95efa643ee27df2168 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 21 Jun 2022 15:45:49 +0200 Subject: gh-74953: _PyThread_cond_after() uses _PyTime_t (#94056) pthread _PyThread_cond_after() implementation now uses the _PyTime_t type to handle properly overflow: clamp to the maximum value. Remove MICROSECONDS_TO_TIMESPEC() function. --- Python/thread_pthread.h | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) (limited to 'Python/thread_pthread.h') diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index a5719c39bc0..c310d72abd2 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -113,19 +113,6 @@ #endif -#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \ -do { \ - struct timeval tv; \ - gettimeofday(&tv, NULL); \ - tv.tv_usec += microseconds % 1000000; \ - tv.tv_sec += microseconds / 1000000; \ - tv.tv_sec += tv.tv_usec / 1000000; \ - tv.tv_usec %= 1000000; \ - ts.tv_sec = tv.tv_sec; \ - ts.tv_nsec = tv.tv_usec * 1000; \ -} while(0) - - /* * pthread_cond support */ @@ -156,23 +143,23 @@ _PyThread_cond_init(PyCOND_T *cond) return pthread_cond_init(cond, condattr_monotonic); } + void _PyThread_cond_after(long long us, struct timespec *abs) { + _PyTime_t timeout = _PyTime_FromMicrosecondsClamp(us); + _PyTime_t t; #ifdef CONDATTR_MONOTONIC if (condattr_monotonic) { - clock_gettime(CLOCK_MONOTONIC, abs); - abs->tv_sec += us / 1000000; - abs->tv_nsec += (us % 1000000) * 1000; - abs->tv_sec += abs->tv_nsec / 1000000000; - abs->tv_nsec %= 1000000000; - return; + t = _PyTime_GetMonotonicClock(); } + else #endif - - struct timespec ts; - MICROSECONDS_TO_TIMESPEC(us, ts); - *abs = ts; + { + t = _PyTime_GetSystemClock(); + } + t = _PyTime_Add(t, timeout); + _PyTime_AsTimespec_clamp(t, abs); } @@ -639,9 +626,9 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, goto unlock; } - struct timespec abs; + struct timespec abs_timeout; if (microseconds > 0) { - _PyThread_cond_after(microseconds, &abs); + _PyThread_cond_after(microseconds, &abs_timeout); } // Continue trying until we get the lock @@ -649,7 +636,7 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, while (1) { if (microseconds > 0) { status = pthread_cond_timedwait(&thelock->lock_released, - &thelock->mut, &abs); + &thelock->mut, &abs_timeout); if (status == 1) { break; } -- cgit v1.2.3