From 32c075e1f01849e161724bbd400ba77244e482cc Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 31 Jul 2007 13:33:18 +0000 Subject: . --- nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c') diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c index 3e88ee1866..30ef991bd0 100644 --- a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c +++ b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 Free Software Foundation, Inc. +/* Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek , 2006. @@ -30,6 +30,10 @@ __lll_robust_lock_wait (int *futex) int oldval = *futex; int tid = THREAD_GETMEM (THREAD_SELF, tid); + /* If the futex changed meanwhile try locking again. */ + if (oldval == 0) + goto try; + do { if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0)) @@ -41,6 +45,9 @@ __lll_robust_lock_wait (int *futex) continue; lll_futex_wait (futex, newval); + + try: + ; } while ((oldval = atomic_compare_and_exchange_val_acq (futex, tid | FUTEX_WAITERS, @@ -57,6 +64,11 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime) return EINVAL; int tid = THREAD_GETMEM (THREAD_SELF, tid); + int oldval = *futex; + + /* If the futex changed meanwhile try locking again. */ + if (oldval == 0) + goto try; do { @@ -80,7 +92,6 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime) return ETIMEDOUT; /* Wait. */ - int oldval = *futex; if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0)) return oldval; @@ -90,8 +101,13 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime) continue; lll_futex_timed_wait (futex, newval, &rt); + + try: + ; } - while (atomic_compare_and_exchange_bool_acq (futex, tid | FUTEX_WAITERS, 0)); + while ((oldval = atomic_compare_and_exchange_val_acq (futex, + tid | FUTEX_WAITERS, + 0)) != 0); return 0; } -- cgit v1.2.1