about summary refs log tree commit diff
path: root/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2008-01-10 18:34:43 +0000
committerUlrich Drepper <drepper@redhat.com>2008-01-10 18:34:43 +0000
commitab355d9aa5186937757b20b93f7d52ea3926427a (patch)
tree202797696b5ede624ce3e0bfeb14e39dc4d5dc5f /nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
parentf6bacb8ef4dfcee39864d6383e3660d8ac267d23 (diff)
downloadglibc-ab355d9aa5186937757b20b93f7d52ea3926427a.tar.gz
glibc-ab355d9aa5186937757b20b93f7d52ea3926427a.tar.xz
glibc-ab355d9aa5186937757b20b93f7d52ea3926427a.zip
* pthread-errnos.sym: Add EOVERFLOW.
	* sysdeps/unix/sysv/linux/structsem.sym: Add SEM_VALUE_MAX.
	* sysdeps/unix/sysv/linux/sem_post.c: Don't overflow value field.
	* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S41
1 files changed, 38 insertions, 3 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
index ac045b6e34..2edcdde4f0 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/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.
 
@@ -34,12 +34,21 @@ __new_sem_post:
 
 	movl	8(%esp), %ebx
 
+#if VALUE == 0
+	movl	(%ebx), %eax
+#else
+	movl	VALUE(%ebx), %eax
+#endif
+0:	cmpl	$SEM_VALUE_MAX, %eax
+	je	3f
+	leal	1(%eax), %edx
 	LOCK
 #if VALUE == 0
-	addl	$1, (%ebx)
+	cmpxchgl %edx, (%ebx)
 #else
-	addl	$1, VALUE(%ebx)
+	cmpxchgl %edx, VALUE(%ebx)
 #endif
+	jnz	0b
 
 	cmpl	$0, NWAITERS(%ebx)
 	je	2f
@@ -82,6 +91,32 @@ __new_sem_post:
 	orl	$-1, %eax
 	popl	%ebx
 	ret
+
+3:
+#ifdef PIC
+	call	__i686.get_pc_thunk.bx
+#else
+	movl	$5f, %ebx
+5:
+#endif
+	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
+#if USE___THREAD
+# ifdef NO_TLS_DIRECT_SEG_REFS
+	movl	errno@gotntpoff(%ebx), %edx
+	addl	%gs:0, %edx
+	movl	$EOVERFLOW, (%edx)
+# else
+	movl	errno@gotntpoff(%ebx), %edx
+	movl	$EOVERFLOW, %gs:(%edx)
+# endif
+#else
+	call	__errno_location@plt
+	movl	$EOVERFLOW, (%eax)
+#endif
+
+	orl	$-1, %eax
+	popl	%ebx
+	ret
 	.size	__new_sem_post,.-__new_sem_post
 	versioned_symbol(libpthread, __new_sem_post, sem_post, GLIBC_2_1)
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)