mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-07 10:00:07 +00:00
Optimize pthread_cond_timedwait to avoid unnecessary call to clock_gettime for CLOCK_MONOTONIC
This commit is contained in:
parent
5643a977d0
commit
be3c0fe888
@ -510,34 +510,13 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
if (__glibc_unlikely (abstime->tv_sec < 0))
|
||||
err = ETIMEDOUT;
|
||||
|
||||
else if ((flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK) != 0)
|
||||
{
|
||||
/* CLOCK_MONOTONIC is requested. */
|
||||
struct timespec rt;
|
||||
if (__clock_gettime (CLOCK_MONOTONIC, &rt) != 0)
|
||||
__libc_fatal ("clock_gettime does not support "
|
||||
"CLOCK_MONOTONIC");
|
||||
/* Convert the absolute timeout value to a relative
|
||||
timeout. */
|
||||
rt.tv_sec = abstime->tv_sec - rt.tv_sec;
|
||||
rt.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
|
||||
if (rt.tv_nsec < 0)
|
||||
{
|
||||
rt.tv_nsec += 1000000000;
|
||||
--rt.tv_sec;
|
||||
}
|
||||
/* Did we already time out? */
|
||||
if (__glibc_unlikely (rt.tv_sec < 0))
|
||||
err = ETIMEDOUT;
|
||||
else
|
||||
err = futex_reltimed_wait_cancelable
|
||||
(cond->__data.__g_signals + g, 0, &rt, private);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use CLOCK_REALTIME. */
|
||||
err = futex_abstimed_wait_cancelable
|
||||
(cond->__data.__g_signals + g, 0, abstime, private);
|
||||
(cond->__data.__g_signals + g, 0, abstime,
|
||||
(flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK) != 0
|
||||
? 0
|
||||
: FUTEX_CLOCK_REALTIME, private);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,10 +110,10 @@ do_futex_wait (struct new_sem *sem, const struct timespec *abstime)
|
||||
#if __HAVE_64B_ATOMICS
|
||||
err = futex_abstimed_wait_cancelable (
|
||||
(unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0, abstime,
|
||||
sem->private);
|
||||
FUTEX_CLOCK_REALTIME, sem->private);
|
||||
#else
|
||||
err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK,
|
||||
abstime, sem->private);
|
||||
abstime, FUTEX_CLOCK_REALTIME, sem->private);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
|
@ -169,7 +169,7 @@ futex_abstimed_wait (unsigned int* futex_word, unsigned int expected,
|
||||
static __always_inline int
|
||||
futex_abstimed_wait_cancelable (unsigned int* futex_word,
|
||||
unsigned int expected,
|
||||
const struct timespec* abstime, int private);
|
||||
const struct timespec* abstime, int clockbit, int private);
|
||||
|
||||
/* Atomically wrt other futex operations on the same futex, this unblocks the
|
||||
specified number of processes, or all processes blocked on this futex if
|
||||
|
@ -52,7 +52,7 @@ do_futex_wait (struct new_sem *sem, const struct timespec *abstime)
|
||||
int err;
|
||||
|
||||
err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK,
|
||||
abstime, sem->private);
|
||||
abstime, FUTEX_CLOCK_REALTIME, sem->private);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ futex_abstimed_wait (unsigned int *futex_word, unsigned int expected,
|
||||
static __always_inline int
|
||||
futex_abstimed_wait_cancelable (unsigned int *futex_word,
|
||||
unsigned int expected,
|
||||
const struct timespec *abstime, int private)
|
||||
const struct timespec *abstime, int clockbit, int private)
|
||||
{
|
||||
/* Work around the fact that the kernel rejects negative timeout values
|
||||
despite them being valid. */
|
||||
@ -203,7 +203,7 @@ futex_abstimed_wait_cancelable (unsigned int *futex_word,
|
||||
int oldtype;
|
||||
oldtype = __pthread_enable_asynccancel ();
|
||||
int err = lll_futex_timed_wait_bitset (futex_word, expected, abstime,
|
||||
FUTEX_CLOCK_REALTIME, private);
|
||||
clockbit, private);
|
||||
__pthread_disable_asynccancel (oldtype);
|
||||
switch (err)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user