about summary refs log tree commit diff
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.gz
glibc-73f7c32c47ab2397935d9fc2aeaa594794b38c7e.tar.xz
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