summaryrefslogtreecommitdiff
path: root/nptl/pthread_rwlock_timedrdlock.c
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2012-11-05 21:12:10 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2012-11-05 21:12:52 +0530
commit8f861542dd0603bef99e126e509ece89514c1eeb (patch)
tree083f3bd20edfa09a2341e0340013c0781b4696ad /nptl/pthread_rwlock_timedrdlock.c
parent155ee340b875834693fbd1b7401af7fe88ace04d (diff)
[S390,PPC] Implement FUTEX_WAIT_BITSET for timedwait functions
Since the FUTEX_WAIT operation takes a relative timeout, the pthread_cond_timedwait and other timed function implementations have to get a relative timeout from the absolute timeout parameter it gets before it makes the futex syscall. This value is then converted back into an absolute timeout within the kernel. This is a waste and has hence been improved upon by a FUTEX_WAIT_BITSET operation (OR'd with FUTEX_CLOCK_REALTIME to make the kernel use the realtime clock instead of the default monotonic clock). This was implemented only in the x86 and sh assembly code and not in the C code. This patch implements support for FUTEX_WAIT_BITSET whenever available (since linux-2.6.29) for s390 and powerpc.
Diffstat (limited to 'nptl/pthread_rwlock_timedrdlock.c')
-rw-r--r--nptl/pthread_rwlock_timedrdlock.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/nptl/pthread_rwlock_timedrdlock.c b/nptl/pthread_rwlock_timedrdlock.c
index be8216d579..b7622abfa2 100644
--- a/nptl/pthread_rwlock_timedrdlock.c
+++ b/nptl/pthread_rwlock_timedrdlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003,2004,2007,2011 Free Software Foundation, Inc.
+/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
@@ -76,6 +76,16 @@ pthread_rwlock_timedrdlock (rwlock, abstime)
break;
}
+ /* Work around the fact that the kernel rejects negative timeout values
+ despite them being valid. */
+ if (__builtin_expect (abstime->tv_sec < 0, 0))
+ {
+ result = ETIMEDOUT;
+ break;
+ }
+
+#if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
+ || !defined lll_futex_timed_wait_bitset)
/* Get the current time. So far we support only one clock. */
struct timeval tv;
(void) gettimeofday (&tv, NULL);
@@ -96,6 +106,7 @@ pthread_rwlock_timedrdlock (rwlock, abstime)
result = ETIMEDOUT;
break;
}
+#endif
/* Remember that we are a reader. */
if (++rwlock->__data.__nr_readers_queued == 0)
@@ -112,8 +123,16 @@ pthread_rwlock_timedrdlock (rwlock, abstime)
lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
/* Wait for the writer to finish. */
+#if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
+ || !defined lll_futex_timed_wait_bitset)
err = lll_futex_timed_wait (&rwlock->__data.__readers_wakeup,
waitval, &rt, rwlock->__data.__shared);
+#else
+ err = lll_futex_timed_wait_bitset (&rwlock->__data.__readers_wakeup,
+ waitval, abstime,
+ FUTEX_CLOCK_REALTIME,
+ rwlock->__data.__shared);
+#endif
/* Get the lock. */
lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);