about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2009-07-17 15:50:23 -0700
committerUlrich Drepper <drepper@redhat.com>2009-07-17 15:50:23 -0700
commit0adae4681750bea9eb729c8935d4b152de4a6b68 (patch)
treebca81eae4d40b31cc66782d8f297150290c10cc3
parentc3c2f3cf56ffcfd200f6c26aa5492049140bbbcb (diff)
downloadglibc-0adae4681750bea9eb729c8935d4b152de4a6b68.tar.gz
glibc-0adae4681750bea9eb729c8935d4b152de4a6b68.tar.xz
glibc-0adae4681750bea9eb729c8935d4b152de4a6b68.zip
Optimize x86-64 sem_wait for uncontested semaphore.
-rw-r--r--nptl/ChangeLog3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S51
2 files changed, 30 insertions, 24 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 5204ad10ca..5db47a138b 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,5 +1,8 @@
 2009-07-17  Ulrich Drepper  <drepper@redhat.com>
 
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S (sem_wait): Optimize
+	handling of uncontested semaphore.
+
 	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
 	(__condvar_cleanup): Rewrite to use cfi directives instead of
 	hand-coded unwind tables.
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
index de6a53b015..a01d745a17 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
@@ -40,18 +40,11 @@ sem_wait:
 	cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0)
 	cfi_lsda(DW_EH_PE_udata4, .LexceptSTART)
 #endif
-	pushq	%r12
-	cfi_adjust_cfa_offset(8)
-	cfi_rel_offset(%r12, 0)
-	pushq	%r13
-	cfi_adjust_cfa_offset(8)
-	cfi_rel_offset(%r13, 0)
-	movq	%rdi, %r13
 
 #if VALUE == 0
-	movl	(%r13), %eax
+	movl	(%rdi), %eax
 #else
-	movl	VALUE(%r13), %eax
+	movl	VALUE(%rdi), %eax
 #endif
 2:	testl	%eax, %eax
 	je	1f
@@ -59,27 +52,24 @@ sem_wait:
 	leal	-1(%rax), %edx
 	LOCK
 #if VALUE == 0
-	cmpxchgl %edx, (%r13)
+	cmpxchgl %edx, (%rdi)
 #else
-	cmpxchgl %edx, VALUE(%r13)
+	cmpxchgl %edx, VALUE(%rdi)
 #endif
 	jne	2b
 
-7:	xorl	%eax, %eax
-
-9:	popq	%r13
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(%r13)
-	popq	%r12
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(%r12)
-
+	xorl	%eax, %eax
 	retq
 
-	cfi_adjust_cfa_offset(2 * 8)
-	cfi_rel_offset(%r12, 8)
+1:	pushq	%r12
+	cfi_adjust_cfa_offset(8)
+	cfi_rel_offset(%r12, 0)
+	pushq	%r13
+	cfi_adjust_cfa_offset(8)
 	cfi_rel_offset(%r13, 0)
-1:	LOCK
+	movq	%rdi, %r13
+
+	LOCK
 	addq	$1, NWAITERS(%r13)
 
 .LcleanupSTART:
@@ -128,8 +118,21 @@ sem_wait:
 
 	LOCK
 	subq	$1, NWAITERS(%r13)
-	jmp	7b
 
+	xorl	%eax, %eax
+
+9:	popq	%r13
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r13)
+	popq	%r12
+	cfi_adjust_cfa_offset(-8)
+	cfi_restore(%r12)
+
+	retq
+
+	cfi_adjust_cfa_offset(2 * 8)
+	cfi_rel_offset(%r12, 8)
+	cfi_rel_offset(%r13, 0)
 4:	negq	%r12
 #if USE___THREAD
 	movq	errno@gottpoff(%rip), %rdx