* 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.
-NPTL 0.28 by Ulrich Drepper
+NPTL 0.29 by Ulrich Drepper
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
-/* 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.
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
/* 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;
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. */
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. */
__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;
#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
subl $wakeup_seq, %ebx
movl %eax, %esi
+ movl (%esp), %eax
call __pthread_disable_asynccancel
/* Lock. */
#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
ENTER_KERNEL
subl $wakeup_seq, %ebx
+ movl (%esp), %eax
call __pthread_disable_asynccancel
/* Lock. */
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
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
#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