* sysdeps/unix/sysv/linux/ia64/pthread_once.c: Use __builtin_expect.
	Use __lll_add instead of spelling it out.  Use protected symbol names.
	* sysdeps/unix/sysv/linux/ia64/sem_post.c: Use __builtin_expect.
	Use __lll_add.
	* sysdeps/unix/sysv/linux/ia64/lowlevellock.h (__lll_compare_and_swap):
	Renamed from lll_compare_and_swap.  Use new name where necessary.
	(__lll_add): Defined.
	(__lll_dec_if_positive): Defined.
	(__lll_test_and_set): Defined.
	* sysdeps/ia64/pthread_spin_init.c: Removed.
	* sysdeps/unix/sysv/linux/ia64/lowlevelmutex.c: Removed.
	* sysdeps/unix/sysv/linux/ia64/sem_trywait.c: Removed.
	* sysdeps/unix/sysv/linux/ia64/sem_wait.c: Removed.
	* sysdeps/unix/sysv/linux/ia64/lowlevellock.c: Removed.
	* sysdeps/unix/sysv/linux/ia64/libc-lowlevellock.c: Removed.
	* sysdeps/unix/sysv/linux/ia64/libc-lowlevelmutex.c: Removed.
	* sysdeps/unix/sysv/linux/ia64/sem_timedwait.c: Removed.
This commit is contained in:
Ulrich Drepper 2003-03-18 05:31:53 +00:00
parent 970269474a
commit 4773086e04
15 changed files with 102 additions and 525 deletions

View File

@ -1 +1 @@
NPTL 0.29 by Ulrich Drepper NPTL 0.30 by Ulrich Drepper

View File

@ -5,6 +5,23 @@
2003-03-17 Ulrich Drepper <drepper@redhat.com> 2003-03-17 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/ia64/pthread_once.c: Use __builtin_expect.
Use __lll_add instead of spelling it out. Use protected symbol names.
* sysdeps/unix/sysv/linux/ia64/sem_post.c: Use __builtin_expect.
Use __lll_add.
* sysdeps/unix/sysv/linux/ia64/lowlevellock.h (__lll_compare_and_swap):
Renamed from lll_compare_and_swap. Use new name where necessary.
(__lll_add): Defined.
(__lll_dec_if_positive): Defined.
(__lll_test_and_set): Defined.
* sysdeps/ia64/pthread_spin_init.c: Removed.
* sysdeps/unix/sysv/linux/ia64/lowlevelmutex.c: Removed.
* sysdeps/unix/sysv/linux/ia64/sem_trywait.c: Removed.
* sysdeps/unix/sysv/linux/ia64/sem_wait.c: Removed.
* sysdeps/unix/sysv/linux/ia64/lowlevellock.c: Removed.
* sysdeps/unix/sysv/linux/ia64/libc-lowlevellock.c: Removed.
* sysdeps/unix/sysv/linux/ia64/libc-lowlevelmutex.c: Removed.
* sysdeps/unix/sysv/linux/ia64/sem_timedwait.c: Removed.
* sysdeps/ia64/bits/atomic.h: Add __builtin_expect where appropriate. * sysdeps/ia64/bits/atomic.h: Add __builtin_expect where appropriate.
* sysdeps/ia64/pthread_spin_unlock.c (pthread_spin_unlock): Use * sysdeps/ia64/pthread_spin_unlock.c (pthread_spin_unlock): Use
__sync_lock_release_si. __sync_lock_release_si.

View File

@ -1,20 +0,0 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Not needed. pthread_spin_init is an alias for pthread_spin_unlock. */

View File

@ -26,4 +26,3 @@ pthread_spin_unlock (pthread_spinlock_t *lock)
__sync_lock_release_si ((int *) lock); __sync_lock_release_si ((int *) lock);
return 0; return 0;
} }
strong_alias (pthread_spin_unlock, pthread_spin_init)

View File

@ -1,19 +0,0 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Not needed. lll_mutex_* implementation is the same as lll_*. */

View File

@ -1,21 +0,0 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* No difference to lowlevelmutex.c */
#include "lowlevelmutex.c"

View File

