unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella via Libc-alpha <libc-alpha@sourceware.org>
To: libc-alpha@sourceware.org
Cc: Kurt Kanzenbach <kurt@linutronix.de>
Subject: [PATCH 2/4] nptl: Use FUTEX_LOCK_PI2 when available
Date: Wed, 11 Aug 2021 17:01:31 -0300	[thread overview]
Message-ID: <20210811200133.3869287-3-adhemerval.zanella@linaro.org> (raw)
In-Reply-To: <20210811200133.3869287-1-adhemerval.zanella@linaro.org>

This patch uses the new futex PI operation provided by Linux v5.14
when it is required.

The futex_lock_pi64() is moved to futex-internal.c (since it used on
two different places and its code size might be large depending of the
kernel configuration) and clockid is added as an argument.

Co-authored-by: Kurt Kanzenbach <kurt@linutronix.de>
---
 nptl/futex-internal.c             | 63 +++++++++++++++++++++++++++++++
 nptl/pthread_mutex_lock.c         |  3 +-
 nptl/pthread_mutex_timedlock.c    |  3 +-
 sysdeps/nptl/futex-internal.h     | 54 +-------------------------
 sysdeps/nptl/lowlevellock-futex.h |  1 +
 5 files changed, 70 insertions(+), 54 deletions(-)

diff --git a/nptl/futex-internal.c b/nptl/futex-internal.c
index e74647a9d4..58605b2fca 100644
--- a/nptl/futex-internal.c
+++ b/nptl/futex-internal.c
@@ -140,3 +140,66 @@ __futex_abstimed_wait_cancelable64 (unsigned int* futex_word,
                                        abstime, private, true);
 }
 libc_hidden_def (__futex_abstimed_wait_cancelable64)
+
+int
+__futex_lock_pi64 (int *futex_word, clockid_t clockid,
+		   const struct __timespec64 *abstime, int private)
+{
+  int err;
+
+  unsigned int clockbit = clockid == CLOCK_REALTIME
+			  ? FUTEX_CLOCK_REALTIME : 0;
+  int op_pi2 = __lll_private_flag (FUTEX_LOCK_PI2 | clockbit, private);
+#if __ASSUME_FUTEX_LOCK_PI2
+  /* Assume __ASSUME_TIME64_SYSCALLS since FUTEX_LOCK_PI2 was added later.  */
+  err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word, op_pi2, 0, abstime);
+#else
+  /* FUTEX_LOCK_PI does not support clock selection, so for CLOCK_MONOTONIC
+     the only option is to use FUTEX_LOCK_PI2.  */
+  int op_pi1 = __lll_private_flag (FUTEX_LOCK_PI, private);
+  int op_pi = abstime != NULL && clockid != CLOCK_REALTIME ? op_pi2 : op_pi1;
+
+# ifdef __ASSUME_TIME64_SYSCALLS
+  err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word, op_pi, 0, abstime);
+# else
+  bool need_time64 = abstime != NULL && !in_time_t_range (abstime->tv_sec);
+  if (need_time64)
+    err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word, op_pi, 0, abstime);
+  else
+    {
+      struct timespec ts32, *pts32 = NULL;
+      if (abstime != NULL)
+	{
+	  ts32 = valid_timespec64_to_timespec (*abstime);
+	  pts32 = &ts32;
+	}
+      err = INTERNAL_SYSCALL_CALL (futex, futex_word, op_pi, 0, pts32);
+    }
+# endif	 /* __ASSUME_TIME64_SYSCALLS */
+   /* FUTEX_LOCK_PI2 is not available on this kernel.  */
+   if (err == -ENOSYS)
+     err = -EINVAL;
+#endif /* __ASSUME_FUTEX_LOCK_PI2  */
+
+  switch (err)
+    {
+    case 0:
+    case -EAGAIN:
+    case -EINTR:
+    case -ETIMEDOUT:
+    case -ESRCH:
+    case -EDEADLK:
+    case -EINVAL: /* This indicates either state corruption or that the kernel
+                     found a waiter on futex address which is waiting via
+                     FUTEX_WAIT or FUTEX_WAIT_BITSET.  This is reported on
+                     some futex_lock_pi usage (pthread_mutex_timedlock for
+                     instance).  */
+      return -err;
+
+    case -EFAULT: /* Must have been caused by a glibc or application bug.  */
+    case -ENOSYS: /* Must have been caused by a glibc bug.  */
+    /* No other errors are documented at this time.  */
+    default:
+      futex_fatal_error ();
+    }
+}
diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
index da624f322d..8e2ff2793f 100644
--- a/nptl/pthread_mutex_lock.c
+++ b/nptl/pthread_mutex_lock.c
@@ -422,7 +422,8 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex)
 	    int private = (robust
 			   ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
 			   : PTHREAD_MUTEX_PSHARED (mutex));
