From patchwork Fri Nov 1 09:57:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 35563 Received: (qmail 122998 invoked by alias); 1 Nov 2019 10:02:17 -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 122990 invoked by uid 89); 1 Nov 2019 10:02:17 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT autolearn=ham version=3.3.1 spammy=1718 X-HELO: esa4.hgst.iphmx.com DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1572602535; x=1604138535; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=Z31PPYpa7n+EBPqDkD5lj6+jLO+JPhh4vQqC3rtRjYc=; b=AjejGmch1EHFKuhyfTYvT5iU91Gy/398a4uCtXj1o6xfO8x4aHUYAyie kJfS2s+NHTN54+cFqZEBdNXQITqThLVRD8rwrkRl52nhu30LQPA9cx0Jt UXbMyeTszUhsi8JhSQlhJOc2Tbzdh4K3uusZIA/e+OUEWdbuTRAnCmOzP cXzfGZEsT+uy8tMbGIRmojwJLb9n9g07cb/Gukt/cQ2Y4CW9KBcmfyTSF 9m5HHrZ7CcIOCMUxGvp7JcnPIxtFUeO46QgwElEMuwpQGgvA49Lq4lkSZ jA3WScn8liThMfzL9qFxK18IjVBUWBCAxWbYGWAhHFejULa7lIOdSoDd4 A==; IronPort-SDR: rNMegaCY7hHMwRSysGSxMv8KIwvSu6hmX0P77vG7e+Q3V+1PnM3DIiQy5u4QDuSImk8SRrV/bC 3+4eMGhd/Fhnak+gqoeqV4nwBLnASOye1S9JbyM5EwnyA29AhK3WZuBRlNIgr3eVWLktRcl9MM smR/XvwmH9UL7+4F/yCDXTk3pRgX+PzK1QTFPL5/Q2h+3aapSFMy9FeXqvDpWX81PBUtHS62ah v0F+Wo3yX1Sv7kHuxQHGLGRW4Q6vuYyazft52aNMSBv5dGF6RgK/hONHjKePSo/+qkQQ/PBFC/ 7Og= IronPort-SDR: +PmuLqrepq/ucv0I6xaLtkD3MiLSG5JFbJyM+Rqjjh7l6Bq2B6nuBMwW03laNjmIZRKAcff8J+ Fz77JrcbewdtibN5GLD8UC/ucUdPdM7Fw9092XQwoX7RPPR5ecBvfZFj+GUoQlyl/CpzJyysKS eLcFp//iJ8pxucjgiLGcj30vaAVWnXvf3EWtaJPJG+JQZg6SREXETbx6C9ak6b6bUJIYrB2SxJ 1WApCDX/jKaxC5EBuH7VbjIIdNfFUlQVSByfwY75h+OL0H3rzbUb/CMDa77FQlQyR6nrl3sV6W MNFl7BL3KTnqqFL/JxX/16er IronPort-SDR: OfJFu9r7JGaRyg7U0MoGiVe3eD12Q4GL+agCUxLT9G64fDtgB6xTgkITA9TKjyCzbRq21UHJyu mSnONb6ArGKUN+JDf2cC89vUdihRYx/r2tq6BjRjWGlA1bOupaMC8PlAzVnQJaUMk5ya6AQt9V PB4sl3j/0O3Cxa0WTVrVPMypZEZqD1/4HiIzb+I3c7+LkT1TNDGkhXuBuWdb5mjkX3DlqGqdAG vIjkzDuk1ukrEmIjhWHbVwwVd+VpOoENCnjW3FTsYra5pKHa/37SveWUrD9JFubGnf3BH0Y3Ob xoo= WDCIronportException: Internal From: Alistair Francis To: libc-alpha@sourceware.org Cc: alistair23@gmail.com, Alistair Francis Subject: [PATCH v3] sysdeps/nanosleep: Use clock_nanosleep_time64 if avaliable Date: Fri, 1 Nov 2019 02:57:07 -0700 Message-Id: <20191101095707.6208-1-alistair.francis@wdc.com> MIME-Version: 1.0 The nanosleep syscall is not supported on newer 32-bit platforms (such as RV32). To fix this issue let's use clock_nanosleep_time64 if it is avaliable. Let's use CLOCK_REALTIME when calling clock_nanosleep_time64 as the Linux specification says: "POSIX.1 specifies that nanosleep() should measure time against the CLOCK_REALTIME clock. However, Linux measures the time using the CLOCK_MONOTONIC clock. This probably does not matter, since the POSIX.1 specification for clock_settime(2) says that discontinuous changes in CLOCK_REALTIME should not affect nanosleep()" --- The nptl/check-abi-libpthread test is failing on a large number of archs. This is what seems to be failing, although I can't figure out why: diff -p -U 0 ./sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist /glibc-build-many/build/glibcs/mips64el-linux-gnu-n32-soft/glibc/nptl/libpthread.symlist --- ./sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist 2019-10-23 15:15:14.834550013 -0700 +++ /glibc-build-many/build/glibcs/mips64el-linux-gnu-n32-soft/glibc/nptl/libpthread.symlist 2019-11-01 02:30:26.339004183 -0700 @@ -45 +44,0 @@ GLIBC_2.0 msync F -GLIBC_2.0 nanosleep F @@ -195 +193,0 @@ GLIBC_2.2.3 pthread_getattr_np F -GLIBC_2.2.6 __nanosleep F v3: - Fix incorrect fallthroughs - Call __clock_nanosleep_time64 to remove redundant code - Remove Linux version of nanosleep v2: - Explicitly include `#include ` include/time.h | 22 ++++++++ nptl/Makefile | 2 +- nptl/thrd_sleep.c | 25 ++++----- posix/nanosleep.c | 11 +++- sysdeps/unix/sysv/linux/clock_nanosleep.c | 67 +++++++++++++++++++++-- sysdeps/unix/sysv/linux/nanosleep.c | 31 ----------- 6 files changed, 103 insertions(+), 55 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/nanosleep.c diff --git a/include/time.h b/include/time.h index 000672e3bcc..310e0ff29fd 100644 --- a/include/time.h +++ b/include/time.h @@ -165,6 +165,8 @@ extern struct tm *__tz_convert (__time64_t timer, int use_localtime, extern int __nanosleep (const struct timespec *__requested_time, struct timespec *__remaining); hidden_proto (__nanosleep) +extern int __clock_nanosleep (clockid_t clock_id, int flags, + const struct timespec *req, struct timespec *rem); extern int __getdate_r (const char *__string, struct tm *__resbufp) attribute_hidden; @@ -187,6 +189,26 @@ libc_hidden_proto (__difftime64) extern double __difftime (time_t time1, time_t time0); +#if __TIMESIZE == 64 +# define __thrd_sleep_time64 thrd_sleep +# define __clock_nanosleep_time64 __clock_nanosleep +# define __nanosleep_time64 __nanosleep +# define __nanosleep_nocancel_time64 __nanosleep_nocancel +#else +extern int __thrd_sleep_time64 (const struct __timespec64* time_point, + struct __timespec64* remaining); +libc_hidden_proto (__thrd_sleep_time64) +extern int __clock_nanosleep_time64 (clockid_t clock_id, + int flags, const struct __timespec64 *req, + struct __timespec64 *rem); +libc_hidden_proto (__clock_nanosleep_time64) +extern int __nanosleep_time64 (const struct __timespec64 *requested_time, + struct __timespec64 *remaining); +libc_hidden_proto (__nanosleep_time64) +extern int __nanosleep_nocancel_time64 (const struct __timespec64 *requested_time, + struct __timespec64 *remaining); +libc_hidden_proto (__nanosleep_nocancel_time64) +#endif /* Use in the clock_* functions. Size of the field representing the actual clock ID. */ diff --git a/nptl/Makefile b/nptl/Makefile index 41f8f5e8d23..206529063aa 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -44,7 +44,7 @@ pthread-compat-wrappers = \ write read close accept \ connect recv recvfrom send \ sendto fsync lseek lseek64 \ - msync nanosleep open open64 pause \ + msync open open64 pause \ pread pread64 pwrite pwrite64 \ tcdrain wait waitpid msgrcv msgsnd \ sigwait sigsuspend \ diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c index 2e185dd748e..c865f815eea 100644 --- a/nptl/thrd_sleep.c +++ b/nptl/thrd_sleep.c @@ -17,23 +17,18 @@ . */ #include -#include - -#include "thrd_priv.h" +#include int thrd_sleep (const struct timespec* time_point, struct timespec* remaining) { - INTERNAL_SYSCALL_DECL (err); - int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, remaining); - if (INTERNAL_SYSCALL_ERROR_P (ret, err)) - { - /* C11 states thrd_sleep function returns -1 if it has been interrupted - by a signal, or a negative value if it fails. */ - ret = INTERNAL_SYSCALL_ERRNO (ret, err); - if (ret == EINTR) - return -1; - return -2; - } - return 0; + int ret = __clock_nanosleep (CLOCK_REALTIME, 0, time_point, remaining); + /* C11 states thrd_sleep function returns -1 if it has been interrupted + by a signal, or a negative value if it fails. */ + switch (ret) + { + case 0: return 0; + case EINTR: return -1; + default: return -2; + } } diff --git a/posix/nanosleep.c b/posix/nanosleep.c index d8564c71192..12ee70a57c9 100644 --- a/posix/nanosleep.c +++ b/posix/nanosleep.c @@ -22,10 +22,15 @@ /* Pause execution for a number of nanoseconds. */ int __nanosleep (const struct timespec *requested_time, - struct timespec *remaining) + struct timespec *remaining) { - __set_errno (ENOSYS); - return -1; + int ret = __clock_nanosleep (CLOCK_REALTIME, 0, requested_time, remaining); + if (ret != 0) + { + __set_errno (ret); + return -1; + } + return ret; } stub_warning (nanosleep) diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c index 1f240b8720a..97545e96a6c 100644 --- a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -16,6 +16,7 @@ . */ #include +#include #include #include @@ -26,9 +27,11 @@ /* We can simply use the syscall. The CPU clocks are not supported with this function. */ int -__clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, - struct timespec *rem) +__clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec64 *req, + struct __timespec64 *rem) { + int r = -1; + if (clock_id == CLOCK_THREAD_CPUTIME_ID) return EINVAL; if (clock_id == CLOCK_PROCESS_CPUTIME_ID) @@ -37,12 +40,66 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, /* If the call is interrupted by a signal handler or encounters an error, it returns a positive value similar to errno. */ INTERNAL_SYSCALL_DECL (err); - int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, clock_id, flags, - req, rem); + +#ifdef __ASSUME_TIME64_SYSCALLS +# ifndef __NR_clock_nanosleep_time64 +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep +# endif + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, clock_id, + flags, req, rem); +#else +# ifdef __NR_clock_nanosleep_time64 + long int ret_64; + + ret_64 = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, clock_id, + flags, req, rem); + + if (ret_64 == 0 || errno != ENOSYS) + { + return (INTERNAL_SYSCALL_ERROR_P (ret_64, err) + ? INTERNAL_SYSCALL_ERRNO (ret_64, err) : 0); + } +# endif /* __NR_clock_nanosleep_time64 */ + struct timespec ts32, tr32; + + if (! in_time_t_range (req->tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + ts32 = valid_timespec64_to_timespec (*req); + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, &ts32, &tr32); + + if ((r == 0 || errno != ENOSYS) && rem) + *rem = valid_timespec_to_timespec64 (tr32); +#endif /* __ASSUME_TIME64_SYSCALLS */ + return (INTERNAL_SYSCALL_ERROR_P (r, err) - ? INTERNAL_SYSCALL_ERRNO (r, err) : 0); + ? INTERNAL_SYSCALL_ERRNO (r, err) : 0); } +#if __TIMESIZE != 64 +int +__clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, + struct timespec *rem) +{ + int r; + struct __timespec64 treq64, trem64; + + treq64 = valid_timespec_to_timespec64 (*req); + r = __clock_nanosleep_time64 (clock_id, flags, &treq64, &trem64); + + if (r == 0 || errno != ENOSYS) + { + if (rem) + *rem = valid_timespec64_to_timespec (trem64); + } + + return r; +} +#endif + versioned_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_17); /* clock_nanosleep moved to libc in version 2.17; old binaries may expect the symbol version it had in librt. */ diff --git a/sysdeps/unix/sysv/linux/nanosleep.c b/sysdeps/unix/sysv/linux/nanosleep.c deleted file mode 100644 index 6787909248f..00000000000 --- a/sysdeps/unix/sysv/linux/nanosleep.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Linux nanosleep syscall implementation. - Copyright (C) 2017-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 - . */ - -#include -#include -#include - -/* Pause execution for a number of nanoseconds. */ -int -__nanosleep (const struct timespec *requested_time, - struct timespec *remaining) -{ - return SYSCALL_CANCEL (nanosleep, requested_time, remaining); -} -hidden_def (__nanosleep) -weak_alias (__nanosleep, nanosleep)