From e42a990eccb6ce79650db5fb713b94732df82f4d Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 21 Nov 2003 10:00:11 +0000 Subject: [PATCH] Update. * sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Don't store mutex address if the current value is ~0l. * sysdeps/pthread/pthread_cond_timedwait.c (__pthread_cond_timedwait): Likewise. * sysdeps/pthread/pthread_cond_broadcast.c (__pthread_cond_broadcast): Don't use requeue for pshared condvars. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S (__pthread_cond_wait): Don't store mutex address if the current value is ~0l. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S (__pthread_cond_timedwait): Likewise. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S (__pthread_cond_broadcast): Don't use requeue for pshared condvars. * pthread_cond_init.c (__pthread_cond_init): Initialize __mutex element with ~0l for pshared condvars, with NULL otherwise. * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S (__pthread_cond_wait): Don't store mutex address if the current value is ~0l. * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S (__pthread_cond_timedwait): Likewise. * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S (__pthread_cond_broadcast): Don't use requeue for pshared condvars. --- nptl/ChangeLog | 29 ++++++++++++++++++++++ nptl/pthread_cond_init.c | 2 ++ nptl/sysdeps/pthread/pthread_cond_broadcast.c | 7 ++++-- nptl/sysdeps/pthread/pthread_cond_timedwait.c | 6 +++-- nptl/sysdeps/pthread/pthread_cond_wait.c | 6 +++-- .../sysv/linux/i386/i486/pthread_cond_broadcast.S | 11 ++++---- .../sysv/linux/i386/i486/pthread_cond_timedwait.S | 6 +++-- .../unix/sysv/linux/i386/i486/pthread_cond_wait.S | 6 +++-- .../sysv/linux/x86_64/pthread_cond_broadcast.S | 10 ++++---- .../sysv/linux/x86_64/pthread_cond_timedwait.S | 5 +++- .../unix/sysv/linux/x86_64/pthread_cond_wait.S | 7 ++++-- 11 files changed, 72 insertions(+), 23 deletions(-) diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 8049711..5c9dfa8 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,5 +1,34 @@ 2003-11-21 Ulrich Drepper + * sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Don't + store mutex address if the current value is ~0l. + * sysdeps/pthread/pthread_cond_timedwait.c + (__pthread_cond_timedwait): Likewise. + * sysdeps/pthread/pthread_cond_broadcast.c + (__pthread_cond_broadcast): Don't use requeue for pshared + condvars. + + * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S + (__pthread_cond_wait): Don't store mutex address if the current + value is ~0l. + * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S + (__pthread_cond_timedwait): Likewise. + * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S + (__pthread_cond_broadcast): Don't use requeue for pshared + condvars. + + * pthread_cond_init.c (__pthread_cond_init): Initialize __mutex + element with ~0l for pshared condvars, with NULL otherwise. + + * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S + (__pthread_cond_wait): Don't store mutex address if the current + value is ~0l. + * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S + (__pthread_cond_timedwait): Likewise. + * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S + (__pthread_cond_broadcast): Don't use requeue for pshared + condvars. + * Makefile: Add rules to build and run tst-cond12 and tst-cond13. * tst-cond12.c: New file. * tst-cond13.c: New file. diff --git a/nptl/pthread_cond_init.c b/nptl/pthread_cond_init.c index 73ae432..bb7c6d6 100644 --- a/nptl/pthread_cond_init.c +++ b/nptl/pthread_cond_init.c @@ -36,6 +36,8 @@ __pthread_cond_init (cond, cond_attr) cond->__data.__total_seq = 0; cond->__data.__wakeup_seq = 0; cond->__data.__woken_seq = 0; + cond->__data.__mutex = (icond_attr == NULL || (icond_attr->value & 1) == 0 + ? NULL : (void *) ~0l); return 0; } diff --git a/nptl/sysdeps/pthread/pthread_cond_broadcast.c b/nptl/sysdeps/pthread/pthread_cond_broadcast.c index 6c3722a..44c3fe6 100644 --- a/nptl/sysdeps/pthread/pthread_cond_broadcast.c +++ b/nptl/sysdeps/pthread/pthread_cond_broadcast.c @@ -54,6 +54,10 @@ __pthread_cond_broadcast (cond) # error "No valid byte order" #endif + /* Do not use requeue for pshared condvars. */ + if (cond->__data.__mutex == (void *) ~0l) + goto wake_all; + /* Wake everybody. */ pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex; if (__builtin_expect (lll_futex_requeue (futex, 1, INT_MAX, @@ -61,9 +65,8 @@ __pthread_cond_broadcast (cond) 0)) { /* The requeue functionality is not available. */ -#ifndef __ASSUME_FUTEX_REQUEUE + wake_all: lll_futex_wake (futex, INT_MAX); -#endif } /* That's all. */ diff --git a/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/nptl/sysdeps/pthread/pthread_cond_timedwait.c index 1655c70..9fa2920 100644 --- a/nptl/sysdeps/pthread/pthread_cond_timedwait.c +++ b/nptl/sysdeps/pthread/pthread_cond_timedwait.c @@ -67,8 +67,10 @@ __pthread_cond_timedwait (cond, mutex, abstime) ++cond->__data.__total_seq; /* Remember the mutex we are using here. If there is already a - different address store this is a bad user bug. */ - cond->__data.__mutex = mutex; + different address store this is a bad user bug. Do not store + anything for pshared condvars. */ + if (cond->__data.__mutex != (void *) ~0l) + cond->__data.__mutex = mutex; /* Prepare structure passed to cancellation handler. */ cbuffer.cond = cond; diff --git a/nptl/sysdeps/pthread/pthread_cond_wait.c b/nptl/sysdeps/pthread/pthread_cond_wait.c index 75edf3d..79c6d99 100644 --- a/nptl/sysdeps/pthread/pthread_cond_wait.c +++ b/nptl/sysdeps/pthread/pthread_cond_wait.c @@ -93,8 +93,10 @@ __pthread_cond_wait (cond, mutex) ++cond->__data.__total_seq; /* Remember the mutex we are using here. If there is already a - different address store this is a bad user bug. */ - cond->__data.__mutex = mutex; + different address store this is a bad user bug. Do not store + anything for pshared condvars. */ + if (cond->__data.__mutex != (void *) ~0l) + cond->__data.__mutex = mutex; /* Prepare structure passed to cancellation handler. */ cbuffer.cond = cond; diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S index cdcf6d2..8d09e22 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S +++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S @@ -83,8 +83,12 @@ __pthread_cond_broadcast: subl $1, cond_lock-wakeup_seq(%ebx) jne 7f + /* Don't use requeue for pshared condvars. */ +8: cmpl $-1, %edi + je 9f + /* Wake up all threads. */ -8: movl $FUTEX_REQUEUE, %ecx + movl $FUTEX_REQUEUE, %ecx movl $SYS_futex, %eax movl $0x7fffffff, %esi movl $1, %edx @@ -97,10 +101,9 @@ __pthread_cond_broadcast: #ifndef __ASSUME_FUTEX_REQUEUE cmpl $-EINVAL, %eax je 9f -10: #endif - xorl %eax, %eax +10: xorl %eax, %eax popl %edi popl %esi popl %ebx @@ -138,14 +141,12 @@ __pthread_cond_broadcast: call __lll_mutex_unlock_wake jmp 8b -#ifndef __ASSUME_FUTEX_REQUEUE 9: /* The futex requeue functionality is not available. */ movl $0x7fffffff, %edx movl $FUTEX_WAKE, %ecx movl $SYS_futex, %eax ENTER_KERNEL jmp 10b -#endif .size __pthread_cond_broadcast, .-__pthread_cond_broadcast versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast, GLIBC_2_3_2) 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 ca5c142..06ad11c 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 @@ -68,11 +68,13 @@ __pthread_cond_timedwait: /* Store the reference to the mutex. If there is already a different value in there this is a bad user bug. */ -2: movl 24(%esp), %eax +2: cmpl $-1, dep_mutex(%ebx) + movl 24(%esp), %eax + je 17f movl %eax, dep_mutex(%ebx) /* Unlock the mutex. */ - xorl %edx, %edx +17: xorl %edx, %edx call __pthread_mutex_unlock_usercnt testl %eax, %eax diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S index ff3a1cc..b38fd6b 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S @@ -65,11 +65,13 @@ __pthread_cond_wait: /* Store the reference to the mutex. If there is already a different value in there this is a bad user bug. */ -2: movl 20(%esp), %eax +2: cmpl $-1, dep_mutex(%ebx) + movl 20(%esp), %eax + je 15f movl %eax, dep_mutex(%ebx) /* Unlock the mutex. */ - xorl %edx, %edx +15: xorl %edx, %edx call __pthread_mutex_unlock_usercnt testl %eax, %eax diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S index e6b2bbf..8e26681 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S @@ -72,8 +72,11 @@ __pthread_cond_broadcast: decl cond_lock-wakeup_seq(%rdi) jne 7f +8: cmpq $-1, %r8 + je 9f + /* Wake up all threads. */ -8: movq $FUTEX_REQUEUE, %rsi + movq $FUTEX_REQUEUE, %rsi movq $SYS_futex, %rax movl $1, %edx movq $0x7fffffff, %r10 @@ -82,10 +85,9 @@ __pthread_cond_broadcast: #ifndef __ASSUME_FUTEX_REQUEUE cmpq $-EINVAL, %rax je 9f -10: #endif - xorl %eax, %eax +10: xorl %eax, %eax retq .align 16 @@ -119,14 +121,12 @@ __pthread_cond_broadcast: subq $cond_lock-wakeup_seq, %rdi jmp 8b -#ifndef __ASSUME_FUTEX_REQUEUE 9: /* The futex requeue functionality is not available. */ movq $0x7fffffff, %rdx movq $FUTEX_WAKE, %rsi movq $SYS_futex, %rax syscall jmp 10b -#endif .size __pthread_cond_broadcast, .-__pthread_cond_broadcast versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast, 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 c0c8f55..e001441 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 @@ -71,15 +71,18 @@ __pthread_cond_timedwait: +--------------------------+ */ + cmpq $-1, dep_mutex(%rdi) + /* Prepare structure passed to cancellation handler. */ movq %rdi, 8(%rsp) movq %rsi, 16(%rsp) movq %rdx, %r13 + je 22f movq %rsi, dep_mutex(%rdi) /* Get internal lock. */ - movl $1, %esi +22: movl $1, %esi xorl %eax, %eax LOCK #if cond_lock == 0 diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S index d8681eb..e572874 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S @@ -117,14 +117,17 @@ __pthread_cond_wait: +--------------------------+ */ - /* Prepare structure passed to cancellation handler. */ + cmpq $-1, dep_mutex(%rdi) + + /* Prepare structure passed to cancellation handler. */ movq %rdi, 8(%rsp) movq %rsi, 16(%rsp) + je 15f movq %rsi, dep_mutex(%rdi) /* Get internal lock. */ - movl $1, %esi +15: movl $1, %esi xorl %eax, %eax LOCK #if cond_lock == 0 -- 2.7.4