@ -1,85 +0,0 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <sys/time.h>
int
lll_unlock_wake_cb (futex)
int *futex;
{
int oldval;
int val = *futex;
do
oldval = val;
while ((val = lll_compare_and_swap (futex, oldval, 0)) != oldval);
if (oldval > 1)
lll_futex_wake (futex, 1);
return 0;
}
hidden_proto (lll_unlock_wake_cb)
int
___lll_timedwait_tid (ptid, abstime)
int *ptid;
const struct timespec *abstime;
{
int tid;
if (abstime == NULL || abstime->tv_nsec >= 1000000000)
return EINVAL;
/* Repeat until thread terminated. */
while ((tid = *ptid) != 0)
{
/* Get current time. */
struct timeval tv;
__gettimeofday (&tv, NULL);
/* Determine relative timeout. */
struct timespec rt;
rt.tv_sec = abstime->tv_sec - tv.tv_sec;
rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
if (rt.tv_nsec < 0)
{
rt.tv_nsec += 1000000000;
rt.tv_sec--;
}
/* Already timed out? */
if (rt.tv_sec < 0)
return ETIMEDOUT;
/* Wait until thread terminates. */
int err = lll_futex_timed_wait (ptid, tid, &rt);
/* Woken due to timeout? */
if (err == -ETIMEDOUT)
/* Yes. */
return ETIMEDOUT;
}
return 0;
}
hidden_proto (___lll_timedwait_tid)

View File

@ -86,38 +86,73 @@
__r10 == -1 ? -__r8 : __r8; \ __r10 == -1 ? -__r8 : __r8; \
}) })
#define lll_compare_and_swap(futex, oldval, newval) \ #define __lll_compare_and_swap(futex, oldval, newval) \
__sync_val_compare_and_swap_si ((futex), (oldval), (newval)) __sync_val_compare_and_swap_si ((futex), (oldval), (newval))
/* Add inc to *futex atomically and return the old value. */
#define __lll_add(futex, inc) \
({ \
int __val, __oldval; \
int *__futex = (futex); \
int __inc = inc; \
\
__val = *__futex; \
do \
{ \
__oldval = __val; \
__val = __lll_compare_and_swap (__futex, __oldval, __oldval + __inc); \
} \
while (__builtin_expect (__val != __oldval, 0)); \
__val; \
})
/* Decrement *futex if it is > 0, and return the old value. */
#define __lll_dec_if_positive(futex) \
({ \
int __val, __oldval; \
int *__futex = (futex); \
\
__val = *__futex; \
do \
{ \
if (__builtin_expect (__val <= 0, 0)) \
break; \
__oldval = __val; \
__val = __lll_compare_and_swap (__futex, __oldval, __oldval - 1); \
} \
while (__builtin_expect (__val != __oldval, 0)); \
__val; \
})
/* Atomically store newval and return the old value. */
#define __lll_test_and_set(futex, newval) \
__sync_lock_test_and_set_si ((futex), (newval))
static inline int static inline int
__attribute__ ((always_inline)) __attribute__ ((always_inline))
__lll_mutex_trylock (int *futex) __lll_mutex_trylock (int *futex)
{ {
return lll_compare_and_swap (futex, 0, 1) != 0; return __lll_compare_and_swap (futex, 0, 1) != 0;
} }
#define lll_mutex_trylock(futex) __lll_mutex_trylock (&(futex)) #define lll_mutex_trylock(futex) __lll_mutex_trylock (&(futex))
extern void ___lll_mutex_lock (int *, int) attribute_hidden; extern void __lll_lock_wait (int *futex, int val) attribute_hidden;
static inline void static inline void
__attribute__ ((always_inline)) __attribute__ ((always_inline))
__lll_mutex_lock (int *futex) __lll_mutex_lock (int *futex)
{ {
int oldval; int val = __lll_add (futex, 1);
int val = *futex;
do if (__builtin_expect (val != 0, 0))
oldval = val; __lll_lock_wait (futex, val);
while ((val = lll_compare_and_swap (futex, oldval, oldval + 1)) != oldval);
if (oldval > 0)
___lll_mutex_lock (futex, oldval + 1);
} }
#define lll_mutex_lock(futex) __lll_mutex_lock (&(futex)) #define lll_mutex_lock(futex) __lll_mutex_lock (&(futex))
extern int ___lll_mutex_timedlock (int *, const struct timespec *, int) extern int __lll_timedlock_wait (int *futex, int val, const struct timespec *)
attribute_hidden; attribute_hidden;
@ -125,15 +160,11 @@ static inline int
__attribute__ ((always_inline)) __attribute__ ((always_inline))
__lll_mutex_timedlock (int *futex, const struct timespec *abstime) __lll_mutex_timedlock (int *futex, const struct timespec *abstime)
{ {
int oldval; int val = __lll_add (futex, 1);
int val = *futex;
int result = 0; int result = 0;
do if (__builtin_expect (val != 0, 0))
oldval = val; result = __lll_timedlock_wait (futex, val, abstime);
while ((val = lll_compare_and_swap (futex, oldval, oldval + 1)) != oldval);
if (oldval > 0)
result = ___lll_mutex_timedlock (futex, abstime, oldval + 1);
return result; return result;
} }
@ -145,13 +176,9 @@ static inline void
__attribute__ ((always_inline)) __attribute__ ((always_inline))
__lll_mutex_unlock (int *futex) __lll_mutex_unlock (int *futex)
{ {
int oldval; int val = __lll_test_and_set (futex, 0);
int val = *futex;
do if (__builtin_expect (val > 1, 0))
oldval = val;
while ((val = lll_compare_and_swap (futex, oldval, 0)) != oldval);
if (oldval > 1)
lll_futex_wake (futex, 1); lll_futex_wake (futex, 1);
} }
#define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex)) #define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex))
@ -182,30 +209,25 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
wakeup when the clone terminates. The memory location contains the wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero thread ID while the clone is running and is reset to zero
afterwards. */ afterwards. */
static inline void #define lll_wait_tid(tid) \
__attribute__ ((always_inline)) do \
__lll_wait_tid (int *ptid) { \
{ __typeof (tid) __tid; \
int tid; while ((__tid = (tid)) != 0) \
lll_futex_wait (&(tid), __tid); \
} \
while (0)
while ((tid = *ptid) != 0) extern int __lll_timedwait_tid (int *, const struct timespec *)
lll_futex_wait (ptid, tid);
}
#define lll_wait_tid(tid) __lll_wait_tid(&(tid))
extern int ___lll_timedwait_tid (int *, const struct timespec *)
attribute_hidden; attribute_hidden;
static inline int
__attribute__ ((always_inline))
__lll_timedwait_tid (int *ptid, const struct timespec *abstime)
{
if (*ptid == 0)
return 0;
return ___lll_timedwait_tid (ptid, abstime); #define lll_timedwait_tid(tid, abstime) \
} ({ \
#define lll_timedwait_tid(tid, abstime) __lll_timedwait_tid (&(tid), abstime) int __res = 0; \
if ((tid) != 0) \
__res = __lll_timedwait_tid (&(tid), (abstime)); \
__res; \
})
/* Conditional variable handling. */ /* Conditional variable handling. */

