aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--nptl/ChangeLog12
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_timedwait.c11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S53
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S51
-rw-r--r--test-skeleton.c18
6 files changed, 66 insertions, 84 deletions
diff --git a/ChangeLog b/ChangeLog
index 39ae870..dff56bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
* nscd/nscd_conf.c: Include <stdio_ext.h>.
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index ad2073d..35f37cb 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -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>
* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
diff --git a/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/nptl/sysdeps/pthread/pthread_cond_timedwait.c
index 71e9cf7..80b8310 100644
--- a/nptl/sysdeps/pthread/pthread_cond_timedwait.c
+++ b/nptl/sysdeps/pthread/pthread_cond_timedwait.c
@@ -98,9 +98,6 @@ __pthread_cond_timedwait (cond, mutex, abstime)
while (1)
{
- /* Prepare to wait. Release the condvar futex. */
- lll_mutex_unlock (cond->__data.__lock);
-
struct timespec rt;
{
#ifdef __NR_clock_gettime
@@ -142,12 +139,10 @@ __pthread_cond_timedwait (cond, mutex, abstime)
}
/* Did we already time out? */
if (__builtin_expect (rt.tv_sec < 0, 0))
- {
- /* We are going to look at shared data again, so get the lock. */
- lll_mutex_lock(cond->__data.__lock);
+ goto timeout;
- goto timeout;
- }
+ /* Prepare to wait. Release the condvar futex. */
+ lll_mutex_unlock (cond->__data.__lock);
/* Enable asynchronous cancellation. Required by the standard. */
cbuffer.oldtype = __pthread_enable_asynccancel ();
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
index 6d1a325..8e6e4bf 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
@@ -92,21 +92,8 @@ __pthread_cond_timedwait:
movl %edi, 12(%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. */
- movl %ebx, %edx
+8: movl %ebx, %edx
.LebxmovedUR:
#ifdef __NR_clock_gettime
/* Get the clock number. Note that the field in the condvar
@@ -156,6 +143,20 @@ __pthread_cond_timedwait:
/* Store relative timeout. */
21: movl %ecx, 4(%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
xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */
movl %edi, %edx
@@ -202,20 +203,8 @@ __pthread_cond_timedwait:
15: cmpl $-ETIMEDOUT, %esi
jne 8b
- jmp 24f
- /* Lock. */
-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)
+13: addl $1, wakeup_seq(%ebx)
adcl $0, wakeup_seq+4(%ebx)
movl $ETIMEDOUT, %esi
jmp 14f
@@ -347,16 +336,6 @@ __pthread_cond_timedwait:
js 13b
jmp 21b
#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
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
GLIBC_2_3_2)
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
index cd5d647..f6b6ab2 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
@@ -118,19 +118,8 @@ __pthread_cond_timedwait:
movq wakeup_seq(%rdi), %r12
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. */
+8:
#ifdef __NR_clock_gettime
/* Get the clock number. Note that the field in the condvar
structure stores the number minus 1. */
@@ -177,6 +166,18 @@ __pthread_cond_timedwait:
21: movq %rcx, 24(%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
xorq %rsi, %rsi /* movq $FUTEX_WAIT, %rsi */
movq %r12, %rdx
@@ -212,21 +213,8 @@ __pthread_cond_timedwait:
15: cmpq $-ETIMEDOUT, %r14
jne 8b
- jmp 24f
-
- /* Lock. */
-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)
+13: incq wakeup_seq(%rdi)
movq $ETIMEDOUT, %r14
jmp 14f
@@ -340,17 +328,6 @@ __pthread_cond_timedwait:
js 13b
jmp 21b
#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:
.size __pthread_cond_timedwait, .-__pthread_cond_timedwait
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
diff --git a/test-skeleton.c b/test-skeleton.c
index f9061ca..9d9a68b 100644
--- a/test-skeleton.c
+++ b/test-skeleton.c
@@ -1,5 +1,5 @@
/* 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.
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 status;
int opt;
+ unsigned int timeoutfactor = 1;
pid_t termpid;
#ifdef STDOUT_UNBUFFERED
@@ -215,6 +216,19 @@ main (int argc, char *argv[])
#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. */
if (test_dir != NULL)
{
@@ -306,7 +320,7 @@ main (int argc, char *argv[])
# define TIMEOUT 2
#endif
signal (SIGALRM, timeout_handler);
- alarm (TIMEOUT);
+ alarm (TIMEOUT * timeoutfactor);
/* Wait for the regular termination. */
termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));