about summary refs log tree commit diff
path: root/nptl/pthread_rwlock_timedwrlock.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_timedwrlock.c
parent155ee340b875834693fbd1b7401af7fe88ace04d (diff)
downloadglibc-8f861542dd0603bef99e126e509ece89514c1eeb.tar.gz
glibc-8f861542dd0603bef99e126e509ece89514c1eeb.tar.xz
glibc-8f861542dd0603bef99e126e509ece89514c1eeb.zip
[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_timedwrlock.c')
-rw-r--r--nptl/pthread_rwlock_timedwrlock.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/nptl/pthread_rwlock_timedwrlock.c b/nptl/pthread_rwlock_timedwrlock.c
index 8eb31cfdc2..5f2399f91e 100644
--- a/nptl/pthread_rwlock_timedwrlock.c
+++ b/nptl/pthread_rwlock_timedwrlock.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.
 
@@ -67,6 +67,16 @@ pthread_rwlock_timedwrlock (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);
@@ -86,6 +96,7 @@ pthread_rwlock_timedwrlock (rwlock, abstime)
 	  result = ETIMEDOUT;
 	  break;
 	}
+#endif
 
       /* Remember that we are a writer.  */
       if (++rwlock->__data.__nr_writers_queued == 0)
@@ -102,8 +113,16 @@ pthread_rwlock_timedwrlock (rwlock, abstime)
       lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
 
       /* Wait for the writer or reader(s) to finish.  */
+#if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
+     || !defined lll_futex_timed_wait_bitset)
       err = lll_futex_timed_wait (&rwlock->__data.__writer_wakeup,
 				  waitval, &rt, rwlock->__data.__shared);
+#else
+      err = lll_futex_timed_wait_bitset (&rwlock->__data.__writer_wakeup,
+					 waitval, abstime,
+					 FUTEX_CLOCK_REALTIME,
+					 rwlock->__data.__shared);
+#endif
 
       /* Get the lock.  */
       lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);