-	    int e = futex_lock_pi64 (&mutex->__data.__lock, NULL, private);
+	    int e = __futex_lock_pi64 (&mutex->__data.__lock, 0 /* ununsed  */,
+				       NULL, private);
 	    if (e == ESRCH || e == EDEADLK)
 	      {
 		assert (e != EDEADLK
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index 11ad7005d0..ca51da6f6c 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -370,7 +370,8 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex,
 	    int private = (robust
 			   ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
 			   : PTHREAD_MUTEX_PSHARED (mutex));
-	    int e = futex_lock_pi64 (&mutex->__data.__lock, abstime, private);
+	    int e = __futex_lock_pi64 (&mutex->__data.__lock, clockid, abstime,
+				       private);
 	    if (e == ETIMEDOUT)
 	      return ETIMEDOUT;
 	    else if (e == ESRCH || e == EDEADLK)
diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
index 79a366604d..f0b7f814cc 100644
--- a/sysdeps/nptl/futex-internal.h
+++ b/sysdeps/nptl/futex-internal.h
@@ -250,58 +250,8 @@ futex_wake (unsigned int* futex_word, int processes_to_wake, int private)
        futex.
      - ETIMEDOUT if the ABSTIME expires.
 */
-static __always_inline int
-futex_lock_pi64 (int *futex_word, const struct __timespec64 *abstime,
-                 int private)
-{
-  int err;
-#ifdef __ASSUME_TIME64_SYSCALLS
-  err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word,
-			       __lll_private_flag (FUTEX_LOCK_PI, private), 0,
-			       abstime);
-#else
-  bool need_time64 = abstime != NULL && !in_time_t_range (abstime->tv_sec);
-  if (need_time64)
-    {
-      err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word,
-				   __lll_private_flag (FUTEX_LOCK_PI, private),
-				   0, abstime);
-      if (err == -ENOSYS)
-	err = -EOVERFLOW;
-    }
-  else
-    {
-      struct timespec ts32;
-      if (abstime != NULL)
-        ts32 = valid_timespec64_to_timespec (*abstime);
-
-      err = INTERNAL_SYSCALL_CALL (futex, futex_word, __lll_private_flag
-                                   (FUTEX_LOCK_PI, private), 0,
-                                   abstime != NULL ? &ts32 : NULL);
-    }
-#endif
-  switch (err)
-    {
-    case 0:
-    case -EAGAIN:
-    case -EINTR:
-    case -ETIMEDOUT:
-    case -ESRCH:
-    case -EDEADLK:
-    case -EINVAL: /* This indicates either state corruption or that the kernel
-		     found a waiter on futex address which is waiting via
-		     FUTEX_WAIT or FUTEX_WAIT_BITSET.  This is reported on
-		     some futex_lock_pi usage (pthread_mutex_timedlock for
-		     instance).  */
-      return -err;
-
-    case -EFAULT: /* Must have been caused by a glibc or application bug.  */
-    case -ENOSYS: /* Must have been caused by a glibc bug.  */
-    /* No other errors are documented at this time.  */
-    default:
-      futex_fatal_error ();
-    }
-}
+int __futex_lock_pi64 (int *futex_word, clockid_t clockid,
+		       const struct __timespec64 *abstime, int private);
 
 /* Wakes the top priority waiter that called a futex_lock_pi operation on
    the futex.
diff --git a/sysdeps/nptl/lowlevellock-futex.h b/sysdeps/nptl/lowlevellock-futex.h
index 66ebfe50f4..abda179e0d 100644
--- a/sysdeps/nptl/lowlevellock-futex.h
+++ b/sysdeps/nptl/lowlevellock-futex.h
@@ -38,6 +38,7 @@
 #define FUTEX_WAKE_BITSET	10
 #define FUTEX_WAIT_REQUEUE_PI   11
 #define FUTEX_CMP_REQUEUE_PI    12
+#define FUTEX_LOCK_PI2		13
 #define FUTEX_PRIVATE_FLAG	128
 #define FUTEX_CLOCK_REALTIME	256
 
-- 
2.30.2


  parent reply	other threads:[~2021-08-11 20:03 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-11 20:01 [PATCH 0/4] Add CLOCK_MONOTONIC support for PI mutexes Adhemerval Zanella via Libc-alpha
2021-08-11 20:01 ` [PATCH 1/4] Linux: Add FUTEX_LOCK_PI2 Adhemerval Zanella via Libc-alpha
2021-08-11 20:01 ` Adhemerval Zanella via Libc-alpha [this message]
2021-08-12  6:42   ` [PATCH 2/4] nptl: Use FUTEX_LOCK_PI2 when available Kurt Kanzenbach via Libc-alpha
2021-08-12 12:40     ` Adhemerval Zanella via Libc-alpha
2021-08-13  6:26       ` Kurt Kanzenbach via Libc-alpha
2021-08-11 20:01 ` [PATCH 3/4] support: Add xpthread_mutex_pi_support_monotonic Adhemerval Zanella via Libc-alpha
2021-08-16  8:01   ` Florian Weimer via Libc-alpha
2021-08-19 12:49     ` Adhemerval Zanella via Libc-alpha
2021-08-11 20:01 ` [PATCH 4/4] nptl: Add CLOCK_MONOTONIC support for PI mutexes Adhemerval Zanella via Libc-alpha

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/libc/involved.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210811200133.3869287-3-adhemerval.zanella@linaro.org \
    --to=libc-alpha@sourceware.org \
    --cc=adhemerval.zanella@linaro.org \
    --cc=kurt@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).