From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by sourceware.org (Postfix) with ESMTPS id 75953393A426 for ; Mon, 21 Jun 2021 11:17:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 75953393A426 From: Kurt Kanzenbach To: libc-alpha@sourceware.org Cc: Adhemerval Zanella , Florian Weimer , Carlos O'Donell , Thomas Gleixner , Sebastian Andrzej Siewior , Kurt Kanzenbach Subject: [PATCH RFC 2/3] nptl: Use futex_lock_pi2() Date: Mon, 21 Jun 2021 13:16:49 +0200 Message-Id: <20210621111650.1164689-3-kurt@linutronix.de> In-Reply-To: <20210621111650.1164689-1-kurt@linutronix.de> References: <20210621111650.1164689-1-kurt@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Jun 2021 11:17:21 -0000 Use futex_lock_pi2() by default, because it supports selectable clocks. On older kernels futex_lock_pi2() will return ENOSYS. Fallback to futex_lock_pi() and don't support CLOCK_MONOTONIC then. Signed-off-by: Kurt Kanzenbach --- nptl/pthread_mutex_timedlock.c | 24 ++++++++++++++++++------ sysdeps/nptl/futex-internal.h | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c index 5afd6222d61e..e7e001d2c17a 100644 --- a/nptl/pthread_mutex_timedlock.c +++ b/nptl/pthread_mutex_timedlock.c @@ -300,11 +300,15 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: { - /* Currently futex FUTEX_LOCK_PI operation only provides support for - CLOCK_REALTIME and trying to emulate by converting a - CLOCK_MONOTONIC to CLOCK_REALTIME will take in account possible - changes to the wall clock. */ - if (__glibc_unlikely (clockid != CLOCK_REALTIME)) + /* Currently futex FUTEX_LOCK_PI operation only provides support for + CLOCK_REALTIME and trying to emulate by converting a + CLOCK_MONOTONIC to CLOCK_REALTIME will take in account possible + changes to the wall clock. + + However, newer Linux kernels support FUTEX_LOCK_PI2 with selectable + clock support. */ + if (__glibc_unlikely (! futex_lockpi2_supported () && + clockid != CLOCK_REALTIME)) return EINVAL; int kind, robust; @@ -370,7 +374,15 @@ __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_pi2_64 (&mutex->__data.__lock, clockid, abstime, + private); + + /* Use futex futex_lock_pi2() by default. This doesn't work for + older kernels. So fallback to futex_lock_pi() then. The clockid + is checked above already. */ + if (__glibc_unlikely (e == ENOSYS)) + e = futex_lock_pi64 (&mutex->__data.__lock, 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 60bdae84405c..b5f101b484c2 100644 --- a/sysdeps/nptl/futex-internal.h +++ b/sysdeps/nptl/futex-internal.h @@ -372,6 +372,23 @@ futex_lock_pi2_64 (int *futex_word, clockid_t clockid, } } +/* Checks whether FUTEX_LOCK_PI2 operation is available on the running Linux + kernel. FUTEX_LOCK_PI2 has been introduced on newer kernel versions. + + Returns true if FUTEX_LOCK_PI2 is available, false otherwise. */ +static __always_inline bool +futex_lockpi2_supported (void) +{ + int err = INTERNAL_SYSCALL_CALL (futex_time64, NULL, FUTEX_LOCK_PI2, 0, NULL); + +#ifndef __ASSUME_TIME64_SYSCALLS + if (err == -ENOSYS) + err = INTERNAL_SYSCALL_CALL (futex, NULL, FUTEX_LOCK_PI2, 0, NULL); +#endif + + return err != -ENOSYS; +} + /* Wakes the top priority waiter that called a futex_lock_pi operation on the futex. -- 2.30.2