From: Kurt Kanzenbach <kurt@linutronix.de>
To: libc-alpha@sourceware.org
Cc: Adhemerval Zanella <adhemerval.zanella@linaro.org>,
Florian Weimer <fweimer@redhat.com>,
Carlos O'Donell <carlos@redhat.com>,
Thomas Gleixner <tglx@linutronix.de>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Kurt Kanzenbach <kurt@linutronix.de>
Subject: [PATCH RFC 1/3] nptl: Introduce futex_lock_pi2()
Date: Mon, 21 Jun 2021 13:16:48 +0200 [thread overview]
Message-ID: <20210621111650.1164689-2-kurt@linutronix.de> (raw)
In-Reply-To: <20210621111650.1164689-1-kurt@linutronix.de>
This variant of futex_lock() has support for selectable clocks and priority
inheritance. The underlying FUTEX_LOCK_PI2 operation has been recently
introduced into the Linux kernel.
It can be used for implementing pthread_mutex_clocklock(MONOTONIC)/PI.
Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
---
sysdeps/nptl/futex-internal.h | 77 +++++++++++++++++++++++++++++++
sysdeps/nptl/lowlevellock-futex.h | 1 +
2 files changed, 78 insertions(+)
diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
index 969ab2bf4bf8..60bdae84405c 100644
--- a/sysdeps/nptl/futex-internal.h
+++ b/sysdeps/nptl/futex-internal.h
@@ -295,6 +295,83 @@ futex_lock_pi64 (int *futex_word, const struct __timespec64 *abstime,
}
}
+/* The operation checks the value of the futex, if the value is 0, then
+ it is atomically set to the caller's thread ID. If the futex value is
+ nonzero, it is atomically sets the FUTEX_WAITERS bit, which signals wrt
+ other futex owner that it cannot unlock the futex in user space by
+ atomically by setting its value to 0.
+
+ If more than one wait operations is issued, the enqueueing of the waiters
+ are done in descending priority order.
+
+ The ABSTIME arguments provides an absolute timeout (measured against the
+ CLOCK_REALTIME or CLOCK_MONOTONIC clock). If TIMEOUT is NULL, the operation
+ will block indefinitely.
+
+ Returns:
+
+ - 0 if woken by a PI unlock operation or spuriously.
+ - EAGAIN if the futex owner thread ID is about to exit, but has not yet
+ handled the state cleanup.
+ - EDEADLK if the futex is already locked by the caller.
+ - ESRCH if the thread ID int he futex does not exist.
+ - EINVAL is the state is corrupted or if there is a waiter on the
+ futex or if the clockid is invalid.
+ - ETIMEDOUT if the ABSTIME expires.
+ - ENOSYS if FUTEX_LOCK_PI2 is not available.
+*/
+static __always_inline int
+futex_lock_pi2_64 (int *futex_word, clockid_t clockid,
+ const struct __timespec64 *abstime,
+ int private)
+{
+ unsigned int clockbit;
+
+ if (! lll_futex_supported_clockid (clockid))
+ return EINVAL;
+
+ clockbit = (clockid == CLOCK_REALTIME) ? FUTEX_CLOCK_REALTIME : 0;
+ int op = __lll_private_flag (FUTEX_LOCK_PI2 | clockbit, private);
+
+ int err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word, op,
+ 0, abstime);
+#ifndef __ASSUME_TIME64_SYSCALLS
+ if (err == -ENOSYS)
+ {
+ if (abstime != NULL && ! in_time_t_range (abstime->tv_sec))
+ return EOVERFLOW;
+
+ struct timespec ts32;
+ if (abstime != NULL)
+ ts32 = valid_timespec64_to_timespec (*abstime);
+
+ err = INTERNAL_SYSCALL_CALL (futex, futex_word, op, 0,
+ abstime != NULL ? &ts32 : NULL);
+ }
+#endif
+ switch (err)
+ {
+ case 0:
+ case -EAGAIN:
+ case -EINTR:
+ case -ETIMEDOUT:
+ case -ESRCH:
+ case -EDEADLK:
+ case -ENOSYS: /* Futex lock pi 2 is not available on this kernel. */
+ 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. */
+ /* No other errors are documented at this time. */
+ default:
+ futex_fatal_error ();
+ }
+}
+
/* 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 66ebfe50f4c1..abda179e0de2 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
next prev parent reply other threads:[~2021-06-21 11:17 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-21 11:16 [PATCH RFC 0/3] nptl: Introduce and use FUTEX_LOCK_PI2 Kurt Kanzenbach
2021-06-21 11:16 ` Kurt Kanzenbach [this message]
2021-06-21 11:16 ` [PATCH RFC 2/3] nptl: Use futex_lock_pi2() Kurt Kanzenbach
2021-06-21 11:16 ` [PATCH RFC 3/3] nptl: Include CLOCK_MONOTONIC in mutex tests Kurt Kanzenbach
2021-06-21 20:07 ` Joseph Myers
2021-06-22 8:58 ` Kurt Kanzenbach
2021-06-21 21:32 ` [PATCH RFC 0/3] nptl: Introduce and use FUTEX_LOCK_PI2 Adhemerval Zanella
2021-06-22 7:26 ` Kurt Kanzenbach
2021-06-22 7:29 ` Florian Weimer
2021-06-22 8:55 ` Kurt Kanzenbach
2021-06-22 12:30 ` Adhemerval Zanella
2021-06-22 14:25 ` Kurt Kanzenbach
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210621111650.1164689-2-kurt@linutronix.de \
--to=kurt@linutronix.de \
--cc=adhemerval.zanella@linaro.org \
--cc=bigeasy@linutronix.de \
--cc=carlos@redhat.com \
--cc=fweimer@redhat.com \
--cc=libc-alpha@sourceware.org \
--cc=tglx@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).