From dc39124662b25ce2db28454f1749d67550e4de31 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 19 Feb 2004 00:55:28 +0000 Subject: Update. 2004-02-18 Carlos O'Donell * test-skeleton.c (main): If set, use environment variable TIMEOUTFACTOR to scale test TIMEOUT. --- nptl/ChangeLog | 12 +++++ nptl/sysdeps/pthread/pthread_cond_timedwait.c | 11 ++--- .../sysv/linux/i386/i486/pthread_cond_timedwait.S | 53 +++++++--------------- .../sysv/linux/x86_64/pthread_cond_timedwait.S | 51 ++++++--------------- 4 files changed, 45 insertions(+), 82 deletions(-) (limited to 'nptl') diff --git a/nptl/ChangeLog b/nptl/ChangeLog index ad2073d224..35f37cba88 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,15 @@ +2004-02-18 Ulrich Drepper + + + * 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 . + * 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 * 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 71e9cf7c8d..80b83107f5 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 6d1a325b9b..8e6e4bfdf5 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 cd5d64791f..f6b6ab246c 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, -- cgit 1.4.1