From patchwork Wed Oct 30 20:00:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 178129 Delivered-To: patch@linaro.org Received: by 2002:a92:409a:0:0:0:0:0 with SMTP id d26csp1755860ill; Wed, 30 Oct 2019 13:02:47 -0700 (PDT) X-Google-Smtp-Source: APXvYqweMMJcHjvDXOL8q2HogBD8bAneLJAD2LB/CxLdn6i5Mj9rrboh6trm/tNwC4KugR3UOzCA X-Received: by 2002:a50:ec8d:: with SMTP id e13mr1794935edr.54.1572465767461; Wed, 30 Oct 2019 13:02:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1572465767; cv=none; d=google.com; s=arc-20160816; b=i05ZdIIQ7WgxrtpGdergCTTS9w6iiwL8mSvDXsAiiDEwilsD/N1RdwiigmalQL9hHp ovZadeGdNGceWrQIb15V8Jqf+VZPslZW5Nr985IzJuHzajTqRlmC2QC5JhCiPHwV4Q9w CI6Dv1/ykIpNZW5jbXfn6aeQVg9XpGE0NeVJ7Tcoke5yvsGNPpl8sOls78hGzxqKYux5 YTbz7O/jJoWXRq44H/2NjaRrGvTyAfvYbrKgCpZSISgNC65Vnd1IJ3JiopcmkbcOtEkW XRu/rP4VS2eNAwX+fR7gSx5ekY4nc84Jcq/x5qWEVRqM2ioMpWwOGnZJ06gFXE0tBpT5 nMxw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:cc:to:from:dkim-signature:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature; bh=Rq3iPkjFISWoQT5s9szu4YZSOdDMY8VQEVKcTd8omG0=; b=hjSUsCbTT7a9Q6cdu7py13Prywed6XHJ82bnNx3PYtxmI6W1yy60He+gkhx80qx9VA 6z3scXVomK39XvauvUkYlhYm12ekjFcJ0DRTXtiJ1ITD4A86XwQqJK0vHzSrhfz04AXX duq4kdm+jp/u2EXnC7+G7cGOa0LLO7kLvOzIG8mn7XZP8V2NyZvZ55LCjikeOii9W9Xm 540dcwJkrHHfQoGiJiuKGB8T1DRkCflBK9XoqiJKAkeg2Do+9nmxJg2ezy7Dvp0ItgQU FqXGGXKDo+Ll2tXz/KgBYxlUbW0D1i3FRb1dcW500GWvjXnUueUPEq8vd2U3BdE2Wa9T bWYQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=Kg34nS6Z; dkim=pass header.i=@linaro.org header.s=google header.b=kbmT8L0i; spf=pass (google.com: domain of libc-alpha-return-106481-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-106481-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id q26si2051045ejz.43.2019.10.30.13.02.45 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Oct 2019 13:02:47 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-106481-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=Kg34nS6Z; dkim=pass header.i=@linaro.org header.s=google header.b=kbmT8L0i; spf=pass (google.com: domain of libc-alpha-return-106481-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-106481-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id; q=dns; s= default; b=ex027B3p1uD8VHBx6+AdsHTTfLOD4e9b1pyv0y0MfgDqRouMDZhiV am3HOuX5MHOT9UrD0tS6nETiI3SqAZSo6jtG6NN7d/bgY1FDZ4zVbsk4HZRyORCb J2XAs/wuQAbI7Bt+nF1c3K7slC5v5LFTRqk2A/Wb51iMxYdUwIJ4bY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id; s=default; bh=6a4EbN1vms1exhiSl+HOuWONfOM=; b=Kg34nS6ZHh95sIn3oFdkRawMOOyC OzNbiLMjE0ZN/hHqkWkpxiPnu/5945+R0J8Du45+64g694q0wsLGCnF3omfWJX76 5AaULeItPhFokyuqxpTTHd4nO3tUZWk7UZl0FByGftfswB8HjwlftDwto4emSnIt wFXIB+BGJV11gsE= Received: (qmail 83509 invoked by alias); 30 Oct 2019 20:01:37 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 78821 invoked by uid 89); 30 Oct 2019 20:01:18 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mail-qk1-f194.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=Rq3iPkjFISWoQT5s9szu4YZSOdDMY8VQEVKcTd8omG0=; b=kbmT8L0i+XlwVDci+BsUgHxbNej++Kb25/wOff1Y4A2s7TWZzObOyf/k43P33wl/y8 RiC6Ml8ze9CCv94sVnHRfdAt231bSSxpKOm07nWL3VwD4o7zYKJZsFMk2b08HV7diMs5 MlkilLpvm9WPbPaHTI+kjLcE6SLtqcNrFaQtRvKjCu9LrNCOI5HNzFlg5gN4nSG7IeOu UqVnDVc5BLKYsMABQWbiHMU3NWWTVH0IuxzhiFuglUMTtHGV/YH2EoR12HicDyrVRV2v CisjbDDAwnKRFd4dkbhvg6Qv8UjNS1EdtiWaOcgVtCcOy+JOIteR2krZ+hab2isafkAT gwFw== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Alistair Francis Subject: [PATCH 1/5] Consolidate futex-internal.h Date: Wed, 30 Oct 2019 17:00:48 -0300 Message-Id: <20191030200052.497-1-adhemerval.zanella@linaro.org> NPTL is already Linux specific, there is no need to parametrize futex operations and add a sysdep Linux specific implementation. This patch moves the relevant Linux code to nptl one. Checked on x86_64-linux-gnu and i686-linux-gnu. --- sysdeps/nptl/futex-internal.h | 211 +++++++++++++++++-- sysdeps/unix/sysv/linux/futex-internal.h | 255 ----------------------- 2 files changed, 196 insertions(+), 270 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/futex-internal.h -- 2.17.1 Reviewed-by: Carlos O'Donell diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h index 4e6e8fa324..76921466f0 100644 --- a/sysdeps/nptl/futex-internal.h +++ b/sysdeps/nptl/futex-internal.h @@ -74,11 +74,35 @@ # error FUTEX_PRIVATE must be equal to 0 #endif +/* Calls __libc_fatal with an error message. Convenience function for + concrete implementations of the futex interface. */ +static __always_inline __attribute__ ((__noreturn__)) void +futex_fatal_error (void) +{ + __libc_fatal ("The futex facility returned an unexpected error code.\n"); +} + + +/* The Linux kernel treats provides absolute timeouts based on the + CLOCK_REALTIME clock and relative timeouts measured against the + CLOCK_MONOTONIC clock. + + We expect a Linux kernel version of 2.6.22 or more recent (since this + version, EINTR is not returned on spurious wake-ups anymore). */ + /* Returns EINVAL if PSHARED is neither PTHREAD_PROCESS_PRIVATE nor PTHREAD_PROCESS_SHARED; otherwise, returns 0 if PSHARED is supported, and ENOTSUP if not. */ static __always_inline int -futex_supports_pshared (int pshared); +futex_supports_pshared (int pshared) +{ + if (__glibc_likely (pshared == PTHREAD_PROCESS_PRIVATE)) + return 0; + else if (pshared == PTHREAD_PROCESS_SHARED) + return 0; + else + return EINVAL; +} /* Atomically wrt other futex operations on the same futex, this blocks iff the value *FUTEX_WORD matches the expected value. This is @@ -112,7 +136,27 @@ futex_supports_pshared (int pshared); a futex_wait call when synchronizing similar to Dekker synchronization. However, we make no such guarantee here. */ static __always_inline int -futex_wait (unsigned int *futex_word, unsigned int expected, int private); +futex_wait (unsigned int *futex_word, unsigned int expected, int private) +{ + int err = lll_futex_timed_wait (futex_word, expected, NULL, private); + switch (err) + { + case 0: + case -EAGAIN: + case -EINTR: + return -err; + + case -ETIMEDOUT: /* Cannot have happened as we provided no timeout. */ + case -EFAULT: /* Must have been caused by a glibc or application bug. */ + case -EINVAL: /* Either due to wrong alignment or due to the timeout not + being normalized. 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 (); + } +} /* Like futex_wait but does not provide any indication why we stopped waiting. Thus, when this function returns, you have to always check FUTEX_WORD to @@ -132,7 +176,30 @@ futex_wait_simple (unsigned int *futex_word, unsigned int expected, /* Like futex_wait but is a POSIX cancellation point. */ static __always_inline int futex_wait_cancelable (unsigned int *futex_word, unsigned int expected, - int private); + int private) +{ + int oldtype; + oldtype = __pthread_enable_asynccancel (); + int err = lll_futex_timed_wait (futex_word, expected, NULL, private); + __pthread_disable_asynccancel (oldtype); + switch (err) + { + case 0: + case -EAGAIN: + case -EINTR: + return -err; + + case -ETIMEDOUT: /* Cannot have happened as we provided no timeout. */ + case -EFAULT: /* Must have been caused by a glibc or application bug. */ + case -EINVAL: /* Either due to wrong alignment or due to the timeout not + being normalized. 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 (); + } +} /* Like futex_wait, but will eventually time out (i.e., stop being blocked) after the duration of time provided (i.e., RELTIME) has @@ -144,32 +211,134 @@ futex_wait_cancelable (unsigned int *futex_word, unsigned int expected, */ static __always_inline int futex_reltimed_wait (unsigned int* futex_word, unsigned int expected, - const struct timespec* reltime, int private); + const struct timespec* reltime, int private) +{ + int err = lll_futex_timed_wait (futex_word, expected, reltime, private); + switch (err) + { + case 0: + case -EAGAIN: + case -EINTR: + case -ETIMEDOUT: + return -err; + + case -EFAULT: /* Must have been caused by a glibc or application bug. */ + case -EINVAL: /* Either due to wrong alignment or due to the timeout not + being normalized. 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 (); + } +} /* Like futex_reltimed_wait but is a POSIX cancellation point. */ static __always_inline int futex_reltimed_wait_cancelable (unsigned int* futex_word, unsigned int expected, - const struct timespec* reltime, int private); + const struct timespec* reltime, int private) +{ + int oldtype; + oldtype = LIBC_CANCEL_ASYNC (); + int err = lll_futex_timed_wait (futex_word, expected, reltime, private); + LIBC_CANCEL_RESET (oldtype); + switch (err) + { + case 0: + case -EAGAIN: + case -EINTR: + case -ETIMEDOUT: + return -err; + + case -EFAULT: /* Must have been caused by a glibc or application bug. */ + case -EINVAL: /* Either due to wrong alignment or due to the timeout not + being normalized. 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 (); + } +} /* Check whether the specified clockid is supported by futex_abstimed_wait and futex_abstimed_wait_cancelable. */ static __always_inline int -futex_abstimed_supported_clockid (clockid_t clockid); +futex_abstimed_supported_clockid (clockid_t clockid) +{ + return lll_futex_supported_clockid (clockid); +} /* Like futex_reltimed_wait, but the provided timeout (ABSTIME) is an absolute point in time; a call will time out after this point in time. */ static __always_inline int futex_abstimed_wait (unsigned int* futex_word, unsigned int expected, clockid_t clockid, - const struct timespec* abstime, int private); + const struct timespec* abstime, int private) +{ + /* Work around the fact that the kernel rejects negative timeout values + despite them being valid. */ + if (__glibc_unlikely ((abstime != NULL) && (abstime->tv_sec < 0))) + return ETIMEDOUT; + int err = lll_futex_clock_wait_bitset (futex_word, expected, + clockid, abstime, + private); + switch (err) + { + case 0: + case -EAGAIN: + case -EINTR: + case -ETIMEDOUT: + return -err; + + case -EFAULT: /* Must have been caused by a glibc or application bug. */ + case -EINVAL: /* Either due to wrong alignment, unsupported + clockid or due to the timeout not being + normalized. 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 (); + } +} /* Like futex_reltimed_wait but is a POSIX cancellation point. */ static __always_inline int futex_abstimed_wait_cancelable (unsigned int* futex_word, unsigned int expected, clockid_t clockid, - const struct timespec* abstime, int private); + const struct timespec* abstime, int private) +{ + /* Work around the fact that the kernel rejects negative timeout values + despite them being valid. */ + if (__glibc_unlikely ((abstime != NULL) && (abstime->tv_sec < 0))) + return ETIMEDOUT; + int oldtype; + oldtype = __pthread_enable_asynccancel (); + int err = lll_futex_clock_wait_bitset (futex_word, expected, + clockid, abstime, + private); + __pthread_disable_asynccancel (oldtype); + switch (err) + { + case 0: + case -EAGAIN: + case -EINTR: + case -ETIMEDOUT: + return -err; + + case -EFAULT: /* Must have been caused by a glibc or application bug. */ + case -EINVAL: /* Either due to wrong alignment or due to the timeout not + being normalized. 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 (); + } +} /* Atomically wrt other futex operations on the same futex, this unblocks the specified number of processes, or all processes blocked on this futex if @@ -190,14 +359,26 @@ futex_abstimed_wait_cancelable (unsigned int* futex_word, object destruction (see above); therefore, we must not report or abort on most errors. */ static __always_inline void -futex_wake (unsigned int* futex_word, int processes_to_wake, int private); - -/* Calls __libc_fatal with an error message. Convenience function for - concrete implementations of the futex interface. */ -static __always_inline __attribute__ ((__noreturn__)) void -futex_fatal_error (void) +futex_wake (unsigned int* futex_word, int processes_to_wake, int private) { - __libc_fatal ("The futex facility returned an unexpected error code.\n"); + int res = lll_futex_wake (futex_word, processes_to_wake, private); + /* No error. Ignore the number of woken processes. */ + if (res >= 0) + return; + switch (res) + { + case -EFAULT: /* Could have happened due to memory reuse. */ + case -EINVAL: /* Could be either due to incorrect alignment (a bug in + glibc or in the application) or due to memory being + reused for a PI futex. We cannot distinguish between the + two causes, and one of them is correct use, so we do not + act in this case. */ + return; + case -ENOSYS: /* Must have been caused by a glibc bug. */ + /* No other errors are documented at this time. */ + default: + futex_fatal_error (); + } } #endif /* futex-internal.h */ diff --git a/sysdeps/unix/sysv/linux/futex-internal.h b/sysdeps/unix/sysv/linux/futex-internal.h deleted file mode 100644 index 5a4f4ff818..0000000000 --- a/sysdeps/unix/sysv/linux/futex-internal.h +++ /dev/null @@ -1,255 +0,0 @@ -/* futex operations for glibc-internal use. Linux version. - Copyright (C) 2014-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef FUTEX_INTERNAL_H -#define FUTEX_INTERNAL_H - -#include -#include -#include -#include - -/* See sysdeps/nptl/futex-internal.h for documentation; this file only - contains Linux-specific comments. - - The Linux kernel treats provides absolute timeouts based on the - CLOCK_REALTIME clock and relative timeouts measured against the - CLOCK_MONOTONIC clock. - - We expect a Linux kernel version of 2.6.22 or more recent (since this - version, EINTR is not returned on spurious wake-ups anymore). */ - -/* FUTEX_SHARED is always supported by the Linux kernel. */ -static __always_inline int -futex_supports_pshared (int pshared) -{ - if (__glibc_likely (pshared == PTHREAD_PROCESS_PRIVATE)) - return 0; - else if (pshared == PTHREAD_PROCESS_SHARED) - return 0; - else - return EINVAL; -} - -/* See sysdeps/nptl/futex-internal.h for details. */ -static __always_inline int -futex_wait (unsigned int *futex_word, unsigned int expected, int private) -{ - int err = lll_futex_timed_wait (futex_word, expected, NULL, private); - switch (err) - { - case 0: - case -EAGAIN: - case -EINTR: - return -err; - - case -ETIMEDOUT: /* Cannot have happened as we provided no timeout. */ - case -EFAULT: /* Must have been caused by a glibc or application bug. */ - case -EINVAL: /* Either due to wrong alignment or due to the timeout not - being normalized. 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 (); - } -} - -/* See sysdeps/nptl/futex-internal.h for details. */ -static __always_inline int -futex_wait_cancelable (unsigned int *futex_word, unsigned int expected, - int private) -{ - int oldtype; - oldtype = __pthread_enable_asynccancel (); - int err = lll_futex_timed_wait (futex_word, expected, NULL, private); - __pthread_disable_asynccancel (oldtype); - switch (err) - { - case 0: - case -EAGAIN: - case -EINTR: - return -err; - - case -ETIMEDOUT: /* Cannot have happened as we provided no timeout. */ - case -EFAULT: /* Must have been caused by a glibc or application bug. */ - case -EINVAL: /* Either due to wrong alignment or due to the timeout not - being normalized. 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 (); - } -} - -/* See sysdeps/nptl/futex-internal.h for details. */ -static __always_inline int -futex_reltimed_wait (unsigned int *futex_word, unsigned int expected, - const struct timespec *reltime, int private) -{ - int err = lll_futex_timed_wait (futex_word, expected, reltime, private); - switch (err) - { - case 0: - case -EAGAIN: - case -EINTR: - case -ETIMEDOUT: - return -err; - - case -EFAULT: /* Must have been caused by a glibc or application bug. */ - case -EINVAL: /* Either due to wrong alignment or due to the timeout not - being normalized. 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 (); - } -} - -/* See sysdeps/nptl/futex-internal.h for details. */ -static __always_inline int -futex_reltimed_wait_cancelable (unsigned int *futex_word, - unsigned int expected, - const struct timespec *reltime, int private) -{ - int oldtype; - oldtype = LIBC_CANCEL_ASYNC (); - int err = lll_futex_timed_wait (futex_word, expected, reltime, private); - LIBC_CANCEL_RESET (oldtype); - switch (err) - { - case 0: - case -EAGAIN: - case -EINTR: - case -ETIMEDOUT: - return -err; - - case -EFAULT: /* Must have been caused by a glibc or application bug. */ - case -EINVAL: /* Either due to wrong alignment or due to the timeout not - being normalized. 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 (); - } -} - -/* See sysdeps/nptl/futex-internal.h for details. */ -static __always_inline int -futex_abstimed_supported_clockid (clockid_t clockid) -{ - return lll_futex_supported_clockid (clockid); -} - -/* See sysdeps/nptl/futex-internal.h for details. */ -static __always_inline int -futex_abstimed_wait (unsigned int *futex_word, unsigned int expected, - clockid_t clockid, - const struct timespec *abstime, int private) -{ - /* Work around the fact that the kernel rejects negative timeout values - despite them being valid. */ - if (__glibc_unlikely ((abstime != NULL) && (abstime->tv_sec < 0))) - return ETIMEDOUT; - int err = lll_futex_clock_wait_bitset (futex_word, expected, - clockid, abstime, - private); - switch (err) - { - case 0: - case -EAGAIN: - case -EINTR: - case -ETIMEDOUT: - return -err; - - case -EFAULT: /* Must have been caused by a glibc or application bug. */ - case -EINVAL: /* Either due to wrong alignment, unsupported - clockid or due to the timeout not being - normalized. 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 (); - } -} - -/* See sysdeps/nptl/futex-internal.h for details. */ -static __always_inline int -futex_abstimed_wait_cancelable (unsigned int *futex_word, - unsigned int expected, - clockid_t clockid, - const struct timespec *abstime, int private) -{ - /* Work around the fact that the kernel rejects negative timeout values - despite them being valid. */ - if (__glibc_unlikely ((abstime != NULL) && (abstime->tv_sec < 0))) - return ETIMEDOUT; - int oldtype; - oldtype = __pthread_enable_asynccancel (); - int err = lll_futex_clock_wait_bitset (futex_word, expected, - clockid, abstime, - private); - __pthread_disable_asynccancel (oldtype); - switch (err) - { - case 0: - case -EAGAIN: - case -EINTR: - case -ETIMEDOUT: - return -err; - - case -EFAULT: /* Must have been caused by a glibc or application bug. */ - case -EINVAL: /* Either due to wrong alignment or due to the timeout not - being normalized. 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 (); - } -} - -/* See sysdeps/nptl/futex-internal.h for details. */ -static __always_inline void -futex_wake (unsigned int *futex_word, int processes_to_wake, int private) -{ - int res = lll_futex_wake (futex_word, processes_to_wake, private); - /* No error. Ignore the number of woken processes. */ - if (res >= 0) - return; - switch (res) - { - case -EFAULT: /* Could have happened due to memory reuse. */ - case -EINVAL: /* Could be either due to incorrect alignment (a bug in - glibc or in the application) or due to memory being - reused for a PI futex. We cannot distinguish between the - two causes, and one of them is correct use, so we do not - act in this case. */ - return; - case -ENOSYS: /* Must have been caused by a glibc bug. */ - /* No other errors are documented at this time. */ - default: - futex_fatal_error (); - } -} - -#endif /* futex-internal.h */