2004-02-18  Carlos O'Donell  <carlos@baldric.uwo.ca>

	* test-skeleton.c (main): If set, use environment variable
	TIMEOUTFACTOR to scale test TIMEOUT.
This commit is contained in:
Ulrich Drepper 2004-02-19 00:55:28 +00:00
parent 4a08113c4e
commit dc39124662
6 changed files with 66 additions and 84 deletions

View File

@ -1,3 +1,8 @@
2004-02-18 Carlos O'Donell <carlos@baldric.uwo.ca>
* test-skeleton.c (main): If set, use environment variable
TIMEOUTFACTOR to scale test TIMEOUT.
2004-02-18 Ulrich Drepper <drepper@redhat.com> 2004-02-18 Ulrich Drepper <drepper@redhat.com>
* nscd/nscd_conf.c: Include <stdio_ext.h>. * nscd/nscd_conf.c: Include <stdio_ext.h>.

View File

@ -1,3 +1,15 @@
2004-02-18 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
(__pthread_cond_timedwait): Perform timeout test while holding
internal lock to prevent wakeup race.
Patch by Dinakar Guniguntala <dgunigun@in.ibm.com>.
* sysdeps/pthread/pthread_cond_timedwait.c
(__pthread_cond_timedwait): Likewise.
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
(__pthread_cond_timedwait): Likewise.
2004-02-18 Jakub Jelinek <jakub@redhat.com> 2004-02-18 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S

View File

@ -98,9 +98,6 @@ __pthread_cond_timedwait (cond, mutex, abstime)
while (1) while (1)
{ {
/* Prepare to wait. Release the condvar futex. */
lll_mutex_unlock (cond->__data.__lock);
struct timespec rt; struct timespec rt;
{ {
#ifdef __NR_clock_gettime #ifdef __NR_clock_gettime
@ -142,12 +139,10 @@ __pthread_cond_timedwait (cond, mutex, abstime)
} }
/* Did we already time out? */ /* Did we already time out? */
if (__builtin_expect (rt.tv_sec < 0, 0)) if (__builtin_expect (rt.tv_sec < 0, 0))
{ goto timeout;
/* We are going to look at shared data again, so get the lock. */
lll_mutex_lock(cond->__data.__lock);
goto timeout; /* Prepare to wait. Release the condvar futex. */
} lll_mutex_unlock (cond->__data.__lock);
/* Enable asynchronous cancellation. Required by the standard. */ /* Enable asynchronous cancellation. Required by the standard. */
cbuffer.oldtype = __pthread_enable_asynccancel (); cbuffer.oldtype = __pthread_enable_asynccancel ();

View File

@ -92,21 +92,8 @@ __pthread_cond_timedwait:
movl %edi, 12(%esp) movl %edi, 12(%esp)
movl %edx, 16(%esp) movl %edx, 16(%esp)
/* Unlock. */
8: LOCK
#if cond_lock == 0
subl $1, (%ebx)
#else
subl $1, cond_lock(%ebx)
#endif
jne 3f
.LcleanupSTART:
4: call __pthread_enable_asynccancel
movl %eax, (%esp)
/* Get the current time. */ /* Get the current time. */
movl %ebx, %edx 8: movl %ebx, %edx
.LebxmovedUR: .LebxmovedUR:
#ifdef __NR_clock_gettime #ifdef __NR_clock_gettime
/* Get the clock number. Note that the field in the condvar /* Get the clock number. Note that the field in the condvar
@ -156,6 +143,20 @@ __pthread_cond_timedwait:
/* Store relative timeout. */ /* Store relative timeout. */
21: movl %ecx, 4(%esp) 21: movl %ecx, 4(%esp)
movl %edx, 8(%esp) movl %edx, 8(%esp)
/* Unlock. */
LOCK
#if cond_lock == 0
subl $1, (%ebx)
#else
subl $1, cond_lock(%ebx)
#endif
jne 3f
.LcleanupSTART:
4: call __pthread_enable_asynccancel
movl %eax, (%esp)
leal 4(%esp), %esi leal 4(%esp), %esi
xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */ xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */
movl %edi, %edx movl %edi, %edx
@ -202,20 +203,8 @@ __pthread_cond_timedwait:
15: cmpl $-ETIMEDOUT, %esi 15: cmpl $-ETIMEDOUT, %esi
jne 8b jne 8b
jmp 24f
/* Lock. */ 13: addl $1, wakeup_seq(%ebx)
13: movl $1, %edx
xorl %eax, %eax
LOCK
#if cond_lock == 0
cmpxchgl %edx, (%ebx)
#else
cmpxchgl %edx, cond_lock(%ebx)
#endif
jnz 23f
24: addl $1, wakeup_seq(%ebx)
adcl $0, wakeup_seq+4(%ebx) adcl $0, wakeup_seq+4(%ebx)
movl $ETIMEDOUT, %esi movl $ETIMEDOUT, %esi
jmp 14f jmp 14f
@ -347,16 +336,6 @@ __pthread_cond_timedwait:
js 13b js 13b
jmp 21b jmp 21b
#endif #endif
/* Locking after time elapsed failed. */
23:
#if cond_lock == 0
movl %ebx, %ecx
#else
leal cond_lock(%ebx), %ecx
#endif
call __lll_mutex_lock_wait
jmp 24b
.size __pthread_cond_timedwait, .-__pthread_cond_timedwait .size __pthread_cond_timedwait, .-__pthread_cond_timedwait
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait, versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
GLIBC_2_3_2) GLIBC_2_3_2)