View File

@ -1,100 +0,0 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <sys/time.h>
void
___lll_mutex_lock (futex, newval)
int *futex;
int newval;
{
int oldval, val;
do
{
lll_futex_wait (futex, newval);
val = *futex;
do
oldval = val;
while ((val = lll_compare_and_swap (futex, oldval, oldval + 1))
!= oldval);
newval = val + 1;
}
while (val != 0);
*futex = 2;
}
hidden_proto (___lll_mutex_lock)
int
___lll_mutex_timedlock (futex, abstime, newval)
int *futex;
const struct timespec *abstime;
int newval;
{
/* Reject invalid timeouts. */
if (abstime->tv_nsec >= 1000000000)
return EINVAL;
int oldval, val;
do
{
/* Get the current time. */
struct timeval tv;
__gettimeofday (&tv, NULL);
/* Compute relative timeout. */
struct timespec rt;
rt.tv_sec = abstime->tv_sec - tv.tv_sec;
rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
if (rt.tv_nsec < 0)
{
rt.tv_nsec += 1000000000;
--rt.tv_sec;
}
/* Already timed out? */
if (rt.tv_sec < 0)
return ETIMEDOUT;
/* Wait. */
int err = lll_futex_timed_wait (futex, newval, &rt);
/* If timed out return with an appropriate error. */
if (err == -ETIMEDOUT)
return ETIMEDOUT;
val = *futex;
do
oldval = val;
while ((val = lll_compare_and_swap (futex, oldval, oldval + 1))
!= oldval);
newval = val + 1;
}
while (val != 0);
*futex = 2;
return 0;
}
hidden_proto (___lll_mutex_timedlock)

View File

