mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-18 22:50:07 +00:00
(pthread_cond_timedwait_relative_old): Get remaining time from nanosleep call
so that in case we restart we only wait for the remaining time. (pthread_cond_timedwait_relative_new): Likewise.
This commit is contained in:
parent
f532a7c3f5
commit
450db0463b
@ -26,13 +26,13 @@
|
||||
#include "restart.h"
|
||||
|
||||
static int pthread_cond_timedwait_relative_old(pthread_cond_t *,
|
||||
pthread_mutex_t *, const struct timespec *);
|
||||
pthread_mutex_t *, struct timespec *);
|
||||
|
||||
static int pthread_cond_timedwait_relative_new(pthread_cond_t *,
|
||||
pthread_mutex_t *, const struct timespec *);
|
||||
pthread_mutex_t *, struct timespec *);
|
||||
|
||||
static int (*pthread_cond_tw_rel)(pthread_cond_t *, pthread_mutex_t *,
|
||||
const struct timespec *) = pthread_cond_timedwait_relative_old;
|
||||
struct timespec *) = pthread_cond_timedwait_relative_old;
|
||||
|
||||
/* initialize this module */
|
||||
void __pthread_init_condvar(int rt_sig_available)
|
||||
@ -82,7 +82,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
extr.pu_extricate_func = cond_extricate_func;
|
||||
|
||||
/* Register extrication interface */
|
||||
__pthread_set_own_extricate_if(self, &extr);
|
||||
__pthread_set_own_extricate_if(self, &extr);
|
||||
|
||||
/* Atomically enqueue thread for waiting, but only if it is not
|
||||
canceled. If the thread is canceled, then it will fall through the
|
||||
@ -100,14 +100,14 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
__pthread_unlock(&cond->__c_lock);
|
||||
|
||||
if (already_canceled) {
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
pthread_exit(PTHREAD_CANCELED);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(mutex);
|
||||
|
||||
suspend(self);
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
|
||||
/* Check for cancellation again, to provide correct cancellation
|
||||
point behavior */
|
||||
@ -126,11 +126,11 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
/* The following function is used on kernels that don't have rt signals.
|
||||
SIGUSR1 is used as the restart signal. The different code is needed
|
||||
because that ordinary signal does not queue. */
|
||||
|
||||
|
||||
static int
|
||||
pthread_cond_timedwait_relative_old(pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
const struct timespec * reltime)
|
||||
struct timespec * reltime)
|
||||
{
|
||||
volatile pthread_descr self = thread_self();
|
||||
sigset_t unblock, initial_mask;
|
||||
@ -149,7 +149,7 @@ requeue_and_wait_again:
|
||||
extr.pu_extricate_func = cond_extricate_func;
|
||||
|
||||
/* Register extrication interface */
|
||||
__pthread_set_own_extricate_if(self, &extr);
|
||||
__pthread_set_own_extricate_if(self, &extr);
|
||||
|
||||
/* Enqueue to wait on the condition and check for cancellation. */
|
||||
__pthread_lock(&cond->__c_lock, self);
|
||||
@ -161,7 +161,7 @@ requeue_and_wait_again:
|
||||
__pthread_unlock(&cond->__c_lock);
|
||||
|
||||
if (already_canceled) {
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
pthread_exit(PTHREAD_CANCELED);
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ requeue_and_wait_again:
|
||||
sigaddset(&unblock, __pthread_sig_restart);
|
||||
sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);
|
||||
/* Sleep for the required duration */
|
||||
retsleep = __libc_nanosleep(reltime, NULL);
|
||||
retsleep = __libc_nanosleep(reltime, reltime);
|
||||
/* Block the restart signal again */
|
||||
sigprocmask(SIG_SETMASK, &initial_mask, NULL);
|
||||
was_signalled = 0;
|
||||
@ -191,7 +191,7 @@ requeue_and_wait_again:
|
||||
}
|
||||
|
||||
/* Now was_signalled is true if we exited the above code
|
||||
due to the delivery of a restart signal. In that case,
|
||||
due to the delivery of a restart signal. In that case,
|
||||
we know we have been dequeued and resumed and that the
|
||||
resume count is balanced. Otherwise, there are some
|
||||
cases to consider. First, try to bump up the resume count
|
||||
@ -214,13 +214,13 @@ requeue_and_wait_again:
|
||||
__pthread_unlock(&cond->__c_lock);
|
||||
|
||||
if (was_on_queue) {
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
pthread_mutex_lock(mutex);
|
||||
|
||||
if (retsleep == 0)
|
||||
return ETIMEDOUT;
|
||||
/* Woken by a signal: resume waiting as
|
||||
required by Single Unix Specification. */
|
||||
/* Woken by a signal: resume waiting as required by Single Unix
|
||||
Specification. */
|
||||
goto requeue_and_wait_again;
|
||||
}
|
||||
|
||||
@ -228,11 +228,11 @@ requeue_and_wait_again:
|
||||
}
|
||||
}
|
||||
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
|
||||
/* The remaining logic is the same as in other cancellable waits,
|
||||
such as pthread_join sem_wait or pthread_cond wait. */
|
||||
|
||||
|
||||
if (THREAD_GETMEM(self, p_woken_by_cancel)
|
||||
&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
|
||||
THREAD_SETMEM(self, p_woken_by_cancel, 0);
|
||||
@ -250,7 +250,7 @@ requeue_and_wait_again:
|
||||
static int
|
||||
pthread_cond_timedwait_relative_new(pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
const struct timespec * reltime)
|
||||
struct timespec * reltime)
|
||||
{
|
||||
volatile pthread_descr self = thread_self();
|
||||
sigset_t unblock, initial_mask;
|
||||
@ -258,7 +258,7 @@ pthread_cond_timedwait_relative_new(pthread_cond_t *cond,
|
||||
sigjmp_buf jmpbuf;
|
||||
pthread_extricate_if extr;
|
||||
|
||||
requeue_and_wait_again:
|
||||
requeue_and_wait_again:
|
||||
|
||||
retsleep = 0;
|
||||
already_canceled = 0;
|
||||
@ -269,7 +269,7 @@ requeue_and_wait_again:
|
||||
extr.pu_extricate_func = cond_extricate_func;
|
||||
|
||||
/* Register extrication interface */
|
||||
__pthread_set_own_extricate_if(self, &extr);
|
||||
__pthread_set_own_extricate_if(self, &extr);
|
||||
|
||||
/* Enqueue to wait on the condition and check for cancellation. */
|
||||
__pthread_lock(&cond->__c_lock, self);
|
||||
@ -281,7 +281,7 @@ requeue_and_wait_again:
|
||||
__pthread_unlock(&cond->__c_lock);
|
||||
|
||||
if (already_canceled) {
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
pthread_exit(PTHREAD_CANCELED);
|
||||
}
|
||||
|
||||
@ -298,7 +298,7 @@ requeue_and_wait_again:
|
||||
sigaddset(&unblock, __pthread_sig_restart);
|
||||
sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);
|
||||
/* Sleep for the required duration */
|
||||
retsleep = __libc_nanosleep(reltime, NULL);
|
||||
retsleep = __libc_nanosleep(reltime, reltime);
|
||||
/* Block the restart signal again */
|
||||
sigprocmask(SIG_SETMASK, &initial_mask, NULL);
|
||||
was_signalled = 0;
|
||||
@ -309,7 +309,7 @@ requeue_and_wait_again:
|
||||
THREAD_SETMEM(self, p_signal_jmp, NULL);
|
||||
|
||||
/* Now was_signalled is true if we exited the above code
|
||||
due to the delivery of a restart signal. In that case,
|
||||
due to the delivery of a restart signal. In that case,
|
||||
everything is cool. We have been removed from the queue
|
||||
by the other thread, and consumed its signal.
|
||||
|
||||
@ -322,7 +322,7 @@ requeue_and_wait_again:
|
||||
if (!was_signalled) {
|
||||
int was_on_queue;
|
||||
|
||||
/* __pthread_lock will queue back any spurious restarts that
|
||||
/* __pthread_lock will queue back any spurious restarts that
|
||||
may happen to it. */
|
||||
|
||||
__pthread_lock(&cond->__c_lock, self);
|
||||
@ -330,13 +330,13 @@ requeue_and_wait_again:
|
||||
__pthread_unlock(&cond->__c_lock);
|
||||
|
||||
if (was_on_queue) {
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
pthread_mutex_lock(mutex);
|
||||
|
||||
if (retsleep == 0)
|
||||
return ETIMEDOUT;
|
||||
/* Woken by a signal: resume waiting as
|
||||
required by Single Unix Specification. */
|
||||
/* Woken by a signal: resume waiting as required by Single Unix
|
||||
Specification. */
|
||||
goto requeue_and_wait_again;
|
||||
}
|
||||
|
||||
@ -344,11 +344,11 @@ requeue_and_wait_again:
|
||||
suspend(self);
|
||||
}
|
||||
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
__pthread_set_own_extricate_if(self, 0);
|
||||
|
||||
/* The remaining logic is the same as in other cancellable waits,
|
||||
such as pthread_join sem_wait or pthread_cond wait. */
|
||||
|
||||
|
||||
if (THREAD_GETMEM(self, p_woken_by_cancel)
|
||||
&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
|
||||
THREAD_SETMEM(self, p_woken_by_cancel, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user