* 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.
This commit is contained in:
Ulrich Drepper 2003-03-11 23:26:35 +00:00
parent 3e976b962a
commit 32a589b1ea
11 changed files with 58 additions and 13 deletions

View File

@ -1 +1 @@
NPTL 0.28 by Ulrich Drepper
NPTL 0.29 by Ulrich Drepper

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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. */

View File

@ -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;

View File

@ -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. */

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -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