@ -52,9 +52,9 @@ __pthread_once (once_control, init_routine)
oldval = val; oldval = val;
newval = (oldval & 3) | __fork_generation | 1; newval = (oldval & 3) | __fork_generation | 1;
val = __lll_compare_and_swap (once_control, oldval, newval);
} }
while ((val = lll_compare_and_swap (once_control, oldval, newval)) while (__builtin_expect (val != oldval, 0));
!= oldval);
/* Check if another thread already runs the initializer. */ /* Check if another thread already runs the initializer. */
if ((oldval & 1) != 0) if ((oldval & 1) != 0)
@ -80,11 +80,7 @@ __pthread_once (once_control, init_routine)
/* Add one to *once_control. */ /* Add one to *once_control. */
val = *once_control; __lll_add (once_control, 1);
do
oldval = val;
while ((val = lll_compare_and_swap (once_control, oldval, oldval + 1))
!= oldval);
/* Wake up all other threads. */ /* Wake up all other threads. */
lll_futex_wake (once_control, INT_MAX); lll_futex_wake (once_control, INT_MAX);

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2003 Free Software Foundation, Inc. /* sem_post -- post to a POSIX semaphore. IA-64 version.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@ -25,20 +26,15 @@
#include <shlib-compat.h> #include <shlib-compat.h>
int int
__new_sem_post (sem_t *sem) __new_sem_post (sem_t *sem)
{ {
int oldval, val; int *futex = (int *) sem;
int err; int err, nr;
val = *(int *) sem; nr = __lll_add (futex, 1);
do err = lll_futex_wake (futex, nr + 1);
oldval = val; if (__builtin_expect (err, 0) < 0)
while ((val = lll_compare_and_swap ((int *) sem, oldval, oldval + 1))
!= oldval);
err = lll_futex_wake ((int *) sem, oldval + 1);
if (err < 0)
{ {
__set_errno (-err); __set_errno (-err);
return -1; return -1;

View File

@ -1,92 +0,0 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <internaltypes.h>
#include <semaphore.h>
#include <shlib-compat.h>
int
sem_timedwait (sem, abstime)
sem_t *sem;
const struct timespec *abstime;
{
int oldval, val;
val = *(int *) sem;
do
{
while (__builtin_expect (val == 0, 0))
{
/* Check for invalid timeout values. */
if (abstime->tv_nsec >= 1000000000)
{
__set_errno (EINVAL);
return -1;
}
/* Get the current time. */
struct timeval tv;
(void) __gettimeofday(&tv, NULL);
/* Compute the relative timeout. */
struct timespec rt;
rt.tv_sec = abstime->tv_sec - tv.tv_sec;
rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
if (rt.tv_nsec < 0)
{
rt.tv_nsec += 1000000000;
--rt.tv_sec;
}
/* Already timed out. */
if (rt.tv_sec < 0)
{
__set_errno (ETIMEDOUT);
return -1;
}
/* Do wait. */
int err = lll_futex_timed_wait ((int *) sem, 0, &rt);
/* Returned after timing out? */
if (err == -ETIMEDOUT)
{
__set_errno (ETIMEDOUT);
return -1;
}
/* Handle EINTR. */
if (err != 0 && err != -EWOULDBLOCK)
{
__set_errno (-err);
return -1;
}
val = *(int *) sem;
}
oldval = val;
}
while ((val = lll_compare_and_swap ((int *) sem, oldval, oldval - 1))
!= oldval);
return 0;
}

View File

@ -1,51 +0,0 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <internaltypes.h>
#include <semaphore.h>
#include <shlib-compat.h>
int
__new_sem_trywait (sem_t *sem)
{
int oldval, val = *(int *) sem;
do
{
if (__builtin_expect (val == 0, 0))
{
__set_errno (EAGAIN);
return -1;
}
oldval = val;
}
while ((val = lll_compare_and_swap ((int *) sem, oldval, oldval - 1))
!= oldval);
return 0;
}
versioned_symbol (libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1);
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
strong_alias (__new_sem_trywait, __old_sem_trywait)
compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0);
#endif

View File

@ -1,64 +0,0 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <internaltypes.h>
#include <semaphore.h>
#include <shlib-compat.h>
int
__new_sem_wait (sem_t *sem)
{
int oldval, val;
/* Atomically decrement semaphore counter if it is > 0. */
val = *(int *) sem;
do
{
while (__builtin_expect (val == 0, 0))
{
/* Do wait. */
int err = lll_futex_wait ((int *) sem, 0);
/* Handle EINTR. */
if (err != 0 && err != -EWOULDBLOCK)
{
__set_errno (-err);
return -1;
}
val = *(int *) sem;
}
oldval = val;
}
while ((val = lll_compare_and_swap ((int *) sem, oldval, oldval - 1))
!= oldval);
return 0;
}
versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
strong_alias (__new_sem_wait, __old_sem_wait)
compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0);
#endif

View File

@ -83,11 +83,10 @@ hidden_proto (__lll_timedlock_wait)
int int
lll_unlock_wake_cb (int *futex) lll_unlock_wake_cb (int *futex)
{ {
if (__lll_add (futex, -1) - 1 != 0) int val = __lll_test_and_set (futex, 0);
{
*futex = 0; if (__builtin_expect (val > 1, 0))
lll_futex_wake (futex, 1); lll_futex_wake (futex, 1);
}
return 0; return 0;
} }