diff options
-rw-r--r-- | nptl/Banner | 2 | ||||
-rw-r--r-- | nptl/ChangeLog | 11 | ||||
-rw-r--r-- | nptl/cancellation.c | 31 | ||||
-rw-r--r-- | nptl/pthreadP.h | 2 | ||||
-rw-r--r-- | nptl/sysdeps/pthread/pthread_cond_timedwait.c | 2 | ||||
-rw-r--r-- | nptl/sysdeps/pthread/pthread_cond_wait.c | 4 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S | 5 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S | 5 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S | 2 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S | 2 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S | 5 |
11 files changed, 58 insertions, 13 deletions
diff --git a/nptl/Banner b/nptl/Banner index 6e4ad3f789..7b44e76bdc 100644 --- a/nptl/Banner +++ b/nptl/Banner @@ -1 +1 @@ -NPTL 0.28 by Ulrich Drepper +NPTL 0.29 by Ulrich Drepper diff --git a/nptl/ChangeLog b/nptl/ChangeLog index a4cd4f5482..15b9cd71ad 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,5 +1,16 @@ 2003-03-11 Ulrich Drepper <drepper@redhat.com> + * cancellation.c (__pthread_enable_asynccancel_2): New function. + * pthreadP.h: Declare __pthread_enable_asynccancel_2. + * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S + (__pthread_cond_timedwait): Use __pthread_enable_asynccancel_2 + instead of __pthread_enable_asynccancel. + * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S + (__pthread_cond_wait): Likewise. + * sysdeps/pthread/pthread_cond_timedwait.c + (__pthread_cond_timedwait): Likewise. + * sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Likewise. + * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S (__condvar_cleanup): Wake up all waiters in case we got signaled after being woken up but before disabling asynchronous diff --git a/nptl/cancellation.c b/nptl/cancellation.c index f136bbb4c4..1dfbe4baca 100644 --- a/nptl/cancellation.c +++ b/nptl/cancellation.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -57,6 +57,35 @@ __pthread_enable_asynccancel (void) return oldval; } +/* XXX Ideally we have only one version. But this needs preparation. */ +void +internal_function attribute_hidden +__pthread_enable_asynccancel_2 (int *oldvalp) +{ + struct pthread *self = THREAD_SELF; + + while (1) + { + int oldval = *oldvalp = THREAD_GETMEM (self, cancelhandling); + int newval = oldval | CANCELTYPE_BITMASK; + + if (newval == oldval) + break; + + if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval, + oldval) == 0) + { + if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval)) + { + THREAD_SETMEM (self, result, PTHREAD_CANCELED); + __do_cancel (); + } + + break; + } + } +} + void internal_function attribute_hidden diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index c9f31e801a..ca458974c8 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -319,6 +319,8 @@ extern int __pthread_cond_wait_2_0 (pthread_cond_2_0_t *cond, /* The two functions are in libc.so and not exported. */ extern int __libc_enable_asynccancel (void) attribute_hidden; +extern void __libc_enable_asynccancel_2 (int *oldvalp) + internal_function attribute_hidden; extern void __libc_disable_asynccancel (int oldtype) internal_function attribute_hidden; diff --git a/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/nptl/sysdeps/pthread/pthread_cond_timedwait.c index 417f873868..0635e6ed93 100644 --- a/nptl/sysdeps/pthread/pthread_cond_timedwait.c +++ b/nptl/sysdeps/pthread/pthread_cond_timedwait.c @@ -120,7 +120,7 @@ __pthread_cond_timedwait (cond, mutex, abstime) lll_mutex_unlock (cond->__data.__lock); /* Enable asynchronous cancellation. Required by the standard. */ - cbuffer.oldtype = __pthread_enable_asynccancel (); + __pthread_enable_asynccancel_2 (&cbuffer.oldtype); /* Wait until woken by signal or broadcast. Note that we truncate the 'val' value to 32 bits. */ diff --git a/nptl/sysdeps/pthread/pthread_cond_wait.c b/nptl/sysdeps/pthread/pthread_cond_wait.c index 78fcc7f6c6..b681ef26fd 100644 --- a/nptl/sysdeps/pthread/pthread_cond_wait.c +++ b/nptl/sysdeps/pthread/pthread_cond_wait.c @@ -123,7 +123,7 @@ __pthread_cond_wait (cond, mutex) lll_mutex_unlock (cond->__data.__lock); /* Enable asynchronous cancellation. Required by the standard. */ - cbuffer.oldtype = __pthread_enable_asynccancel (); + __pthread_enable_asynccancel_2 (&cbuffer.oldtype); /* Wait until woken by signal or broadcast. Note that we truncate the 'val' value to 32 bits. */ @@ -133,7 +133,7 @@ __pthread_cond_wait (cond, mutex) __pthread_disable_asynccancel (cbuffer.oldtype); /* We are going to look at shared data again, so get the lock. */ - lll_mutex_lock(cond->__data.__lock); + lll_mutex_lock (cond->__data.__lock); /* Check whether we are eligible for wakeup. */ val = cond->__data.__wakeup_seq; 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 122be6f714..f11a44ec43 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 @@ -108,8 +108,8 @@ __pthread_cond_timedwait: #endif jne 3f -4: call __pthread_enable_asynccancel - movl %eax, (%esp) +4: movl %esp, %eax + call __pthread_enable_asynccancel_2 /* Get the current time. */ movl %ebx, %edx @@ -145,6 +145,7 @@ __pthread_cond_timedwait: subl $wakeup_seq, %ebx movl %eax, %esi + movl (%esp), %eax call __pthread_disable_asynccancel /* Lock. */ 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 b3a49e794a..c13c38290e 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 @@ -165,8 +165,8 @@ __pthread_cond_wait: #endif jne 3f -4: call __pthread_enable_asynccancel - movl %eax, (%esp) +4: movl %esp, %eax + call __pthread_enable_asynccancel_2 movl %esi, %ecx /* movl $FUTEX_WAIT, %ecx */ movl %edi, %edx @@ -175,6 +175,7 @@ __pthread_cond_wait: ENTER_KERNEL subl $wakeup_seq, %ebx + movl (%esp), %eax call __pthread_disable_asynccancel /* Lock. */ diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S index e7e1707a48..1585921ff0 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S @@ -49,7 +49,7 @@ __lll_lock_wait: xorq %r10, %r10 /* No timeout. */ 1: - leal -1(%esi), %edx /* account for the preceeded xadd. */ + leaq -1(%rsi), %rdx /* account for the preceeded xadd. */ movq %r10, %rsi /* movl $FUTEX_WAIT, %ecx */ movq $SYS_futex, %rax syscall diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S index a494e0efaa..55e4ec4682 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S @@ -50,7 +50,7 @@ __lll_mutex_lock_wait: xorq %r10, %r10 /* No timeout. */ 1: - leal 1(%esi), %edx /* account for the preceeded xadd. */ + leaq 1(%rsi), %rdx /* account for the preceeded xadd. */ movq %r10, %rsi /* movl $FUTEX_WAIT, %ecx */ movq $SYS_futex, %rax syscall 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 c15566fdf0..193cc081e1 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 @@ -153,9 +153,10 @@ __pthread_cond_wait: #endif jne 3f -4: callq __pthread_enable_asynccancel - movq %rax, (%rsp) +4: movq %rsp, %edi + callq __pthread_enable_asynccancel_2 + movq 8(%rsp), %rdi xorq %r10, %r10 movq %r12, %rdx addq $wakeup_seq-cond_lock, %rdi |