summaryrefslogtreecommitdiff
path: root/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S36
1 files changed, 30 insertions, 6 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
index adbbcdfa71..b4014c6505 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -30,12 +30,21 @@
.type sem_post,@function
.align 16
sem_post:
+#if VALUE == 0
+ movl (%rdi), %eax
+#else
+ movl VALUE(%rdi), %eax
+#endif
+0: cmpl $SEM_VALUE_MAX, %eax
+ je 3f
+ leal 1(%eax), %esi
LOCK
#if VALUE == 0
- addl $1, (%rdi)
+ cmpxchgl %esi, (%rdi)
#else
- addl $1, VALUE(%rdi)
+ cmpxchgl %esi, VALUE(%rdi)
#endif
+ jnz 0b
cmpq $0, NWAITERS(%rdi)
je 2f
@@ -54,13 +63,28 @@ sem_post:
1:
#if USE___THREAD
- movq errno@gottpoff(%rip), %rdx
- movl $EINVAL, %fs:(%rdx)
+ movl $EINVAL, %eax
#else
callq __errno_location@plt
- movl $EINVAL, (%rax)
+ movl $EINVAL, %edx
#endif
+ jmp 4f
+3:
+#if USE___THREAD
+ movl $EOVERFLOW, %eax
+#else
+ callq __errno_location@plt
+ movl $EOVERFLOW, %edx
+#endif
+
+4:
+#if USE___THREAD
+ movq errno@gottpoff(%rip), %rdx
+ movl %eax, %fs:(%rdx)
+#else
+ movl %edx, (%rax)
+#endif
orl $-1, %eax
retq
.size sem_post,.-sem_post