about summary refs log tree commit diff
path: root/nptl/sysdeps/unix/sysv/linux/sem_post.c
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/sem_post.c
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/sem_post.c')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sem_post.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/sem_post.c b/nptl/sysdeps/unix/sysv/linux/sem_post.c
index 25b676fcd2..58b226f63d 100644
--- a/nptl/sysdeps/unix/sysv/linux/sem_post.c
+++ b/nptl/sysdeps/unix/sysv/linux/sem_post.c
@@ -1,5 +1,5 @@
 /* sem_post -- post to a POSIX semaphore.  Generic futex-using version.
-   Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -31,7 +31,18 @@ __new_sem_post (sem_t *sem)
 {
   struct new_sem *isem = (struct new_sem *) sem;
 
-  int nr = atomic_increment_val (&isem->value);
+  __typeof (isem->value) cur;
+  do
+    {
+      cur = isem->value;
+      if (isem->value == SEM_VALUE_MAX)
+	{
+	  __set_errno (EOVERFLOW);
+	  return -1;
+	}
+    }
+  while (atomic_compare_and_exchange_bool_acq (&isem->value, cur + 1, cur));
+
   atomic_full_barrier ();
   if (isem->nwaiters > 0)
     {