(pthread_cond_timedwait_relative_old): Do tight

loop around nanosleep calls instead of around most of the function
(pthread_cond_timedwait_relative_new): Likewise.
body.  Got rid of backwards goto and one local.
This commit is contained in:
Ulrich Drepper 2000-02-11 18:00:19 +00:00
parent ab4e3a0ab2
commit 66dcc06fe7

View File

@ -134,14 +134,13 @@ pthread_cond_timedwait_relative_old(pthread_cond_t *cond,
{ {
volatile pthread_descr self = thread_self(); volatile pthread_descr self = thread_self();
sigset_t unblock, initial_mask; sigset_t unblock, initial_mask;
int retsleep, already_canceled, was_signalled; int already_canceled = 0;
int was_signalled = 0;
sigjmp_buf jmpbuf; sigjmp_buf jmpbuf;
pthread_extricate_if extr; pthread_extricate_if extr;
struct timeval now; struct timeval now;
struct timespec reltime; struct timespec reltime;
requeue_and_wait_again:
/* Compute a time offset relative to now. */ /* Compute a time offset relative to now. */
__gettimeofday (&now, NULL); __gettimeofday (&now, NULL);
reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000; reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;
@ -153,10 +152,6 @@ requeue_and_wait_again:
if (reltime.tv_sec < 0) if (reltime.tv_sec < 0)
return ETIMEDOUT; return ETIMEDOUT;
retsleep = 0;
already_canceled = 0;
was_signalled = 0;
/* Set up extrication interface */ /* Set up extrication interface */
extr.pu_object = cond; extr.pu_object = cond;
extr.pu_extricate_func = cond_extricate_func; extr.pu_extricate_func = cond_extricate_func;
@ -191,13 +186,14 @@ requeue_and_wait_again:
sigemptyset(&unblock); sigemptyset(&unblock);
sigaddset(&unblock, __pthread_sig_restart); sigaddset(&unblock, __pthread_sig_restart);
sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask); sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);
/* Sleep for the required duration */ /* Sleep for the required duration. If woken by a signal, resume waiting
retsleep = __libc_nanosleep(&reltime, NULL); as required by Single Unix Specification. */
while (__libc_nanosleep(&reltime, &reltime) != 0)
;
/* Block the restart signal again */ /* Block the restart signal again */
sigprocmask(SIG_SETMASK, &initial_mask, NULL); sigprocmask(SIG_SETMASK, &initial_mask, NULL);
was_signalled = 0; was_signalled = 0;
} else { } else {
retsleep = -1;
was_signalled = 1; was_signalled = 1;
} }
THREAD_SETMEM(self, p_signal_jmp, NULL); THREAD_SETMEM(self, p_signal_jmp, NULL);
@ -229,12 +225,7 @@ requeue_and_wait_again:
if (was_on_queue) { if (was_on_queue) {
__pthread_set_own_extricate_if(self, 0); __pthread_set_own_extricate_if(self, 0);
pthread_mutex_lock(mutex); pthread_mutex_lock(mutex);
return ETIMEDOUT;
if (retsleep == 0)
return ETIMEDOUT;
/* Woken by a signal: resume waiting as required by Single Unix
Specification. */
goto requeue_and_wait_again;
} }
suspend(self); suspend(self);
@ -267,14 +258,13 @@ pthread_cond_timedwait_relative_new(pthread_cond_t *cond,
{ {
volatile pthread_descr self = thread_self(); volatile pthread_descr self = thread_self();
sigset_t unblock, initial_mask; sigset_t unblock, initial_mask;
int retsleep, already_canceled, was_signalled; int already_canceled = 0;
int was_signalled = 0;
sigjmp_buf jmpbuf; sigjmp_buf jmpbuf;
pthread_extricate_if extr; pthread_extricate_if extr;
struct timeval now; struct timeval now;
struct timespec reltime; struct timespec reltime;
requeue_and_wait_again:
/* Compute a time offset relative to now. */ /* Compute a time offset relative to now. */
__gettimeofday (&now, NULL); __gettimeofday (&now, NULL);
reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000; reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;
@ -286,7 +276,6 @@ pthread_cond_timedwait_relative_new(pthread_cond_t *cond,
if (reltime.tv_sec < 0) if (reltime.tv_sec < 0)
return ETIMEDOUT; return ETIMEDOUT;
retsleep = 0;
already_canceled = 0; already_canceled = 0;
was_signalled = 0; was_signalled = 0;
@ -323,13 +312,14 @@ pthread_cond_timedwait_relative_new(pthread_cond_t *cond,
sigemptyset(&unblock); sigemptyset(&unblock);
sigaddset(&unblock, __pthread_sig_restart); sigaddset(&unblock, __pthread_sig_restart);
sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask); sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);
/* Sleep for the required duration */ /* Sleep for the required duration. If woken by a signal, resume waiting
retsleep = __libc_nanosleep(&reltime, NULL); as required by Single Unix Specification. */
while (__libc_nanosleep(&reltime, &reltime) != 0)
;
/* Block the restart signal again */ /* Block the restart signal again */
sigprocmask(SIG_SETMASK, &initial_mask, NULL); sigprocmask(SIG_SETMASK, &initial_mask, NULL);
was_signalled = 0; was_signalled = 0;
} else { } else {
retsleep = -1;
was_signalled = 1; was_signalled = 1;
} }
THREAD_SETMEM(self, p_signal_jmp, NULL); THREAD_SETMEM(self, p_signal_jmp, NULL);
@ -358,12 +348,7 @@ pthread_cond_timedwait_relative_new(pthread_cond_t *cond,
if (was_on_queue) { if (was_on_queue) {
__pthread_set_own_extricate_if(self, 0); __pthread_set_own_extricate_if(self, 0);
pthread_mutex_lock(mutex); pthread_mutex_lock(mutex);
return ETIMEDOUT;
if (retsleep == 0)
return ETIMEDOUT;
/* Woken by a signal: resume waiting as required by Single Unix
Specification. */
goto requeue_and_wait_again;
} }
/* Eat the outstanding restart() from the signaller */ /* Eat the outstanding restart() from the signaller */