From patchwork Mon Jun 21 11:16:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kurt Kanzenbach X-Patchwork-Id: 43930 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 64BC53898528 for ; Mon, 21 Jun 2021 11:21:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 64BC53898528 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1624274508; bh=fJCVXMASq2girTD1YGIxd060Hnj1iMvzPvXz6S3CUAE=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=maZIVv4ZSlL2GZ64M0Jk6KxPS4EdoQmCNffzotfEqP1HI8uPFAhi8yMyLgG+ysQfl fcfXgKmgAnNIzrV+TDiy1T7Ng+hA1rGcZ6E56NXK94vrwrgMPCkyIxYxAa8kxD989u DQ4509uL9b5Pgn73Gf2o9EDhkJ3D5T0/mn3BfAmQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by sourceware.org (Postfix) with ESMTPS id 5286C393A41B for ; Mon, 21 Jun 2021 11:17:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5286C393A41B To: libc-alpha@sourceware.org Subject: [PATCH RFC 1/3] nptl: Introduce futex_lock_pi2() Date: Mon, 21 Jun 2021 13:16:48 +0200 Message-Id: <20210621111650.1164689-2-kurt@linutronix.de> In-Reply-To: <20210621111650.1164689-1-kurt@linutronix.de> References: <20210621111650.1164689-1-kurt@linutronix.de> MIME-Version: 1.0 X-Spam-Status: No, score=-10.7 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-Patchwork-Original-From: Kurt Kanzenbach via Libc-alpha From: Kurt Kanzenbach Reply-To: Kurt Kanzenbach Cc: Florian Weimer , Sebastian Andrzej Siewior , Kurt Kanzenbach , Thomas Gleixner Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" 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 --- 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