From 4773086e0498c99ee11422fc39606e9a53f12502 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 18 Mar 2003 05:31:53 +0000 Subject: Update. * 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. --- nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h | 118 ++++++++++++++--------- 1 file changed, 70 insertions(+), 48 deletions(-) (limited to 'nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h') diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h index b64bf1ca15..fc37e5d4fb 100644 --- a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h @@ -86,54 +86,85 @@ __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)) +/* 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 __attribute__ ((always_inline)) __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)) -extern void ___lll_mutex_lock (int *, int) attribute_hidden; +extern void __lll_lock_wait (int *futex, int val) attribute_hidden; static inline void __attribute__ ((always_inline)) __lll_mutex_lock (int *futex) { - int oldval; - int val = *futex; - - do - oldval = val; - while ((val = lll_compare_and_swap (futex, oldval, oldval + 1)) != oldval); - if (oldval > 0) - ___lll_mutex_lock (futex, oldval + 1); + int val = __lll_add (futex, 1); + + if (__builtin_expect (val != 0, 0)) + __lll_lock_wait (futex, val); } #define lll_mutex_lock(futex) __lll_mutex_lock (&(futex)) -extern int ___lll_mutex_timedlock (int *, const struct timespec *, int) - attribute_hidden; +extern int __lll_timedlock_wait (int *futex, int val, const struct timespec *) + attribute_hidden; static inline int __attribute__ ((always_inline)) __lll_mutex_timedlock (int *futex, const struct timespec *abstime) { - int oldval; - int val = *futex; + int val = __lll_add (futex, 1); int result = 0; - do - oldval = val; - while ((val = lll_compare_and_swap (futex, oldval, oldval + 1)) != oldval); - if (oldval > 0) - result = ___lll_mutex_timedlock (futex, abstime, oldval + 1); + if (__builtin_expect (val != 0, 0)) + result = __lll_timedlock_wait (futex, val, abstime); return result; } @@ -145,13 +176,9 @@ static inline void __attribute__ ((always_inline)) __lll_mutex_unlock (int *futex) { - int oldval; - int val = *futex; + int val = __lll_test_and_set (futex, 0); - do - oldval = val; - while ((val = lll_compare_and_swap (futex, oldval, 0)) != oldval); - if (oldval > 1) + if (__builtin_expect (val > 1, 0)) lll_futex_wake (futex, 1); } #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 thread ID while the clone is running and is reset to zero afterwards. */ -static inline void -__attribute__ ((always_inline)) -__lll_wait_tid (int *ptid) -{ - int tid; - - while ((tid = *ptid) != 0) - lll_futex_wait (ptid, tid); -} -#define lll_wait_tid(tid) __lll_wait_tid(&(tid)) - - -extern int ___lll_timedwait_tid (int *, const struct timespec *) +#define lll_wait_tid(tid) \ + do \ + { \ + __typeof (tid) __tid; \ + while ((__tid = (tid)) != 0) \ + lll_futex_wait (&(tid), __tid); \ + } \ + while (0) + +extern int __lll_timedwait_tid (int *, const struct timespec *) 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) __lll_timedwait_tid (&(tid), abstime) +#define lll_timedwait_tid(tid, abstime) \ + ({ \ + int __res = 0; \ + if ((tid) != 0) \ + __res = __lll_timedwait_tid (&(tid), (abstime)); \ + __res; \ + }) /* Conditional variable handling. */ -- cgit 1.4.1