From a032a6587011cbdac8c2f7e11f15dc4e592bbb55 Mon Sep 17 00:00:00 2001 From: Austin Foxley Date: Tue, 16 Feb 2010 12:27:18 -0800 Subject: mass sync with glibc nptl Signed-off-by: Austin Foxley --- libpthread/nptl/sysdeps/unix/sysv/linux/sem_post.c | 30 +++++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/sem_post.c') diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_post.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_post.c index 7f0b67918..7ed0df89a 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_post.c +++ b/libpthread/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 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 , 2003. @@ -27,14 +27,30 @@ int __new_sem_post (sem_t *sem) { - int *futex = (int *) sem; + struct new_sem *isem = (struct new_sem *) sem; - int nr = atomic_increment_val (futex); - int err = lll_futex_wake (futex, nr); - if (__builtin_expect (err, 0) < 0) + __typeof (isem->value) cur; + do { - __set_errno (-err); - return -1; + 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) + { + int err = lll_futex_wake (&isem->value, 1, + isem->private ^ FUTEX_PRIVATE_FLAG); + if (__builtin_expect (err, 0) < 0) + { + __set_errno (-err); + return -1; + } } return 0; } -- cgit v1.2.3