View File

@ -118,19 +118,8 @@ __pthread_cond_timedwait:
movq wakeup_seq(%rdi), %r12 movq wakeup_seq(%rdi), %r12
movq %r12, 40(%rsp) movq %r12, 40(%rsp)
/* Unlock. */
8: LOCK
#if cond_lock == 0
decl (%rdi)
#else
decl cond_lock(%rdi)
#endif
jne 3f
4: callq __pthread_enable_asynccancel
movl %eax, (%rsp)
/* Get the current time. */ /* Get the current time. */
8:
#ifdef __NR_clock_gettime #ifdef __NR_clock_gettime
/* Get the clock number. Note that the field in the condvar /* Get the clock number. Note that the field in the condvar
structure stores the number minus 1. */ structure stores the number minus 1. */
@ -177,6 +166,18 @@ __pthread_cond_timedwait:
21: movq %rcx, 24(%rsp) 21: movq %rcx, 24(%rsp)
movq %rdx, 32(%rsp) movq %rdx, 32(%rsp)
/* Unlock. */
LOCK
#if cond_lock == 0
decl (%rdi)
#else
decl cond_lock(%rdi)
#endif
jne 3f
4: callq __pthread_enable_asynccancel
movl %eax, (%rsp)
leaq 24(%rsp), %r10 leaq 24(%rsp), %r10
xorq %rsi, %rsi /* movq $FUTEX_WAIT, %rsi */ xorq %rsi, %rsi /* movq $FUTEX_WAIT, %rsi */
movq %r12, %rdx movq %r12, %rdx
@ -212,21 +213,8 @@ __pthread_cond_timedwait:
15: cmpq $-ETIMEDOUT, %r14 15: cmpq $-ETIMEDOUT, %r14
jne 8b jne 8b
jmp 24f
/* Lock. */ 13: incq wakeup_seq(%rdi)
13: movq 8(%rsp), %rdi
movl $1, %esi
xorl %eax, %eax
LOCK
#if cond_lock == 0
cmpxchgl %esi, (%rdi)
#else
cmpxchgl %esi, cond_lock(%rdi)
#endif
jne 23f
24: incq wakeup_seq(%rdi)
movq $ETIMEDOUT, %r14 movq $ETIMEDOUT, %r14
jmp 14f jmp 14f
@ -340,17 +328,6 @@ __pthread_cond_timedwait:
js 13b js 13b
jmp 21b jmp 21b
#endif #endif
/* Locking after time elapsed failed. */
23:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
callq __lll_mutex_lock_wait
#if cond_lock != 0
subq $cond_lock, %rdi
#endif
jmp 24b
.LENDCODE: .LENDCODE:
.size __pthread_cond_timedwait, .-__pthread_cond_timedwait .size __pthread_cond_timedwait, .-__pthread_cond_timedwait
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait, versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,

View File

@ -1,5 +1,5 @@
/* Skeleton for test programs. /* Skeleton for test programs.
Copyright (C) 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Copyright (C) 1998,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@ -193,6 +193,7 @@ main (int argc, char *argv[])
int direct = 0; /* Directly call the test function? */ int direct = 0; /* Directly call the test function? */
int status; int status;
int opt; int opt;
unsigned int timeoutfactor = 1;
pid_t termpid; pid_t termpid;
#ifdef STDOUT_UNBUFFERED #ifdef STDOUT_UNBUFFERED
@ -215,6 +216,19 @@ main (int argc, char *argv[])
#endif #endif
} }
/* If set, read the test TIMEOUTFACTOR value from the environment.
This value is used to scale the default test timeout values. */
char *envstr_timeoutfactor = getenv ("TIMEOUTFACTOR");
if (envstr_timeoutfactor != NULL)
{
char *envstr_conv = envstr_timeoutfactor;
unsigned long int env_fact;
env_fact = strtoul (envstr_timeoutfactor, &envstr_conv, 0);
if (*envstr_conv == '\0' && envstr_conv != envstr_timeoutfactor)
timeoutfactor = MAX (env_fact, 1);
}
/* Set TMPDIR to specified test directory. */ /* Set TMPDIR to specified test directory. */
if (test_dir != NULL) if (test_dir != NULL)
{ {
@ -306,7 +320,7 @@ main (int argc, char *argv[])
# define TIMEOUT 2 # define TIMEOUT 2
#endif #endif
signal (SIGALRM, timeout_handler); signal (SIGALRM, timeout_handler);
alarm (TIMEOUT); alarm (TIMEOUT * timeoutfactor);
/* Wait for the regular termination. */ /* Wait for the regular termination. */
termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)); termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));