aboutsummaryrefslogtreecommitdiff
path: root/nptl/sysdeps/unix/sysv/linux/x86_64
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-09-02 18:59:24 +0000
committerUlrich Drepper <drepper@redhat.com>2004-09-02 18:59:24 +0000
commit73f7c32c47ab2397935d9fc2aeaa594794b38c7e (patch)
tree1a0f7d20c9009fbd67c33495f9db0a5d665092b3 /nptl/sysdeps/unix/sysv/linux/x86_64
parent86aca5ac58e152336e676bc1231acac6adc32068 (diff)
downloadglibc-73f7c32c47ab2397935d9fc2aeaa594794b38c7e.tar
glibc-73f7c32c47ab2397935d9fc2aeaa594794b38c7e.tar.gz
glibc-73f7c32c47ab2397935d9fc2aeaa594794b38c7e.tar.bz2
glibc-73f7c32c47ab2397935d9fc2aeaa594794b38c7e.zip
[BZ #357]
Update. 2004-09-02 Steven Munroe <sjmunroe@us.ibm.com> [BZ #357] * stdlib/tst-setcontext.c (test_stack): Added test for stack clobber. (main): Call test_stack. * sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S (__getcontext): Push stack frame then save parms in local frame. Improve instruction scheduling. * sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S (__swapcontext): Likewise.
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/x86_64')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S24
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S51
3 files changed, 67 insertions, 10 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
index a7bc5816cc..e5cc605f24 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
@@ -100,7 +100,7 @@ typedef union
unsigned long long int __wakeup_seq;
unsigned long long int __woken_seq;
void *__mutex;
- int __clock;
+ int __nwaiters;
unsigned int __broadcast_seq;
} __data;
char __size[__SIZEOF_PTHREAD_COND_T];
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 95f8aabd11..67bec6caa7 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
@@ -111,6 +111,7 @@ __pthread_cond_timedwait:
movq 8(%rsp), %rdi
incq total_seq(%rdi)
incl cond_futex(%rdi)
+ addl $(1 << clock_bits), cond_nwaiters(%rdi)
/* Install cancellation handler. */
#ifdef PIC
@@ -135,8 +136,9 @@ __pthread_cond_timedwait:
/* Get the clock number. Note that the field in the condvar
structure stores the number minus 1. */
movq 8(%rsp), %rdi
- movl cond_clock(%rdi), %edi
- /* Only clocks 0 and 1 are allowed. Both are handled in the
+ movl cond_nwaiters(%rdi), %edi
+ andl $((1 << clock_bits) - 1), %edi
+ /* Only clocks 0 and 1 are allowed so far. Both are handled in the
kernel. */
leaq 24(%rsp), %rsi
movq $__NR_clock_gettime, %rax
@@ -244,7 +246,23 @@ __pthread_cond_timedwait:
9: xorq %r14, %r14
14: incq woken_seq(%rdi)
-24: LOCK
+24: subl $(1 << clock_bits), cond_nwaiters(%rdi)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ cmpq $0xffffffffffffffff, total_seq(%rdi)
+ jne 25f
+ movl cond_nwaiters(%rdi), %eax
+ andl $~((1 << clock_bits) - 1), %eax
+ jne 25f
+
+ addq $cond_nwaiters, %rdi
+ movq $SYS_futex, %rax
+ movq $FUTEX_WAKE, %rsi
+ movl $1, %edx
+ syscall
+ subq $cond_nwaiters, %rdi
+
+25: LOCK
#if cond_lock == 0
decl (%rdi)
#else
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 9e7da301d3..f5de0a280c 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
@@ -40,6 +40,8 @@
.globl __condvar_cleanup
.hidden __condvar_cleanup
__condvar_cleanup:
+ pushq %r12
+
/* Get internal lock. */
movq %rdi, %r8
movq 8(%rdi), %rdi
@@ -66,12 +68,28 @@ __condvar_cleanup:
jne 3f
incq wakeup_seq(%rdi)
-
incq woken_seq(%rdi)
-
incl cond_futex(%rdi)
-3: LOCK
+3: subl $(1 << clock_bits), cond_nwaiters(%rdi)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ xorq %r12, %r12
+ cmpq $0xffffffffffffffff, total_seq(%rdi)
+ jne 4f
+ movl cond_nwaiters(%rdi), %eax
+ andl $~((1 << clock_bits) - 1), %eax
+ jne 4f
+
+ addq $cond_nwaiters, %rdi
+ movq $SYS_futex, %rax
+ movq $FUTEX_WAKE, %rsi
+ movl $1, %edx
+ syscall
+ subq $cond_nwaiters, %rdi
+ movq $1, %r12
+
+4: LOCK
#if cond_lock == 0
decl (%rdi)
#else
@@ -84,15 +102,19 @@ __condvar_cleanup:
callq __lll_mutex_unlock_wake
/* Wake up all waiters to make sure no signal gets lost. */
-2: addq $cond_futex, %rdi
+2: testq %r12, %r12
+ jnz 5f
+ addq $cond_futex, %rdi
movq $FUTEX_WAKE, %rsi
movl $0x7fffffff, %edx
movq $SYS_futex, %rax
syscall
- movq 16(%r8), %rdi
+5: movq 16(%r8), %rdi
callq __pthread_mutex_cond_lock
+ popq %r12
+
retq
.size __condvar_cleanup, .-__condvar_cleanup
@@ -157,6 +179,7 @@ __pthread_cond_wait:
movq 8(%rsp), %rdi
incq total_seq(%rdi)
incl cond_futex(%rdi)
+ addl $(1 << clock_bits), cond_nwaiters(%rdi)
/* Install cancellation handler. */
#ifdef PIC
@@ -229,7 +252,23 @@ __pthread_cond_wait:
incq woken_seq(%rdi)
/* Unlock */
-16: LOCK
+16: subl $(1 << clock_bits), cond_nwaiters(%rdi)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ cmpq $0xffffffffffffffff, total_seq(%rdi)
+ jne 17f
+ movl cond_nwaiters(%rdi), %eax
+ andl $~((1 << clock_bits) - 1), %eax
+ jne 17f
+
+ addq $cond_nwaiters, %rdi
+ movq $SYS_futex, %rax
+ movq $FUTEX_WAKE, %rsi
+ movl $1, %edx
+ syscall
+ subq $cond_nwaiters, %rdi
+
+17: LOCK
#if cond_lock == 0
decl (%rdi)
#else