Message ID | 68f80207b37c5c06984b7a7f62444e35dcbeff56.1567097252.git.alistair.francis@wdc.com |
---|---|
State | New, archived |
Headers |
Received: (qmail 127105 invoked by alias); 29 Aug 2019 16:53:53 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <libc-alpha.sourceware.org> List-Unsubscribe: <mailto:libc-alpha-unsubscribe-##L=##H@sourceware.org> List-Subscribe: <mailto:libc-alpha-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/libc-alpha/> List-Post: <mailto:libc-alpha@sourceware.org> List-Help: <mailto:libc-alpha-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 127035 invoked by uid 89); 29 Aug 2019 16:53:52 -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 autolearn=ham version=3.3.1 spammy=encounters X-HELO: esa2.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=1567097691; x=1598633691; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MJ90FEWZm9a/Xy9xyQh9oW5kpyUVN63x+xQclRJzWgI=; b=PB3H8sb7tZ69KJINsaQvrSJuXx2VVy1gw3Iu5GyEdpce5zNzLeaPlyLO C1fyNObfuFzwCBpVOv5QNdLmLocTxrMo7gwupZMyPDEW2dt6fEJCtZydC hd2yzLalG3oAjl8XkPeYp8ZnFcwSVVxIWOv2/dHLbsSoiQoAHb9J5ZN9K aI5FXXRNdS9Q8Fg/17CmxlSiGcNgwwDbJIoIF67VtGhEK30nA+zJpr2JL bp/wdhrojC/jl2en5ijE8G5nYcy9QyCykMWsABtI+bUJVaUKjiIJPppjz puQlQ6Oue0jszdqsR1xbjNVSEshoGzOegvUocP11e5pWmRGqt0wrPSdpl Q==; IronPort-SDR: cCxkEKolq6/T8bvOaPNBzeU6iobB1v3tTs32BXyUCVChe+0IoXIRDgpBQ5CeNWo889rh7rGjKB 2Tff1rv+1mGWKt54ZuiiMAXC3HSnMjWae91urVFADBb7Bcu7I799ki9LxlYogiI5+/Uk/ykese pGIaiRoPJm2TymkJ62jwJqmmiccbucS3ty0blRPUuq/dks2TZe7MMrJWT/6U7i+QZbGwyPgF5i jG9qWL09JPQwPmMlmCsHVqqt0JzZX33ZzfeiQZpW7sTlwwOnWtfk7Ac1nmmnZBEfawPHSbDjH0 E54= IronPort-SDR: IT39w0vCNzL5KcgTXU9M+VlmeHye5M/P4W4fNXoXhjPkGDGrQUEO9Z3Rs357GFie9FDTnT1H4a aZnlxeJajiqj04GsvPj4NbLpNJolmYRaIp9LgaXZxYnwR7xBocyiSS17S7DvNpR/xI70YEKCn5 7TVL/DGN1Othts5a8HLvNM7nkDODViw+XrPVnoLEgJwBthuEoCAxCvcg3EVDYYGo+nzZrigCnL wEepI2wobzxfchA2TWsl+xTxZT908mmf7k2b96Bd5CX6/TMkA6uUJnu3UMaMUQr6zZG+CL9Djm gMXEuov1QswqSJj0M66fhpq0 IronPort-SDR: /ct55jVDfVqrKehMxc8cpaOuaBb3SJ5kNfRQ8GTjgBJG1tkkxRPIrBcO3Q89TMOV+WpO3JoHOP URrIjcktCN94fFNp4rELyktyT1BAgZQUpjeuFyOaQDb+aF6dnDHG1A2X12LOBSba0k49J7qrj+ JWSq7QnB1Nizq98sNg/f2hbfCfe9cpQ0eolMK1Vilq5PiYSq9ZX2TecWV70PBDQaZ75CkLAKTU hjdWTp4+Ln8bnjqYFXRwd1cxURo903F2gEonR6pvt9eZGP3WLPJyIyqfX60FsP+MilmVJj0QgZ fj8= WDCIronportException: Internal From: Alistair Francis <alistair.francis@wdc.com> To: libc-alpha@sourceware.org Cc: arnd@arndb.de, adhemerval.zanella@linaro.org, fweimer@redhat.com, palmer@sifive.com, macro@wdc.com, zongbox@gmail.com, alistair.francis@wdc.com, alistair23@gmail.com Subject: [RFC v5 02/21] sysdeps/nanosleep: Use clock_nanosleep_time64 if avaliable Date: Thu, 29 Aug 2019 09:50:05 -0700 Message-Id: <68f80207b37c5c06984b7a7f62444e35dcbeff56.1567097252.git.alistair.francis@wdc.com> In-Reply-To: <cover.1567097252.git.alistair.francis@wdc.com> References: <cover.1567097252.git.alistair.francis@wdc.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit |
Commit Message
Alistair Francis
Aug. 29, 2019, 4:50 p.m. UTC
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()"
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
* nptl/thrd_sleep.c: Use clock_nanosleep_time64 instead of nanosleep.
* sysdeps/unix/sysv/linux/nanosleep.c: Likewise.
* sysdeps/unix/sysv/linux/clock_nanosleep.c: Likewise.
* sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise.
---
include/time.h | 6 ++
nptl/thrd_sleep.c | 69 ++++++++++++++++--
sysdeps/unix/sysv/linux/clock_nanosleep.c | 74 ++++++++++++++++++--
sysdeps/unix/sysv/linux/nanosleep.c | 65 ++++++++++++++++-
sysdeps/unix/sysv/linux/nanosleep_nocancel.c | 64 ++++++++++++++++-
5 files changed, 264 insertions(+), 14 deletions(-)
Comments
On Thu, 29 Aug 2019, Alistair Francis wrote:
> + valid_timespec_to_timespec64(&tr32, remaining);
Missing space before '('. Likewise elsewhere in this patch (possibly
elsewhere in the series).
On Thu, Aug 29, 2019 at 10:25 AM Joseph Myers <joseph@codesourcery.com> wrote: > > On Thu, 29 Aug 2019, Alistair Francis wrote: > > > + valid_timespec_to_timespec64(&tr32, remaining); > > Missing space before '('. Likewise elsewhere in this patch (possibly > elsewhere in the series). I have fixed this in all of the patches. Alistair > > -- > Joseph S. Myers > joseph@codesourcery.com
Hi Alistair, > 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()" > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com> > > * nptl/thrd_sleep.c: Use clock_nanosleep_time64 instead of > nanosleep. > * sysdeps/unix/sysv/linux/nanosleep.c: Likewise. > * sysdeps/unix/sysv/linux/clock_nanosleep.c: Likewise. > * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise. > --- > include/time.h | 6 ++ > nptl/thrd_sleep.c | 69 ++++++++++++++++-- > sysdeps/unix/sysv/linux/clock_nanosleep.c | 74 > ++++++++++++++++++-- sysdeps/unix/sysv/linux/nanosleep.c | > 65 ++++++++++++++++- sysdeps/unix/sysv/linux/nanosleep_nocancel.c | > 64 ++++++++++++++++- 5 files changed, 264 insertions(+), 14 > deletions(-) > > diff --git a/include/time.h b/include/time.h > index 95b31429212..6d81f91384b 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -172,6 +172,12 @@ 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 > +#endif > > /* Use in the clock_* functions. Size of the field representing the > actual clock ID. */ > diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c > index 07a51808df2..e85da561c68 100644 > --- a/nptl/thrd_sleep.c > +++ b/nptl/thrd_sleep.c > @@ -22,18 +22,79 @@ > #include "thrd_priv.h" > > int > -thrd_sleep (const struct timespec* time_point, struct timespec* > remaining) +__thrd_sleep_time64 (const struct timespec* time_point, > struct timespec* remaining) { > INTERNAL_SYSCALL_DECL (err); > - int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, > remaining); > + int ret = -1; > + > +#ifdef __ASSUME_TIME64_SYSCALLS > +# ifndef __NR_clock_nanosleep_time64 > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > +# endif > + ret = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > CLOCK_REALTIME, > + 0, time_point, remaining); > +#else > +# ifdef __NR_clock_nanosleep_time64 > + long int ret_64; > + > + ret_64 = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > CLOCK_REALTIME, > + 0, time_point, remaining); > + > + if (ret_64 == 0 || errno != ENOSYS) > + ret = ret_64; > +# endif /* __NR_clock_nanosleep_time64 */ > + if (ret < 0) > + { > + struct timespec tp32, tr32; > + > + if (! in_time_t_range (time_point->tv_sec)) > + { > + __set_errno (EOVERFLOW); > + return -1; > + } > + > + valid_timespec64_to_timespec (time_point, &tp32); > + ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, &tp32, &tr32); > + > + if ((ret == 0 || errno != ENOSYS) && remaining) > + valid_timespec_to_timespec64(&tr32, remaining); > + } > +#endif /* __ASSUME_TIME64_SYSCALLS */ > + > 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. */ > + by a signal, or a negative value if it fails. */ > ret = INTERNAL_SYSCALL_ERRNO (ret, err); > if (ret == EINTR) > - return -1; > + return -1; > return -2; > } > return 0; > } > + > +#if __TIMESIZE != 64 > +int > +thrd_sleep (const struct timespec* time_point, struct timespec* > remaining) +{ > + int ret; > + timespec64 tp64, tr64; > + > + valid_timespec_to_timespec64(time_point, &tp64); > + ret = __thrd_sleep_time64 (&tp64, &tr64); > + > + if (ret == 0 || errno != ENOSYS) > + { > + if (! in_time_t_range (tr64->tv_sec)) > + { > + __set_errno (EOVERFLOW); > + return -1; > + } > + > + if (remaining) > + valid_timespec64_to_timespec(&tr32, remaining); > + } > + > + return ret; > +} > +#endif This code seems to follow the pattern introduced in clock_settime() conversion (already in the -master branch). Do you plan to send this and the following patches: https://patchwork.ozlabs.org/patch/1155396/ --> clock_gettime https://patchwork.ozlabs.org/patch/1155398/ --> timespec_get As a separate patch series so we can all benefit from having them in the -master glibc branch? Those patches seems to be orthogonal to ones adding support for RISC-V. The gettimeofday() syscall handling code seems to being now converted to clock_gettime() in the glibc (or at least there is some ongoing effort): https://sourceware.org/git/?p=glibc.git;a=commit;h=b30d257ea8f557bdadca09f5b112538e7b807eb9 Similar situation is with stat and statfs (which are now under the discussion/review): https://patchwork.ozlabs.org/patch/1155399/ --> stat https://patchwork.ozlabs.org/patch/1155401/ --> statfs > diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c > b/sysdeps/unix/sysv/linux/clock_nanosleep.c index > 0cb6614dc92..64302fbcc69 100644 --- > a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++ > b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -21,13 +21,14 @@ > #include <sysdep-cancel.h> > #include "kernel-posix-cpu-timers.h" > > - > /* 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 timespec *req, > + struct timespec *rem) > { > + int r = -1; > + > if (clock_id == CLOCK_THREAD_CPUTIME_ID) > return EINVAL; > if (clock_id == CLOCK_PROCESS_CPUTIME_ID) > @@ -36,9 +37,70 @@ __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) > + r = ret_64; > +# endif /* __NR_clock_nanosleep_time64 */ > + if (r < 0) > + { > + struct timespec ts32, tr32; > + > + if (! in_time_t_range (req->tv_sec)) > + { > + __set_errno (EOVERFLOW); > + return -1; > + } > + > + valid_timespec64_to_timespec (req, &ts32); > + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, &ts32, > &tr32); + > + if ((r == 0 || errno != ENOSYS) && rem) > + valid_timespec_to_timespec64(&tr32, rem); > + } > +#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; > + timespec64 treq64, trem64; > + > + valid_timespec_to_timespec64(req, &treq64) > + r = __clock_nanosleep_time64 (clock_id, flags, &treq64, &trem64); > + > + if (r == 0 || errno != ENOSYS) > + { > + if (! in_time_t_range (trem64->tv_sec)) > + { > + __set_errno (EOVERFLOW); > + return -1; > + } > + > + if (remaining) > + valid_timespec64_to_timespec(&tr32, remaining); > + } > + > + return r; > +} > +#endif > + > weak_alias (__clock_nanosleep, clock_nanosleep) > diff --git a/sysdeps/unix/sysv/linux/nanosleep.c > b/sysdeps/unix/sysv/linux/nanosleep.c index f14ae565af5..9a8dd5a4b82 > 100644 --- a/sysdeps/unix/sysv/linux/nanosleep.c > +++ b/sysdeps/unix/sysv/linux/nanosleep.c > @@ -22,10 +22,71 @@ > > /* Pause execution for a number of nanoseconds. */ > int > +__nanosleep_time64 (const struct timespec *requested_time, > + struct timespec *remaining) > +{ > +#if defined(__ASSUME_TIME64_SYSCALLS) > +# ifndef __NR_clock_nanosleep_time64 > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > +# endif > + return SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, 0, > + requested_time, remaining); > +#else > +# ifdef __NR_clock_nanosleep_time64 > + long int ret_64; > + > + ret_64 = SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, 0, > + requested_time, remaining); > + > + if (ret_64 == 0 || errno != ENOSYS) > + return ret_64; > +# endif /* __NR_clock_nanosleep_time64 */ > + int ret; > + struct timespec ts32, tr32; > + > + if (! in_time_t_range (requested_time->tv_sec)) > + { > + __set_errno (EOVERFLOW); > + return -1; > + } > + > + valid_timespec64_to_timespec (requested_time, &ts32); > + ret = SYSCALL_CANCEL (nanosleep, &ts32, &tr32); > + > + if ((ret == 0 || errno != ENOSYS) && remaining) > + valid_timespec_to_timespec64(&tr32, remaining); > + > + return ret; > +#endif /* __ASSUME_TIME64_SYSCALLS */ > +} > + > +#if __TIMESIZE != 64 > +int > __nanosleep (const struct timespec *requested_time, > - struct timespec *remaining) > + struct timespec *remaining) > { > - return SYSCALL_CANCEL (nanosleep, requested_time, remaining); > + int r; > + timespec64 treq64, trem64; > + > + > + valid_timespec_to_timespec64(req, &treq64); > + r = __nanosleep_time64 (&treq64, &trem64); > + > + if (r == 0 || errno != ENOSYS) > + { > + if (! in_time_t_range (trem64->tv_sec)) > + { > + __set_errno (EOVERFLOW); > + return -1; > + } > + > + if (remaining) > + valid_timespec64_to_timespec(&tr32, remaining); > + } > + > + return r; > } > +#endif > + > hidden_def (__nanosleep) > weak_alias (__nanosleep, nanosleep) > diff --git a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c index > 122ba627ff3..03f5be2ff9e 100644 --- > a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c +++ > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c @@ -20,10 +20,70 @@ > #include <sysdep-cancel.h> > #include <not-cancel.h> > > +int > +__nanosleep_nocancel_time64 (const struct timespec *requested_time, > + struct timespec *remaining) > +{ > +#ifdef __ASSUME_TIME64_SYSCALLS > +# ifndef __NR_clock_nanosleep_time64 > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > +# endif > + return INLINE_SYSCALL_CALL (clock_nanosleep_time64, > CLOCK_REALTIME, 0, > + requested_time, remaining); > +#else > +# ifdef __NR_clock_nanosleep_time64 > + long int ret_64; > + > + ret_64 = INLINE_SYSCALL_CALL (clock_nanosleep_time64, > CLOCK_REALTIME, 0, > + requested_time, remaining); > + > + if (ret_64 == 0 || errno != ENOSYS) > + return ret_64; > +# endif /* __NR_clock_nanosleep_time64 */ > + int ret; > + struct timespec ts32, tr32; > + > + if (! in_time_t_range (requested_time->tv_sec)) > + { > + __set_errno (EOVERFLOW); > + return -1; > + } > + > + valid_timespec64_to_timespec (requested_time, &ts32); > + ret = INLINE_SYSCALL_CALL (nanosleep, &ts32, &tr32); > + > + if (ret == 0 || errno != ENOSYS) > + valid_timespec_to_timespec64(&tr32, remaining); > + > + return ret; > +#endif /* __ASSUME_TIME64_SYSCALLS */ > +} > + > +#if __TIMESIZE != 64 > int > __nanosleep_nocancel (const struct timespec *requested_time, > - struct timespec *remaining) > + struct timespec *remaining) > { > - return INLINE_SYSCALL_CALL (nanosleep, requested_time, remaining); > + int ret; > + timespec64 treq64, trem64; > + > + valid_timespec_to_timespec64(req, &treq64) > + ret = __nanosleep_nocancel_time64 (&treq64, &trem64); > + > + if (ret == 0 || errno != ENOSYS) > + { > + if (! in_time_t_range (trem64->tv_sec)) > + { > + __set_errno (EOVERFLOW); > + return -1; > + } > + > + if (remaining) > + valid_timespec64_to_timespec(&tr32, remaining); > + } > + > + return ret; > } > +#endif > + > hidden_def (__nanosleep_nocancel) Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On Mon, Oct 14, 2019 at 7:00 AM Lukasz Majewski <lukma@denx.de> wrote: > > Hi Alistair, > > > 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()" > > > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com> > > > > * nptl/thrd_sleep.c: Use clock_nanosleep_time64 instead of > > nanosleep. > > * sysdeps/unix/sysv/linux/nanosleep.c: Likewise. > > * sysdeps/unix/sysv/linux/clock_nanosleep.c: Likewise. > > * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise. > > --- > > include/time.h | 6 ++ > > nptl/thrd_sleep.c | 69 ++++++++++++++++-- > > sysdeps/unix/sysv/linux/clock_nanosleep.c | 74 > > ++++++++++++++++++-- sysdeps/unix/sysv/linux/nanosleep.c | > > 65 ++++++++++++++++- sysdeps/unix/sysv/linux/nanosleep_nocancel.c | > > 64 ++++++++++++++++- 5 files changed, 264 insertions(+), 14 > > deletions(-) > > > > diff --git a/include/time.h b/include/time.h > > index 95b31429212..6d81f91384b 100644 > > --- a/include/time.h > > +++ b/include/time.h > > @@ -172,6 +172,12 @@ 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 > > +#endif > > > > /* Use in the clock_* functions. Size of the field representing the > > actual clock ID. */ > > diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c > > index 07a51808df2..e85da561c68 100644 > > --- a/nptl/thrd_sleep.c > > +++ b/nptl/thrd_sleep.c > > @@ -22,18 +22,79 @@ > > #include "thrd_priv.h" > > > > int > > -thrd_sleep (const struct timespec* time_point, struct timespec* > > remaining) +__thrd_sleep_time64 (const struct timespec* time_point, > > struct timespec* remaining) { > > INTERNAL_SYSCALL_DECL (err); > > - int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, > > remaining); > > + int ret = -1; > > + > > +#ifdef __ASSUME_TIME64_SYSCALLS > > +# ifndef __NR_clock_nanosleep_time64 > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > +# endif > > + ret = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > > CLOCK_REALTIME, > > + 0, time_point, remaining); > > +#else > > +# ifdef __NR_clock_nanosleep_time64 > > + long int ret_64; > > + > > + ret_64 = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > > CLOCK_REALTIME, > > + 0, time_point, remaining); > > + > > + if (ret_64 == 0 || errno != ENOSYS) > > + ret = ret_64; > > +# endif /* __NR_clock_nanosleep_time64 */ > > + if (ret < 0) > > + { > > + struct timespec tp32, tr32; > > + > > + if (! in_time_t_range (time_point->tv_sec)) > > + { > > + __set_errno (EOVERFLOW); > > + return -1; > > + } > > + > > + valid_timespec64_to_timespec (time_point, &tp32); > > + ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, &tp32, &tr32); > > + > > + if ((ret == 0 || errno != ENOSYS) && remaining) > > + valid_timespec_to_timespec64(&tr32, remaining); > > + } > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > + > > 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. */ > > + by a signal, or a negative value if it fails. */ > > ret = INTERNAL_SYSCALL_ERRNO (ret, err); > > if (ret == EINTR) > > - return -1; > > + return -1; > > return -2; > > } > > return 0; > > } > > + > > +#if __TIMESIZE != 64 > > +int > > +thrd_sleep (const struct timespec* time_point, struct timespec* > > remaining) +{ > > + int ret; > > + timespec64 tp64, tr64; > > + > > + valid_timespec_to_timespec64(time_point, &tp64); > > + ret = __thrd_sleep_time64 (&tp64, &tr64); > > + > > + if (ret == 0 || errno != ENOSYS) > > + { > > + if (! in_time_t_range (tr64->tv_sec)) > > + { > > + __set_errno (EOVERFLOW); > > + return -1; > > + } > > + > > + if (remaining) > > + valid_timespec64_to_timespec(&tr32, remaining); > > + } > > + > > + return ret; > > +} > > +#endif > > This code seems to follow the pattern introduced in clock_settime() > conversion (already in the -master branch). I hope so :) > > Do you plan to send this and the following patches: > > https://patchwork.ozlabs.org/patch/1155396/ --> clock_gettime > https://patchwork.ozlabs.org/patch/1155398/ --> timespec_get Yes > > As a separate patch series so we can all benefit from having them in > the -master glibc branch? > Those patches seems to be orthogonal to ones adding support for RISC-V. Yep! My plan is to send them seperatley. I have been working through the RV32 tree sending patches in small batches to get them merged. I have a few more batches before I get to these time64_t conversion patches though. I am unfortunately seeing failures with my time64_t conversion patches which I haven't had a chance to look into. > > > The gettimeofday() syscall handling code seems to being now converted to > clock_gettime() in the glibc (or at least there is some ongoing effort): > > https://sourceware.org/git/?p=glibc.git;a=commit;h=b30d257ea8f557bdadca09f5b112538e7b807eb9 Yep, I have rebased all of my work on top of this. > > Similar situation is with stat and statfs (which are now under the > discussion/review): > > https://patchwork.ozlabs.org/patch/1155399/ --> stat > https://patchwork.ozlabs.org/patch/1155401/ --> statfs Yep, I'm working on the next version right now. If you want you are welcome to split out any patches and get them upstreaed. Even just fixing failing test cases would speed things up. My branch is available here: https://github.com/alistair23/glibc/commits/alistair/rv32.next Alistair > > > diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c > > b/sysdeps/unix/sysv/linux/clock_nanosleep.c index > > 0cb6614dc92..64302fbcc69 100644 --- > > a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++ > > b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -21,13 +21,14 @@ > > #include <sysdep-cancel.h> > > #include "kernel-posix-cpu-timers.h" > > > > - > > /* 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 timespec *req, > > + struct timespec *rem) > > { > > + int r = -1; > > + > > if (clock_id == CLOCK_THREAD_CPUTIME_ID) > > return EINVAL; > > if (clock_id == CLOCK_PROCESS_CPUTIME_ID) > > @@ -36,9 +37,70 @@ __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) > > + r = ret_64; > > +# endif /* __NR_clock_nanosleep_time64 */ > > + if (r < 0) > > + { > > + struct timespec ts32, tr32; > > + > > + if (! in_time_t_range (req->tv_sec)) > > + { > > + __set_errno (EOVERFLOW); > > + return -1; > > + } > > + > > + valid_timespec64_to_timespec (req, &ts32); > > + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, &ts32, > > &tr32); + > > + if ((r == 0 || errno != ENOSYS) && rem) > > + valid_timespec_to_timespec64(&tr32, rem); > > + } > > +#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; > > + timespec64 treq64, trem64; > > + > > + valid_timespec_to_timespec64(req, &treq64) > > + r = __clock_nanosleep_time64 (clock_id, flags, &treq64, &trem64); > > + > > + if (r == 0 || errno != ENOSYS) > > + { > > + if (! in_time_t_range (trem64->tv_sec)) > > + { > > + __set_errno (EOVERFLOW); > > + return -1; > > + } > > + > > + if (remaining) > > + valid_timespec64_to_timespec(&tr32, remaining); > > + } > > + > > + return r; > > +} > > +#endif > > + > > weak_alias (__clock_nanosleep, clock_nanosleep) > > diff --git a/sysdeps/unix/sysv/linux/nanosleep.c > > b/sysdeps/unix/sysv/linux/nanosleep.c index f14ae565af5..9a8dd5a4b82 > > 100644 --- a/sysdeps/unix/sysv/linux/nanosleep.c > > +++ b/sysdeps/unix/sysv/linux/nanosleep.c > > @@ -22,10 +22,71 @@ > > > > /* Pause execution for a number of nanoseconds. */ > > int > > +__nanosleep_time64 (const struct timespec *requested_time, > > + struct timespec *remaining) > > +{ > > +#if defined(__ASSUME_TIME64_SYSCALLS) > > +# ifndef __NR_clock_nanosleep_time64 > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > +# endif > > + return SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, 0, > > + requested_time, remaining); > > +#else > > +# ifdef __NR_clock_nanosleep_time64 > > + long int ret_64; > > + > > + ret_64 = SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, 0, > > + requested_time, remaining); > > + > > + if (ret_64 == 0 || errno != ENOSYS) > > + return ret_64; > > +# endif /* __NR_clock_nanosleep_time64 */ > > + int ret; > > + struct timespec ts32, tr32; > > + > > + if (! in_time_t_range (requested_time->tv_sec)) > > + { > > + __set_errno (EOVERFLOW); > > + return -1; > > + } > > + > > + valid_timespec64_to_timespec (requested_time, &ts32); > > + ret = SYSCALL_CANCEL (nanosleep, &ts32, &tr32); > > + > > + if ((ret == 0 || errno != ENOSYS) && remaining) > > + valid_timespec_to_timespec64(&tr32, remaining); > > + > > + return ret; > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > +} > > + > > +#if __TIMESIZE != 64 > > +int > > __nanosleep (const struct timespec *requested_time, > > - struct timespec *remaining) > > + struct timespec *remaining) > > { > > - return SYSCALL_CANCEL (nanosleep, requested_time, remaining); > > + int r; > > + timespec64 treq64, trem64; > > + > > + > > + valid_timespec_to_timespec64(req, &treq64); > > + r = __nanosleep_time64 (&treq64, &trem64); > > + > > + if (r == 0 || errno != ENOSYS) > > + { > > + if (! in_time_t_range (trem64->tv_sec)) > > + { > > + __set_errno (EOVERFLOW); > > + return -1; > > + } > > + > > + if (remaining) > > + valid_timespec64_to_timespec(&tr32, remaining); > > + } > > + > > + return r; > > } > > +#endif > > + > > hidden_def (__nanosleep) > > weak_alias (__nanosleep, nanosleep) > > diff --git a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c > > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c index > > 122ba627ff3..03f5be2ff9e 100644 --- > > a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c +++ > > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c @@ -20,10 +20,70 @@ > > #include <sysdep-cancel.h> > > #include <not-cancel.h> > > > > +int > > +__nanosleep_nocancel_time64 (const struct timespec *requested_time, > > + struct timespec *remaining) > > +{ > > +#ifdef __ASSUME_TIME64_SYSCALLS > > +# ifndef __NR_clock_nanosleep_time64 > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > +# endif > > + return INLINE_SYSCALL_CALL (clock_nanosleep_time64, > > CLOCK_REALTIME, 0, > > + requested_time, remaining); > > +#else > > +# ifdef __NR_clock_nanosleep_time64 > > + long int ret_64; > > + > > + ret_64 = INLINE_SYSCALL_CALL (clock_nanosleep_time64, > > CLOCK_REALTIME, 0, > > + requested_time, remaining); > > + > > + if (ret_64 == 0 || errno != ENOSYS) > > + return ret_64; > > +# endif /* __NR_clock_nanosleep_time64 */ > > + int ret; > > + struct timespec ts32, tr32; > > + > > + if (! in_time_t_range (requested_time->tv_sec)) > > + { > > + __set_errno (EOVERFLOW); > > + return -1; > > + } > > + > > + valid_timespec64_to_timespec (requested_time, &ts32); > > + ret = INLINE_SYSCALL_CALL (nanosleep, &ts32, &tr32); > > + > > + if (ret == 0 || errno != ENOSYS) > > + valid_timespec_to_timespec64(&tr32, remaining); > > + > > + return ret; > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > +} > > + > > +#if __TIMESIZE != 64 > > int > > __nanosleep_nocancel (const struct timespec *requested_time, > > - struct timespec *remaining) > > + struct timespec *remaining) > > { > > - return INLINE_SYSCALL_CALL (nanosleep, requested_time, remaining); > > + int ret; > > + timespec64 treq64, trem64; > > + > > + valid_timespec_to_timespec64(req, &treq64) > > + ret = __nanosleep_nocancel_time64 (&treq64, &trem64); > > + > > + if (ret == 0 || errno != ENOSYS) > > + { > > + if (! in_time_t_range (trem64->tv_sec)) > > + { > > + __set_errno (EOVERFLOW); > > + return -1; > > + } > > + > > + if (remaining) > > + valid_timespec64_to_timespec(&tr32, remaining); > > + } > > + > > + return ret; > > } > > +#endif > > + > > hidden_def (__nanosleep_nocancel) > > > > > Best regards, > > Lukasz Majewski > > -- > > DENX Software Engineering GmbH, Managing Director: Wolfgang Denk > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
Hi Alistair, > On Mon, Oct 14, 2019 at 7:00 AM Lukasz Majewski <lukma@denx.de> wrote: > > > > Hi Alistair, > > > > > 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()" > > > > > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com> > > > > > > * nptl/thrd_sleep.c: Use clock_nanosleep_time64 instead of > > > nanosleep. > > > * sysdeps/unix/sysv/linux/nanosleep.c: Likewise. > > > * sysdeps/unix/sysv/linux/clock_nanosleep.c: Likewise. > > > * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise. > > > --- > > > include/time.h | 6 ++ > > > nptl/thrd_sleep.c | 69 > > > ++++++++++++++++-- sysdeps/unix/sysv/linux/clock_nanosleep.c | > > > 74 ++++++++++++++++++-- sysdeps/unix/sysv/linux/nanosleep.c > > > | 65 ++++++++++++++++- > > > sysdeps/unix/sysv/linux/nanosleep_nocancel.c | 64 > > > ++++++++++++++++- 5 files changed, 264 insertions(+), 14 > > > deletions(-) > > > > > > diff --git a/include/time.h b/include/time.h > > > index 95b31429212..6d81f91384b 100644 > > > --- a/include/time.h > > > +++ b/include/time.h > > > @@ -172,6 +172,12 @@ 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 > > > +#endif > > > > > > /* Use in the clock_* functions. Size of the field representing > > > the actual clock ID. */ > > > diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c > > > index 07a51808df2..e85da561c68 100644 > > > --- a/nptl/thrd_sleep.c > > > +++ b/nptl/thrd_sleep.c > > > @@ -22,18 +22,79 @@ > > > #include "thrd_priv.h" > > > > > > int > > > -thrd_sleep (const struct timespec* time_point, struct timespec* > > > remaining) +__thrd_sleep_time64 (const struct timespec* > > > time_point, struct timespec* remaining) { > > > INTERNAL_SYSCALL_DECL (err); > > > - int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, > > > remaining); > > > + int ret = -1; > > > + > > > +#ifdef __ASSUME_TIME64_SYSCALLS > > > +# ifndef __NR_clock_nanosleep_time64 > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > +# endif > > > + ret = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > > > CLOCK_REALTIME, > > > + 0, time_point, remaining); > > > +#else > > > +# ifdef __NR_clock_nanosleep_time64 > > > + long int ret_64; > > > + > > > + ret_64 = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > > > CLOCK_REALTIME, > > > + 0, time_point, remaining); > > > + > > > + if (ret_64 == 0 || errno != ENOSYS) > > > + ret = ret_64; > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > + if (ret < 0) > > > + { > > > + struct timespec tp32, tr32; > > > + > > > + if (! in_time_t_range (time_point->tv_sec)) > > > + { > > > + __set_errno (EOVERFLOW); > > > + return -1; > > > + } > > > + > > > + valid_timespec64_to_timespec (time_point, &tp32); > > > + ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, &tp32, > > > &tr32); + > > > + if ((ret == 0 || errno != ENOSYS) && remaining) > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > + } > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > + > > > 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. */ > > > + by a signal, or a negative value if it fails. */ > > > ret = INTERNAL_SYSCALL_ERRNO (ret, err); > > > if (ret == EINTR) > > > - return -1; > > > + return -1; > > > return -2; > > > } > > > return 0; > > > } > > > + > > > +#if __TIMESIZE != 64 > > > +int > > > +thrd_sleep (const struct timespec* time_point, struct timespec* > > > remaining) +{ > > > + int ret; > > > + timespec64 tp64, tr64; > > > + > > > + valid_timespec_to_timespec64(time_point, &tp64); > > > + ret = __thrd_sleep_time64 (&tp64, &tr64); > > > + > > > + if (ret == 0 || errno != ENOSYS) > > > + { > > > + if (! in_time_t_range (tr64->tv_sec)) > > > + { > > > + __set_errno (EOVERFLOW); > > > + return -1; > > > + } > > > + > > > + if (remaining) > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > + } > > > + > > > + return ret; > > > +} > > > +#endif > > > > This code seems to follow the pattern introduced in clock_settime() > > conversion (already in the -master branch). > > I hope so :) > > > > > Do you plan to send this and the following patches: > > > > https://patchwork.ozlabs.org/patch/1155396/ --> clock_gettime > > https://patchwork.ozlabs.org/patch/1155398/ --> timespec_get > > Yes > > > > > As a separate patch series so we can all benefit from having them in > > the -master glibc branch? > > Those patches seems to be orthogonal to ones adding support for > > RISC-V. > > Yep! My plan is to send them seperatley. I have been working through > the RV32 tree sending patches in small batches to get them merged. I > have a few more batches before I get to these time64_t conversion > patches though. I am unfortunately seeing failures with my time64_t > conversion patches which I haven't had a chance to look into. > > > > > > > The gettimeofday() syscall handling code seems to being now > > converted to clock_gettime() in the glibc (or at least there is > > some ongoing effort): > > > > https://sourceware.org/git/?p=glibc.git;a=commit;h=b30d257ea8f557bdadca09f5b112538e7b807eb9 > > > > Yep, I have rebased all of my work on top of this. > > > > > Similar situation is with stat and statfs (which are now under the > > discussion/review): > > > > https://patchwork.ozlabs.org/patch/1155399/ --> stat > > https://patchwork.ozlabs.org/patch/1155401/ --> statfs > > Yep, I'm working on the next version right now. > > If you want you are welcome to split out any patches and get them > upstreaed. Even just fixing failing test cases would speed things up. > My branch is available here: > https://github.com/alistair23/glibc/commits/alistair/rv32.next > Please find some comments and my future work plan: 1. The "sysdeps/clock_getres: Use inline syscall if required" : https://github.com/alistair23/glibc/commit/830707a4a3f662b1a97860afe658f6bbd9731d13 commit does not convert this syscall. However, I can convert and post to the glibc alpha the __clock_getres64 (as I already have some older code available). I'm now working on preparing proper patch. 2. Potential compilation error for SoCs with TIMESIZE != 64: https://github.com/alistair23/glibc/commit/4309573e10479516fcdf75c353309497f8017c90#diff-85643011757f36e12ca60b37c3e8ec0dR75 3. Would you be so kind and post (to glibc alpha) the already converted (in your -next tree) __clock_nanosleep64: https://github.com/alistair23/glibc/commit/9e3d95ad1f70909a787dd11fbc735bcafa02050e#diff-5b9f1c6457e0e10079f657f283c19861R177 Just one remark - please in include/time.h use the following paradigm: https://github.com/lmajewski/y2038_glibc/commit/7ff615859f9e111c0c4cf8a6c085201c7ed82813#diff-5b9f1c6457e0e10079f657f283c19861R128 for redirection. > Alistair > > > > > > diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c > > > b/sysdeps/unix/sysv/linux/clock_nanosleep.c index > > > 0cb6614dc92..64302fbcc69 100644 --- > > > a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++ > > > b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -21,13 +21,14 @@ > > > #include <sysdep-cancel.h> > > > #include "kernel-posix-cpu-timers.h" > > > > > > - > > > /* 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 timespec *req, > > > + struct timespec *rem) > > > { > > > + int r = -1; > > > + > > > if (clock_id == CLOCK_THREAD_CPUTIME_ID) > > > return EINVAL; > > > if (clock_id == CLOCK_PROCESS_CPUTIME_ID) > > > @@ -36,9 +37,70 @@ __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) > > > + r = ret_64; > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > + if (r < 0) > > > + { > > > + struct timespec ts32, tr32; > > > + > > > + if (! in_time_t_range (req->tv_sec)) > > > + { > > > + __set_errno (EOVERFLOW); > > > + return -1; > > > + } > > > + > > > + valid_timespec64_to_timespec (req, &ts32); > > > + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, &ts32, > > > &tr32); + > > > + if ((r == 0 || errno != ENOSYS) && rem) > > > + valid_timespec_to_timespec64(&tr32, rem); > > > + } > > > +#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; > > > + timespec64 treq64, trem64; > > > + > > > + valid_timespec_to_timespec64(req, &treq64) > > > + r = __clock_nanosleep_time64 (clock_id, flags, &treq64, > > > &trem64); + > > > + if (r == 0 || errno != ENOSYS) > > > + { > > > + if (! in_time_t_range (trem64->tv_sec)) > > > + { > > > + __set_errno (EOVERFLOW); > > > + return -1; > > > + } > > > + > > > + if (remaining) > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > + } > > > + > > > + return r; > > > +} > > > +#endif > > > + > > > weak_alias (__clock_nanosleep, clock_nanosleep) > > > diff --git a/sysdeps/unix/sysv/linux/nanosleep.c > > > b/sysdeps/unix/sysv/linux/nanosleep.c index > > > f14ae565af5..9a8dd5a4b82 100644 --- > > > a/sysdeps/unix/sysv/linux/nanosleep.c +++ > > > b/sysdeps/unix/sysv/linux/nanosleep.c @@ -22,10 +22,71 @@ > > > > > > /* Pause execution for a number of nanoseconds. */ > > > int > > > +__nanosleep_time64 (const struct timespec *requested_time, > > > + struct timespec *remaining) > > > +{ > > > +#if defined(__ASSUME_TIME64_SYSCALLS) > > > +# ifndef __NR_clock_nanosleep_time64 > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > +# endif > > > + return SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, > > > 0, > > > + requested_time, remaining); > > > +#else > > > +# ifdef __NR_clock_nanosleep_time64 > > > + long int ret_64; > > > + > > > + ret_64 = SYSCALL_CANCEL (clock_nanosleep_time64, > > > CLOCK_REALTIME, 0, > > > + requested_time, remaining); > > > + > > > + if (ret_64 == 0 || errno != ENOSYS) > > > + return ret_64; > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > + int ret; > > > + struct timespec ts32, tr32; > > > + > > > + if (! in_time_t_range (requested_time->tv_sec)) > > > + { > > > + __set_errno (EOVERFLOW); > > > + return -1; > > > + } > > > + > > > + valid_timespec64_to_timespec (requested_time, &ts32); > > > + ret = SYSCALL_CANCEL (nanosleep, &ts32, &tr32); > > > + > > > + if ((ret == 0 || errno != ENOSYS) && remaining) > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > + > > > + return ret; > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > +} > > > + > > > +#if __TIMESIZE != 64 > > > +int > > > __nanosleep (const struct timespec *requested_time, > > > - struct timespec *remaining) > > > + struct timespec *remaining) > > > { > > > - return SYSCALL_CANCEL (nanosleep, requested_time, remaining); > > > + int r; > > > + timespec64 treq64, trem64; > > > + > > > + > > > + valid_timespec_to_timespec64(req, &treq64); > > > + r = __nanosleep_time64 (&treq64, &trem64); > > > + > > > + if (r == 0 || errno != ENOSYS) > > > + { > > > + if (! in_time_t_range (trem64->tv_sec)) > > > + { > > > + __set_errno (EOVERFLOW); > > > + return -1; > > > + } > > > + > > > + if (remaining) > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > + } > > > + > > > + return r; > > > } > > > +#endif > > > + > > > hidden_def (__nanosleep) > > > weak_alias (__nanosleep, nanosleep) > > > diff --git a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c > > > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c index > > > 122ba627ff3..03f5be2ff9e 100644 --- > > > a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c +++ > > > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c @@ -20,10 +20,70 @@ > > > #include <sysdep-cancel.h> > > > #include <not-cancel.h> > > > > > > +int > > > +__nanosleep_nocancel_time64 (const struct timespec > > > *requested_time, > > > + struct timespec *remaining) > > > +{ > > > +#ifdef __ASSUME_TIME64_SYSCALLS > > > +# ifndef __NR_clock_nanosleep_time64 > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > +# endif > > > + return INLINE_SYSCALL_CALL (clock_nanosleep_time64, > > > CLOCK_REALTIME, 0, > > > + requested_time, remaining); > > > +#else > > > +# ifdef __NR_clock_nanosleep_time64 > > > + long int ret_64; > > > + > > > + ret_64 = INLINE_SYSCALL_CALL (clock_nanosleep_time64, > > > CLOCK_REALTIME, 0, > > > + requested_time, remaining); > > > + > > > + if (ret_64 == 0 || errno != ENOSYS) > > > + return ret_64; > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > + int ret; > > > + struct timespec ts32, tr32; > > > + > > > + if (! in_time_t_range (requested_time->tv_sec)) > > > + { > > > + __set_errno (EOVERFLOW); > > > + return -1; > > > + } > > > + > > > + valid_timespec64_to_timespec (requested_time, &ts32); > > > + ret = INLINE_SYSCALL_CALL (nanosleep, &ts32, &tr32); > > > + > > > + if (ret == 0 || errno != ENOSYS) > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > + > > > + return ret; > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > +} > > > + > > > +#if __TIMESIZE != 64 > > > int > > > __nanosleep_nocancel (const struct timespec *requested_time, > > > - struct timespec *remaining) > > > + struct timespec *remaining) > > > { > > > - return INLINE_SYSCALL_CALL (nanosleep, requested_time, > > > remaining); > > > + int ret; > > > + timespec64 treq64, trem64; > > > + > > > + valid_timespec_to_timespec64(req, &treq64) > > > + ret = __nanosleep_nocancel_time64 (&treq64, &trem64); > > > + > > > + if (ret == 0 || errno != ENOSYS) > > > + { > > > + if (! in_time_t_range (trem64->tv_sec)) > > > + { > > > + __set_errno (EOVERFLOW); > > > + return -1; > > > + } > > > + > > > + if (remaining) > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > + } > > > + > > > + return ret; > > > } > > > +#endif > > > + > > > hidden_def (__nanosleep_nocancel) > > > > > > > > > > Best regards, > > > > Lukasz Majewski > > > > -- > > > > DENX Software Engineering GmbH, Managing Director: Wolfgang > > Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, > > Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: > > lukma@denx.de Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On Tue, Oct 15, 2019 at 8:55 AM Lukasz Majewski <lukma@denx.de> wrote: > > Hi Alistair, > > > On Mon, Oct 14, 2019 at 7:00 AM Lukasz Majewski <lukma@denx.de> wrote: > > > > > > Hi Alistair, > > > > > > > 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()" > > > > > > > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com> > > > > > > > > * nptl/thrd_sleep.c: Use clock_nanosleep_time64 instead of > > > > nanosleep. > > > > * sysdeps/unix/sysv/linux/nanosleep.c: Likewise. > > > > * sysdeps/unix/sysv/linux/clock_nanosleep.c: Likewise. > > > > * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise. > > > > --- > > > > include/time.h | 6 ++ > > > > nptl/thrd_sleep.c | 69 > > > > ++++++++++++++++-- sysdeps/unix/sysv/linux/clock_nanosleep.c | > > > > 74 ++++++++++++++++++-- sysdeps/unix/sysv/linux/nanosleep.c > > > > | 65 ++++++++++++++++- > > > > sysdeps/unix/sysv/linux/nanosleep_nocancel.c | 64 > > > > ++++++++++++++++- 5 files changed, 264 insertions(+), 14 > > > > deletions(-) > > > > > > > > diff --git a/include/time.h b/include/time.h > > > > index 95b31429212..6d81f91384b 100644 > > > > --- a/include/time.h > > > > +++ b/include/time.h > > > > @@ -172,6 +172,12 @@ 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 > > > > +#endif > > > > > > > > /* Use in the clock_* functions. Size of the field representing > > > > the actual clock ID. */ > > > > diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c > > > > index 07a51808df2..e85da561c68 100644 > > > > --- a/nptl/thrd_sleep.c > > > > +++ b/nptl/thrd_sleep.c > > > > @@ -22,18 +22,79 @@ > > > > #include "thrd_priv.h" > > > > > > > > int > > > > -thrd_sleep (const struct timespec* time_point, struct timespec* > > > > remaining) +__thrd_sleep_time64 (const struct timespec* > > > > time_point, struct timespec* remaining) { > > > > INTERNAL_SYSCALL_DECL (err); > > > > - int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, > > > > remaining); > > > > + int ret = -1; > > > > + > > > > +#ifdef __ASSUME_TIME64_SYSCALLS > > > > +# ifndef __NR_clock_nanosleep_time64 > > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > > +# endif > > > > + ret = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > > > > CLOCK_REALTIME, > > > > + 0, time_point, remaining); > > > > +#else > > > > +# ifdef __NR_clock_nanosleep_time64 > > > > + long int ret_64; > > > > + > > > > + ret_64 = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > > > > CLOCK_REALTIME, > > > > + 0, time_point, remaining); > > > > + > > > > + if (ret_64 == 0 || errno != ENOSYS) > > > > + ret = ret_64; > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > + if (ret < 0) > > > > + { > > > > + struct timespec tp32, tr32; > > > > + > > > > + if (! in_time_t_range (time_point->tv_sec)) > > > > + { > > > > + __set_errno (EOVERFLOW); > > > > + return -1; > > > > + } > > > > + > > > > + valid_timespec64_to_timespec (time_point, &tp32); > > > > + ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, &tp32, > > > > &tr32); + > > > > + if ((ret == 0 || errno != ENOSYS) && remaining) > > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > > + } > > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > > + > > > > 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. */ > > > > + by a signal, or a negative value if it fails. */ > > > > ret = INTERNAL_SYSCALL_ERRNO (ret, err); > > > > if (ret == EINTR) > > > > - return -1; > > > > + return -1; > > > > return -2; > > > > } > > > > return 0; > > > > } > > > > + > > > > +#if __TIMESIZE != 64 > > > > +int > > > > +thrd_sleep (const struct timespec* time_point, struct timespec* > > > > remaining) +{ > > > > + int ret; > > > > + timespec64 tp64, tr64; > > > > + > > > > + valid_timespec_to_timespec64(time_point, &tp64); > > > > + ret = __thrd_sleep_time64 (&tp64, &tr64); > > > > + > > > > + if (ret == 0 || errno != ENOSYS) > > > > + { > > > > + if (! in_time_t_range (tr64->tv_sec)) > > > > + { > > > > + __set_errno (EOVERFLOW); > > > > + return -1; > > > > + } > > > > + > > > > + if (remaining) > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > + } > > > > + > > > > + return ret; > > > > +} > > > > +#endif > > > > > > This code seems to follow the pattern introduced in clock_settime() > > > conversion (already in the -master branch). > > > > I hope so :) > > > > > > > > Do you plan to send this and the following patches: > > > > > > https://patchwork.ozlabs.org/patch/1155396/ --> clock_gettime > > > https://patchwork.ozlabs.org/patch/1155398/ --> timespec_get > > > > Yes > > > > > > > > As a separate patch series so we can all benefit from having them in > > > the -master glibc branch? > > > Those patches seems to be orthogonal to ones adding support for > > > RISC-V. > > > > Yep! My plan is to send them seperatley. I have been working through > > the RV32 tree sending patches in small batches to get them merged. I > > have a few more batches before I get to these time64_t conversion > > patches though. I am unfortunately seeing failures with my time64_t > > conversion patches which I haven't had a chance to look into. > > > > > > > > > > > The gettimeofday() syscall handling code seems to being now > > > converted to clock_gettime() in the glibc (or at least there is > > > some ongoing effort): > > > > > > https://sourceware.org/git/?p=glibc.git;a=commit;h=b30d257ea8f557bdadca09f5b112538e7b807eb9 > > > > > > > Yep, I have rebased all of my work on top of this. > > > > > > > > Similar situation is with stat and statfs (which are now under the > > > discussion/review): > > > > > > https://patchwork.ozlabs.org/patch/1155399/ --> stat > > > https://patchwork.ozlabs.org/patch/1155401/ --> statfs > > > > Yep, I'm working on the next version right now. > > > > If you want you are welcome to split out any patches and get them > > upstreaed. Even just fixing failing test cases would speed things up. > > My branch is available here: > > https://github.com/alistair23/glibc/commits/alistair/rv32.next > > > > Please find some comments and my future work plan: > > 1. The "sysdeps/clock_getres: Use inline syscall if required" : > https://github.com/alistair23/glibc/commit/830707a4a3f662b1a97860afe658f6bbd9731d13 > commit does not convert this syscall. > > However, I can convert and post to the glibc alpha the __clock_getres64 > (as I already have some older code available). I'm now working on > preparing proper patch. Go for it! :) > > > 2. Potential compilation error for SoCs with TIMESIZE != 64: > https://github.com/alistair23/glibc/commit/4309573e10479516fcdf75c353309497f8017c90#diff-85643011757f36e12ca60b37c3e8ec0dR75 What is the error? > > > 3. Would you be so kind and post (to glibc alpha) the already converted > (in your -next tree) __clock_nanosleep64: > https://github.com/alistair23/glibc/commit/9e3d95ad1f70909a787dd11fbc735bcafa02050e#diff-5b9f1c6457e0e10079f657f283c19861R177 This patch is causing build failures, so I need to investigate that. > > Just one remark - please in include/time.h use the following paradigm: > https://github.com/lmajewski/y2038_glibc/commit/7ff615859f9e111c0c4cf8a6c085201c7ed82813#diff-5b9f1c6457e0e10079f657f283c19861R128 Ok, I'll add this. Alistair > > for redirection. > > > > Alistair > > > > > > > > > diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c > > > > b/sysdeps/unix/sysv/linux/clock_nanosleep.c index > > > > 0cb6614dc92..64302fbcc69 100644 --- > > > > a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++ > > > > b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -21,13 +21,14 @@ > > > > #include <sysdep-cancel.h> > > > > #include "kernel-posix-cpu-timers.h" > > > > > > > > - > > > > /* 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 timespec *req, > > > > + struct timespec *rem) > > > > { > > > > + int r = -1; > > > > + > > > > if (clock_id == CLOCK_THREAD_CPUTIME_ID) > > > > return EINVAL; > > > > if (clock_id == CLOCK_PROCESS_CPUTIME_ID) > > > > @@ -36,9 +37,70 @@ __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) > > > > + r = ret_64; > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > + if (r < 0) > > > > + { > > > > + struct timespec ts32, tr32; > > > > + > > > > + if (! in_time_t_range (req->tv_sec)) > > > > + { > > > > + __set_errno (EOVERFLOW); > > > > + return -1; > > > > + } > > > > + > > > > + valid_timespec64_to_timespec (req, &ts32); > > > > + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, &ts32, > > > > &tr32); + > > > > + if ((r == 0 || errno != ENOSYS) && rem) > > > > + valid_timespec_to_timespec64(&tr32, rem); > > > > + } > > > > +#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; > > > > + timespec64 treq64, trem64; > > > > + > > > > + valid_timespec_to_timespec64(req, &treq64) > > > > + r = __clock_nanosleep_time64 (clock_id, flags, &treq64, > > > > &trem64); + > > > > + if (r == 0 || errno != ENOSYS) > > > > + { > > > > + if (! in_time_t_range (trem64->tv_sec)) > > > > + { > > > > + __set_errno (EOVERFLOW); > > > > + return -1; > > > > + } > > > > + > > > > + if (remaining) > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > + } > > > > + > > > > + return r; > > > > +} > > > > +#endif > > > > + > > > > weak_alias (__clock_nanosleep, clock_nanosleep) > > > > diff --git a/sysdeps/unix/sysv/linux/nanosleep.c > > > > b/sysdeps/unix/sysv/linux/nanosleep.c index > > > > f14ae565af5..9a8dd5a4b82 100644 --- > > > > a/sysdeps/unix/sysv/linux/nanosleep.c +++ > > > > b/sysdeps/unix/sysv/linux/nanosleep.c @@ -22,10 +22,71 @@ > > > > > > > > /* Pause execution for a number of nanoseconds. */ > > > > int > > > > +__nanosleep_time64 (const struct timespec *requested_time, > > > > + struct timespec *remaining) > > > > +{ > > > > +#if defined(__ASSUME_TIME64_SYSCALLS) > > > > +# ifndef __NR_clock_nanosleep_time64 > > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > > +# endif > > > > + return SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, > > > > 0, > > > > + requested_time, remaining); > > > > +#else > > > > +# ifdef __NR_clock_nanosleep_time64 > > > > + long int ret_64; > > > > + > > > > + ret_64 = SYSCALL_CANCEL (clock_nanosleep_time64, > > > > CLOCK_REALTIME, 0, > > > > + requested_time, remaining); > > > > + > > > > + if (ret_64 == 0 || errno != ENOSYS) > > > > + return ret_64; > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > + int ret; > > > > + struct timespec ts32, tr32; > > > > + > > > > + if (! in_time_t_range (requested_time->tv_sec)) > > > > + { > > > > + __set_errno (EOVERFLOW); > > > > + return -1; > > > > + } > > > > + > > > > + valid_timespec64_to_timespec (requested_time, &ts32); > > > > + ret = SYSCALL_CANCEL (nanosleep, &ts32, &tr32); > > > > + > > > > + if ((ret == 0 || errno != ENOSYS) && remaining) > > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > > + > > > > + return ret; > > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > > +} > > > > + > > > > +#if __TIMESIZE != 64 > > > > +int > > > > __nanosleep (const struct timespec *requested_time, > > > > - struct timespec *remaining) > > > > + struct timespec *remaining) > > > > { > > > > - return SYSCALL_CANCEL (nanosleep, requested_time, remaining); > > > > + int r; > > > > + timespec64 treq64, trem64; > > > > + > > > > + > > > > + valid_timespec_to_timespec64(req, &treq64); > > > > + r = __nanosleep_time64 (&treq64, &trem64); > > > > + > > > > + if (r == 0 || errno != ENOSYS) > > > > + { > > > > + if (! in_time_t_range (trem64->tv_sec)) > > > > + { > > > > + __set_errno (EOVERFLOW); > > > > + return -1; > > > > + } > > > > + > > > > + if (remaining) > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > + } > > > > + > > > > + return r; > > > > } > > > > +#endif > > > > + > > > > hidden_def (__nanosleep) > > > > weak_alias (__nanosleep, nanosleep) > > > > diff --git a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c > > > > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c index > > > > 122ba627ff3..03f5be2ff9e 100644 --- > > > > a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c +++ > > > > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c @@ -20,10 +20,70 @@ > > > > #include <sysdep-cancel.h> > > > > #include <not-cancel.h> > > > > > > > > +int > > > > +__nanosleep_nocancel_time64 (const struct timespec > > > > *requested_time, > > > > + struct timespec *remaining) > > > > +{ > > > > +#ifdef __ASSUME_TIME64_SYSCALLS > > > > +# ifndef __NR_clock_nanosleep_time64 > > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > > +# endif > > > > + return INLINE_SYSCALL_CALL (clock_nanosleep_time64, > > > > CLOCK_REALTIME, 0, > > > > + requested_time, remaining); > > > > +#else > > > > +# ifdef __NR_clock_nanosleep_time64 > > > > + long int ret_64; > > > > + > > > > + ret_64 = INLINE_SYSCALL_CALL (clock_nanosleep_time64, > > > > CLOCK_REALTIME, 0, > > > > + requested_time, remaining); > > > > + > > > > + if (ret_64 == 0 || errno != ENOSYS) > > > > + return ret_64; > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > + int ret; > > > > + struct timespec ts32, tr32; > > > > + > > > > + if (! in_time_t_range (requested_time->tv_sec)) > > > > + { > > > > + __set_errno (EOVERFLOW); > > > > + return -1; > > > > + } > > > > + > > > > + valid_timespec64_to_timespec (requested_time, &ts32); > > > > + ret = INLINE_SYSCALL_CALL (nanosleep, &ts32, &tr32); > > > > + > > > > + if (ret == 0 || errno != ENOSYS) > > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > > + > > > > + return ret; > > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > > +} > > > > + > > > > +#if __TIMESIZE != 64 > > > > int > > > > __nanosleep_nocancel (const struct timespec *requested_time, > > > > - struct timespec *remaining) > > > > + struct timespec *remaining) > > > > { > > > > - return INLINE_SYSCALL_CALL (nanosleep, requested_time, > > > > remaining); > > > > + int ret; > > > > + timespec64 treq64, trem64; > > > > + > > > > + valid_timespec_to_timespec64(req, &treq64) > > > > + ret = __nanosleep_nocancel_time64 (&treq64, &trem64); > > > > + > > > > + if (ret == 0 || errno != ENOSYS) > > > > + { > > > > + if (! in_time_t_range (trem64->tv_sec)) > > > > + { > > > > + __set_errno (EOVERFLOW); > > > > + return -1; > > > > + } > > > > + > > > > + if (remaining) > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > + } > > > > + > > > > + return ret; > > > > } > > > > +#endif > > > > + > > > > hidden_def (__nanosleep_nocancel) > > > > > > > > > > > > > > > Best regards, > > > > > > Lukasz Majewski > > > > > > -- > > > > > > DENX Software Engineering GmbH, Managing Director: Wolfgang > > > Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, > > > Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: > > > lukma@denx.de > > > > > Best regards, > > Lukasz Majewski > > -- > > DENX Software Engineering GmbH, Managing Director: Wolfgang Denk > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On Tue, Oct 15, 2019 at 3:28 PM Alistair Francis <alistair23@gmail.com> wrote: > > On Tue, Oct 15, 2019 at 8:55 AM Lukasz Majewski <lukma@denx.de> wrote: > > > > Hi Alistair, > > > > > On Mon, Oct 14, 2019 at 7:00 AM Lukasz Majewski <lukma@denx.de> wrote: > > > > > > > > Hi Alistair, > > > > > > > > > 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()" > > > > > > > > > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com> > > > > > > > > > > * nptl/thrd_sleep.c: Use clock_nanosleep_time64 instead of > > > > > nanosleep. > > > > > * sysdeps/unix/sysv/linux/nanosleep.c: Likewise. > > > > > * sysdeps/unix/sysv/linux/clock_nanosleep.c: Likewise. > > > > > * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise. > > > > > --- > > > > > include/time.h | 6 ++ > > > > > nptl/thrd_sleep.c | 69 > > > > > ++++++++++++++++-- sysdeps/unix/sysv/linux/clock_nanosleep.c | > > > > > 74 ++++++++++++++++++-- sysdeps/unix/sysv/linux/nanosleep.c > > > > > | 65 ++++++++++++++++- > > > > > sysdeps/unix/sysv/linux/nanosleep_nocancel.c | 64 > > > > > ++++++++++++++++- 5 files changed, 264 insertions(+), 14 > > > > > deletions(-) > > > > > > > > > > diff --git a/include/time.h b/include/time.h > > > > > index 95b31429212..6d81f91384b 100644 > > > > > --- a/include/time.h > > > > > +++ b/include/time.h > > > > > @@ -172,6 +172,12 @@ 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 > > > > > +#endif > > > > > > > > > > /* Use in the clock_* functions. Size of the field representing > > > > > the actual clock ID. */ > > > > > diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c > > > > > index 07a51808df2..e85da561c68 100644 > > > > > --- a/nptl/thrd_sleep.c > > > > > +++ b/nptl/thrd_sleep.c > > > > > @@ -22,18 +22,79 @@ > > > > > #include "thrd_priv.h" > > > > > > > > > > int > > > > > -thrd_sleep (const struct timespec* time_point, struct timespec* > > > > > remaining) +__thrd_sleep_time64 (const struct timespec* > > > > > time_point, struct timespec* remaining) { > > > > > INTERNAL_SYSCALL_DECL (err); > > > > > - int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, > > > > > remaining); > > > > > + int ret = -1; > > > > > + > > > > > +#ifdef __ASSUME_TIME64_SYSCALLS > > > > > +# ifndef __NR_clock_nanosleep_time64 > > > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > > > +# endif > > > > > + ret = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > > > > > CLOCK_REALTIME, > > > > > + 0, time_point, remaining); > > > > > +#else > > > > > +# ifdef __NR_clock_nanosleep_time64 > > > > > + long int ret_64; > > > > > + > > > > > + ret_64 = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > > > > > CLOCK_REALTIME, > > > > > + 0, time_point, remaining); > > > > > + > > > > > + if (ret_64 == 0 || errno != ENOSYS) > > > > > + ret = ret_64; > > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > > + if (ret < 0) > > > > > + { > > > > > + struct timespec tp32, tr32; > > > > > + > > > > > + if (! in_time_t_range (time_point->tv_sec)) > > > > > + { > > > > > + __set_errno (EOVERFLOW); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + valid_timespec64_to_timespec (time_point, &tp32); > > > > > + ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, &tp32, > > > > > &tr32); + > > > > > + if ((ret == 0 || errno != ENOSYS) && remaining) > > > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > > > + } > > > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > > > + > > > > > 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. */ > > > > > + by a signal, or a negative value if it fails. */ > > > > > ret = INTERNAL_SYSCALL_ERRNO (ret, err); > > > > > if (ret == EINTR) > > > > > - return -1; > > > > > + return -1; > > > > > return -2; > > > > > } > > > > > return 0; > > > > > } > > > > > + > > > > > +#if __TIMESIZE != 64 > > > > > +int > > > > > +thrd_sleep (const struct timespec* time_point, struct timespec* > > > > > remaining) +{ > > > > > + int ret; > > > > > + timespec64 tp64, tr64; > > > > > + > > > > > + valid_timespec_to_timespec64(time_point, &tp64); > > > > > + ret = __thrd_sleep_time64 (&tp64, &tr64); > > > > > + > > > > > + if (ret == 0 || errno != ENOSYS) > > > > > + { > > > > > + if (! in_time_t_range (tr64->tv_sec)) > > > > > + { > > > > > + __set_errno (EOVERFLOW); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + if (remaining) > > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > > + } > > > > > + > > > > > + return ret; > > > > > +} > > > > > +#endif > > > > > > > > This code seems to follow the pattern introduced in clock_settime() > > > > conversion (already in the -master branch). > > > > > > I hope so :) > > > > > > > > > > > Do you plan to send this and the following patches: > > > > > > > > https://patchwork.ozlabs.org/patch/1155396/ --> clock_gettime > > > > https://patchwork.ozlabs.org/patch/1155398/ --> timespec_get > > > > > > Yes > > > > > > > > > > > As a separate patch series so we can all benefit from having them in > > > > the -master glibc branch? > > > > Those patches seems to be orthogonal to ones adding support for > > > > RISC-V. > > > > > > Yep! My plan is to send them seperatley. I have been working through > > > the RV32 tree sending patches in small batches to get them merged. I > > > have a few more batches before I get to these time64_t conversion > > > patches though. I am unfortunately seeing failures with my time64_t > > > conversion patches which I haven't had a chance to look into. > > > > > > > > > > > > > > > The gettimeofday() syscall handling code seems to being now > > > > converted to clock_gettime() in the glibc (or at least there is > > > > some ongoing effort): > > > > > > > > https://sourceware.org/git/?p=glibc.git;a=commit;h=b30d257ea8f557bdadca09f5b112538e7b807eb9 > > > > > > > > > > Yep, I have rebased all of my work on top of this. > > > > > > > > > > > Similar situation is with stat and statfs (which are now under the > > > > discussion/review): > > > > > > > > https://patchwork.ozlabs.org/patch/1155399/ --> stat > > > > https://patchwork.ozlabs.org/patch/1155401/ --> statfs > > > > > > Yep, I'm working on the next version right now. > > > > > > If you want you are welcome to split out any patches and get them > > > upstreaed. Even just fixing failing test cases would speed things up. > > > My branch is available here: > > > https://github.com/alistair23/glibc/commits/alistair/rv32.next > > > > > > > Please find some comments and my future work plan: > > > > 1. The "sysdeps/clock_getres: Use inline syscall if required" : > > https://github.com/alistair23/glibc/commit/830707a4a3f662b1a97860afe658f6bbd9731d13 > > commit does not convert this syscall. > > > > However, I can convert and post to the glibc alpha the __clock_getres64 > > (as I already have some older code available). I'm now working on > > preparing proper patch. > > Go for it! :) > > > > > > > 2. Potential compilation error for SoCs with TIMESIZE != 64: > > https://github.com/alistair23/glibc/commit/4309573e10479516fcdf75c353309497f8017c90#diff-85643011757f36e12ca60b37c3e8ec0dR75 > > What is the error? > > > > > > > 3. Would you be so kind and post (to glibc alpha) the already converted > > (in your -next tree) __clock_nanosleep64: > > https://github.com/alistair23/glibc/commit/9e3d95ad1f70909a787dd11fbc735bcafa02050e#diff-5b9f1c6457e0e10079f657f283c19861R177 > > This patch is causing build failures, so I need to investigate that. Ah, there are typos from the rebases. I am updating these and I am sending patches out. Alistair > > > > > Just one remark - please in include/time.h use the following paradigm: > > https://github.com/lmajewski/y2038_glibc/commit/7ff615859f9e111c0c4cf8a6c085201c7ed82813#diff-5b9f1c6457e0e10079f657f283c19861R128 > > Ok, I'll add this. > > Alistair > > > > > for redirection. > > > > > > > Alistair > > > > > > > > > > > > diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c > > > > > b/sysdeps/unix/sysv/linux/clock_nanosleep.c index > > > > > 0cb6614dc92..64302fbcc69 100644 --- > > > > > a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++ > > > > > b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -21,13 +21,14 @@ > > > > > #include <sysdep-cancel.h> > > > > > #include "kernel-posix-cpu-timers.h" > > > > > > > > > > - > > > > > /* 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 timespec *req, > > > > > + struct timespec *rem) > > > > > { > > > > > + int r = -1; > > > > > + > > > > > if (clock_id == CLOCK_THREAD_CPUTIME_ID) > > > > > return EINVAL; > > > > > if (clock_id == CLOCK_PROCESS_CPUTIME_ID) > > > > > @@ -36,9 +37,70 @@ __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) > > > > > + r = ret_64; > > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > > + if (r < 0) > > > > > + { > > > > > + struct timespec ts32, tr32; > > > > > + > > > > > + if (! in_time_t_range (req->tv_sec)) > > > > > + { > > > > > + __set_errno (EOVERFLOW); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + valid_timespec64_to_timespec (req, &ts32); > > > > > + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, &ts32, > > > > > &tr32); + > > > > > + if ((r == 0 || errno != ENOSYS) && rem) > > > > > + valid_timespec_to_timespec64(&tr32, rem); > > > > > + } > > > > > +#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; > > > > > + timespec64 treq64, trem64; > > > > > + > > > > > + valid_timespec_to_timespec64(req, &treq64) > > > > > + r = __clock_nanosleep_time64 (clock_id, flags, &treq64, > > > > > &trem64); + > > > > > + if (r == 0 || errno != ENOSYS) > > > > > + { > > > > > + if (! in_time_t_range (trem64->tv_sec)) > > > > > + { > > > > > + __set_errno (EOVERFLOW); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + if (remaining) > > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > > + } > > > > > + > > > > > + return r; > > > > > +} > > > > > +#endif > > > > > + > > > > > weak_alias (__clock_nanosleep, clock_nanosleep) > > > > > diff --git a/sysdeps/unix/sysv/linux/nanosleep.c > > > > > b/sysdeps/unix/sysv/linux/nanosleep.c index > > > > > f14ae565af5..9a8dd5a4b82 100644 --- > > > > > a/sysdeps/unix/sysv/linux/nanosleep.c +++ > > > > > b/sysdeps/unix/sysv/linux/nanosleep.c @@ -22,10 +22,71 @@ > > > > > > > > > > /* Pause execution for a number of nanoseconds. */ > > > > > int > > > > > +__nanosleep_time64 (const struct timespec *requested_time, > > > > > + struct timespec *remaining) > > > > > +{ > > > > > +#if defined(__ASSUME_TIME64_SYSCALLS) > > > > > +# ifndef __NR_clock_nanosleep_time64 > > > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > > > +# endif > > > > > + return SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, > > > > > 0, > > > > > + requested_time, remaining); > > > > > +#else > > > > > +# ifdef __NR_clock_nanosleep_time64 > > > > > + long int ret_64; > > > > > + > > > > > + ret_64 = SYSCALL_CANCEL (clock_nanosleep_time64, > > > > > CLOCK_REALTIME, 0, > > > > > + requested_time, remaining); > > > > > + > > > > > + if (ret_64 == 0 || errno != ENOSYS) > > > > > + return ret_64; > > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > > + int ret; > > > > > + struct timespec ts32, tr32; > > > > > + > > > > > + if (! in_time_t_range (requested_time->tv_sec)) > > > > > + { > > > > > + __set_errno (EOVERFLOW); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + valid_timespec64_to_timespec (requested_time, &ts32); > > > > > + ret = SYSCALL_CANCEL (nanosleep, &ts32, &tr32); > > > > > + > > > > > + if ((ret == 0 || errno != ENOSYS) && remaining) > > > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > > > + > > > > > + return ret; > > > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > > > +} > > > > > + > > > > > +#if __TIMESIZE != 64 > > > > > +int > > > > > __nanosleep (const struct timespec *requested_time, > > > > > - struct timespec *remaining) > > > > > + struct timespec *remaining) > > > > > { > > > > > - return SYSCALL_CANCEL (nanosleep, requested_time, remaining); > > > > > + int r; > > > > > + timespec64 treq64, trem64; > > > > > + > > > > > + > > > > > + valid_timespec_to_timespec64(req, &treq64); > > > > > + r = __nanosleep_time64 (&treq64, &trem64); > > > > > + > > > > > + if (r == 0 || errno != ENOSYS) > > > > > + { > > > > > + if (! in_time_t_range (trem64->tv_sec)) > > > > > + { > > > > > + __set_errno (EOVERFLOW); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + if (remaining) > > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > > + } > > > > > + > > > > > + return r; > > > > > } > > > > > +#endif > > > > > + > > > > > hidden_def (__nanosleep) > > > > > weak_alias (__nanosleep, nanosleep) > > > > > diff --git a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c > > > > > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c index > > > > > 122ba627ff3..03f5be2ff9e 100644 --- > > > > > a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c +++ > > > > > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c @@ -20,10 +20,70 @@ > > > > > #include <sysdep-cancel.h> > > > > > #include <not-cancel.h> > > > > > > > > > > +int > > > > > +__nanosleep_nocancel_time64 (const struct timespec > > > > > *requested_time, > > > > > + struct timespec *remaining) > > > > > +{ > > > > > +#ifdef __ASSUME_TIME64_SYSCALLS > > > > > +# ifndef __NR_clock_nanosleep_time64 > > > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > > > +# endif > > > > > + return INLINE_SYSCALL_CALL (clock_nanosleep_time64, > > > > > CLOCK_REALTIME, 0, > > > > > + requested_time, remaining); > > > > > +#else > > > > > +# ifdef __NR_clock_nanosleep_time64 > > > > > + long int ret_64; > > > > > + > > > > > + ret_64 = INLINE_SYSCALL_CALL (clock_nanosleep_time64, > > > > > CLOCK_REALTIME, 0, > > > > > + requested_time, remaining); > > > > > + > > > > > + if (ret_64 == 0 || errno != ENOSYS) > > > > > + return ret_64; > > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > > + int ret; > > > > > + struct timespec ts32, tr32; > > > > > + > > > > > + if (! in_time_t_range (requested_time->tv_sec)) > > > > > + { > > > > > + __set_errno (EOVERFLOW); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + valid_timespec64_to_timespec (requested_time, &ts32); > > > > > + ret = INLINE_SYSCALL_CALL (nanosleep, &ts32, &tr32); > > > > > + > > > > > + if (ret == 0 || errno != ENOSYS) > > > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > > > + > > > > > + return ret; > > > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > > > +} > > > > > + > > > > > +#if __TIMESIZE != 64 > > > > > int > > > > > __nanosleep_nocancel (const struct timespec *requested_time, > > > > > - struct timespec *remaining) > > > > > + struct timespec *remaining) > > > > > { > > > > > - return INLINE_SYSCALL_CALL (nanosleep, requested_time, > > > > > remaining); > > > > > + int ret; > > > > > + timespec64 treq64, trem64; > > > > > + > > > > > + valid_timespec_to_timespec64(req, &treq64) > > > > > + ret = __nanosleep_nocancel_time64 (&treq64, &trem64); > > > > > + > > > > > + if (ret == 0 || errno != ENOSYS) > > > > > + { > > > > > + if (! in_time_t_range (trem64->tv_sec)) > > > > > + { > > > > > + __set_errno (EOVERFLOW); > > > > > + return -1; > > > > > + } > > > > > + > > > > > + if (remaining) > > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > > + } > > > > > + > > > > > + return ret; > > > > > } > > > > > +#endif > > > > > + > > > > > hidden_def (__nanosleep_nocancel) > > > > > > > > > > > > > > > > > > > > Best regards, > > > > > > > > Lukasz Majewski > > > > > > > > -- > > > > > > > > DENX Software Engineering GmbH, Managing Director: Wolfgang > > > > Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, > > > > Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: > > > > lukma@denx.de > > > > > > > > > > Best regards, > > > > Lukasz Majewski > > > > -- > > > > DENX Software Engineering GmbH, Managing Director: Wolfgang Denk > > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > > Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On Wed, Oct 16, 2019 at 4:42 PM Alistair Francis <alistair23@gmail.com> wrote: > > On Tue, Oct 15, 2019 at 3:28 PM Alistair Francis <alistair23@gmail.com> wrote: > > > > On Tue, Oct 15, 2019 at 8:55 AM Lukasz Majewski <lukma@denx.de> wrote: > > > > > > Hi Alistair, > > > > > > > On Mon, Oct 14, 2019 at 7:00 AM Lukasz Majewski <lukma@denx.de> wrote: > > > > > > > > > > Hi Alistair, > > > > > > > > > > > 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()" > > > > > > > > > > > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com> > > > > > > > > > > > > * nptl/thrd_sleep.c: Use clock_nanosleep_time64 instead of > > > > > > nanosleep. > > > > > > * sysdeps/unix/sysv/linux/nanosleep.c: Likewise. > > > > > > * sysdeps/unix/sysv/linux/clock_nanosleep.c: Likewise. > > > > > > * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise. > > > > > > --- > > > > > > include/time.h | 6 ++ > > > > > > nptl/thrd_sleep.c | 69 > > > > > > ++++++++++++++++-- sysdeps/unix/sysv/linux/clock_nanosleep.c | > > > > > > 74 ++++++++++++++++++-- sysdeps/unix/sysv/linux/nanosleep.c > > > > > > | 65 ++++++++++++++++- > > > > > > sysdeps/unix/sysv/linux/nanosleep_nocancel.c | 64 > > > > > > ++++++++++++++++- 5 files changed, 264 insertions(+), 14 > > > > > > deletions(-) > > > > > > > > > > > > diff --git a/include/time.h b/include/time.h > > > > > > index 95b31429212..6d81f91384b 100644 > > > > > > --- a/include/time.h > > > > > > +++ b/include/time.h > > > > > > @@ -172,6 +172,12 @@ 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 > > > > > > +#endif > > > > > > > > > > > > /* Use in the clock_* functions. Size of the field representing > > > > > > the actual clock ID. */ > > > > > > diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c > > > > > > index 07a51808df2..e85da561c68 100644 > > > > > > --- a/nptl/thrd_sleep.c > > > > > > +++ b/nptl/thrd_sleep.c > > > > > > @@ -22,18 +22,79 @@ > > > > > > #include "thrd_priv.h" > > > > > > > > > > > > int > > > > > > -thrd_sleep (const struct timespec* time_point, struct timespec* > > > > > > remaining) +__thrd_sleep_time64 (const struct timespec* > > > > > > time_point, struct timespec* remaining) { > > > > > > INTERNAL_SYSCALL_DECL (err); > > > > > > - int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, > > > > > > remaining); > > > > > > + int ret = -1; > > > > > > + > > > > > > +#ifdef __ASSUME_TIME64_SYSCALLS > > > > > > +# ifndef __NR_clock_nanosleep_time64 > > > > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > > > > +# endif > > > > > > + ret = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > > > > > > CLOCK_REALTIME, > > > > > > + 0, time_point, remaining); > > > > > > +#else > > > > > > +# ifdef __NR_clock_nanosleep_time64 > > > > > > + long int ret_64; > > > > > > + > > > > > > + ret_64 = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, > > > > > > CLOCK_REALTIME, > > > > > > + 0, time_point, remaining); > > > > > > + > > > > > > + if (ret_64 == 0 || errno != ENOSYS) > > > > > > + ret = ret_64; > > > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > > > + if (ret < 0) > > > > > > + { > > > > > > + struct timespec tp32, tr32; > > > > > > + > > > > > > + if (! in_time_t_range (time_point->tv_sec)) > > > > > > + { > > > > > > + __set_errno (EOVERFLOW); > > > > > > + return -1; > > > > > > + } > > > > > > + > > > > > > + valid_timespec64_to_timespec (time_point, &tp32); > > > > > > + ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, &tp32, > > > > > > &tr32); + > > > > > > + if ((ret == 0 || errno != ENOSYS) && remaining) > > > > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > > > > + } > > > > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > > > > + > > > > > > 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. */ > > > > > > + by a signal, or a negative value if it fails. */ > > > > > > ret = INTERNAL_SYSCALL_ERRNO (ret, err); > > > > > > if (ret == EINTR) > > > > > > - return -1; > > > > > > + return -1; > > > > > > return -2; > > > > > > } > > > > > > return 0; > > > > > > } > > > > > > + > > > > > > +#if __TIMESIZE != 64 > > > > > > +int > > > > > > +thrd_sleep (const struct timespec* time_point, struct timespec* > > > > > > remaining) +{ > > > > > > + int ret; > > > > > > + timespec64 tp64, tr64; > > > > > > + > > > > > > + valid_timespec_to_timespec64(time_point, &tp64); > > > > > > + ret = __thrd_sleep_time64 (&tp64, &tr64); > > > > > > + > > > > > > + if (ret == 0 || errno != ENOSYS) > > > > > > + { > > > > > > + if (! in_time_t_range (tr64->tv_sec)) > > > > > > + { > > > > > > + __set_errno (EOVERFLOW); > > > > > > + return -1; > > > > > > + } > > > > > > + > > > > > > + if (remaining) > > > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > > > + } > > > > > > + > > > > > > + return ret; > > > > > > +} > > > > > > +#endif > > > > > > > > > > This code seems to follow the pattern introduced in clock_settime() > > > > > conversion (already in the -master branch). > > > > > > > > I hope so :) > > > > > > > > > > > > > > Do you plan to send this and the following patches: > > > > > > > > > > https://patchwork.ozlabs.org/patch/1155396/ --> clock_gettime > > > > > https://patchwork.ozlabs.org/patch/1155398/ --> timespec_get > > > > > > > > Yes > > > > > > > > > > > > > > As a separate patch series so we can all benefit from having them in > > > > > the -master glibc branch? > > > > > Those patches seems to be orthogonal to ones adding support for > > > > > RISC-V. > > > > > > > > Yep! My plan is to send them seperatley. I have been working through > > > > the RV32 tree sending patches in small batches to get them merged. I > > > > have a few more batches before I get to these time64_t conversion > > > > patches though. I am unfortunately seeing failures with my time64_t > > > > conversion patches which I haven't had a chance to look into. > > > > > > > > > > > > > > > > > > > The gettimeofday() syscall handling code seems to being now > > > > > converted to clock_gettime() in the glibc (or at least there is > > > > > some ongoing effort): > > > > > > > > > > https://sourceware.org/git/?p=glibc.git;a=commit;h=b30d257ea8f557bdadca09f5b112538e7b807eb9 > > > > > > > > > > > > > Yep, I have rebased all of my work on top of this. > > > > > > > > > > > > > > Similar situation is with stat and statfs (which are now under the > > > > > discussion/review): > > > > > > > > > > https://patchwork.ozlabs.org/patch/1155399/ --> stat > > > > > https://patchwork.ozlabs.org/patch/1155401/ --> statfs > > > > > > > > Yep, I'm working on the next version right now. > > > > > > > > If you want you are welcome to split out any patches and get them > > > > upstreaed. Even just fixing failing test cases would speed things up. > > > > My branch is available here: > > > > https://github.com/alistair23/glibc/commits/alistair/rv32.next > > > > > > > > > > Please find some comments and my future work plan: > > > > > > 1. The "sysdeps/clock_getres: Use inline syscall if required" : > > > https://github.com/alistair23/glibc/commit/830707a4a3f662b1a97860afe658f6bbd9731d13 > > > commit does not convert this syscall. > > > > > > However, I can convert and post to the glibc alpha the __clock_getres64 > > > (as I already have some older code available). I'm now working on > > > preparing proper patch. > > > > Go for it! :) > > > > > > > > > > > 2. Potential compilation error for SoCs with TIMESIZE != 64: > > > https://github.com/alistair23/glibc/commit/4309573e10479516fcdf75c353309497f8017c90#diff-85643011757f36e12ca60b37c3e8ec0dR75 > > > > What is the error? > > > > > > > > > > > 3. Would you be so kind and post (to glibc alpha) the already converted > > > (in your -next tree) __clock_nanosleep64: > > > https://github.com/alistair23/glibc/commit/9e3d95ad1f70909a787dd11fbc735bcafa02050e#diff-5b9f1c6457e0e10079f657f283c19861R177 > > > > This patch is causing build failures, so I need to investigate that. > > Ah, there are typos from the rebases. I am updating these and I am > sending patches out. Do you have plans on adding a __timevalue64 struct? Alistair > > Alistair > > > > > > > > > Just one remark - please in include/time.h use the following paradigm: > > > https://github.com/lmajewski/y2038_glibc/commit/7ff615859f9e111c0c4cf8a6c085201c7ed82813#diff-5b9f1c6457e0e10079f657f283c19861R128 > > > > Ok, I'll add this. > > > > Alistair > > > > > > > > for redirection. > > > > > > > > > > Alistair > > > > > > > > > > > > > > > diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c > > > > > > b/sysdeps/unix/sysv/linux/clock_nanosleep.c index > > > > > > 0cb6614dc92..64302fbcc69 100644 --- > > > > > > a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++ > > > > > > b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -21,13 +21,14 @@ > > > > > > #include <sysdep-cancel.h> > > > > > > #include "kernel-posix-cpu-timers.h" > > > > > > > > > > > > - > > > > > > /* 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 timespec *req, > > > > > > + struct timespec *rem) > > > > > > { > > > > > > + int r = -1; > > > > > > + > > > > > > if (clock_id == CLOCK_THREAD_CPUTIME_ID) > > > > > > return EINVAL; > > > > > > if (clock_id == CLOCK_PROCESS_CPUTIME_ID) > > > > > > @@ -36,9 +37,70 @@ __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) > > > > > > + r = ret_64; > > > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > > > + if (r < 0) > > > > > > + { > > > > > > + struct timespec ts32, tr32; > > > > > > + > > > > > > + if (! in_time_t_range (req->tv_sec)) > > > > > > + { > > > > > > + __set_errno (EOVERFLOW); > > > > > > + return -1; > > > > > > + } > > > > > > + > > > > > > + valid_timespec64_to_timespec (req, &ts32); > > > > > > + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, &ts32, > > > > > > &tr32); + > > > > > > + if ((r == 0 || errno != ENOSYS) && rem) > > > > > > + valid_timespec_to_timespec64(&tr32, rem); > > > > > > + } > > > > > > +#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; > > > > > > + timespec64 treq64, trem64; > > > > > > + > > > > > > + valid_timespec_to_timespec64(req, &treq64) > > > > > > + r = __clock_nanosleep_time64 (clock_id, flags, &treq64, > > > > > > &trem64); + > > > > > > + if (r == 0 || errno != ENOSYS) > > > > > > + { > > > > > > + if (! in_time_t_range (trem64->tv_sec)) > > > > > > + { > > > > > > + __set_errno (EOVERFLOW); > > > > > > + return -1; > > > > > > + } > > > > > > + > > > > > > + if (remaining) > > > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > > > + } > > > > > > + > > > > > > + return r; > > > > > > +} > > > > > > +#endif > > > > > > + > > > > > > weak_alias (__clock_nanosleep, clock_nanosleep) > > > > > > diff --git a/sysdeps/unix/sysv/linux/nanosleep.c > > > > > > b/sysdeps/unix/sysv/linux/nanosleep.c index > > > > > > f14ae565af5..9a8dd5a4b82 100644 --- > > > > > > a/sysdeps/unix/sysv/linux/nanosleep.c +++ > > > > > > b/sysdeps/unix/sysv/linux/nanosleep.c @@ -22,10 +22,71 @@ > > > > > > > > > > > > /* Pause execution for a number of nanoseconds. */ > > > > > > int > > > > > > +__nanosleep_time64 (const struct timespec *requested_time, > > > > > > + struct timespec *remaining) > > > > > > +{ > > > > > > +#if defined(__ASSUME_TIME64_SYSCALLS) > > > > > > +# ifndef __NR_clock_nanosleep_time64 > > > > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > > > > +# endif > > > > > > + return SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, > > > > > > 0, > > > > > > + requested_time, remaining); > > > > > > +#else > > > > > > +# ifdef __NR_clock_nanosleep_time64 > > > > > > + long int ret_64; > > > > > > + > > > > > > + ret_64 = SYSCALL_CANCEL (clock_nanosleep_time64, > > > > > > CLOCK_REALTIME, 0, > > > > > > + requested_time, remaining); > > > > > > + > > > > > > + if (ret_64 == 0 || errno != ENOSYS) > > > > > > + return ret_64; > > > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > > > + int ret; > > > > > > + struct timespec ts32, tr32; > > > > > > + > > > > > > + if (! in_time_t_range (requested_time->tv_sec)) > > > > > > + { > > > > > > + __set_errno (EOVERFLOW); > > > > > > + return -1; > > > > > > + } > > > > > > + > > > > > > + valid_timespec64_to_timespec (requested_time, &ts32); > > > > > > + ret = SYSCALL_CANCEL (nanosleep, &ts32, &tr32); > > > > > > + > > > > > > + if ((ret == 0 || errno != ENOSYS) && remaining) > > > > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > > > > + > > > > > > + return ret; > > > > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > > > > +} > > > > > > + > > > > > > +#if __TIMESIZE != 64 > > > > > > +int > > > > > > __nanosleep (const struct timespec *requested_time, > > > > > > - struct timespec *remaining) > > > > > > + struct timespec *remaining) > > > > > > { > > > > > > - return SYSCALL_CANCEL (nanosleep, requested_time, remaining); > > > > > > + int r; > > > > > > + timespec64 treq64, trem64; > > > > > > + > > > > > > + > > > > > > + valid_timespec_to_timespec64(req, &treq64); > > > > > > + r = __nanosleep_time64 (&treq64, &trem64); > > > > > > + > > > > > > + if (r == 0 || errno != ENOSYS) > > > > > > + { > > > > > > + if (! in_time_t_range (trem64->tv_sec)) > > > > > > + { > > > > > > + __set_errno (EOVERFLOW); > > > > > > + return -1; > > > > > > + } > > > > > > + > > > > > > + if (remaining) > > > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > > > + } > > > > > > + > > > > > > + return r; > > > > > > } > > > > > > +#endif > > > > > > + > > > > > > hidden_def (__nanosleep) > > > > > > weak_alias (__nanosleep, nanosleep) > > > > > > diff --git a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c > > > > > > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c index > > > > > > 122ba627ff3..03f5be2ff9e 100644 --- > > > > > > a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c +++ > > > > > > b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c @@ -20,10 +20,70 @@ > > > > > > #include <sysdep-cancel.h> > > > > > > #include <not-cancel.h> > > > > > > > > > > > > +int > > > > > > +__nanosleep_nocancel_time64 (const struct timespec > > > > > > *requested_time, > > > > > > + struct timespec *remaining) > > > > > > +{ > > > > > > +#ifdef __ASSUME_TIME64_SYSCALLS > > > > > > +# ifndef __NR_clock_nanosleep_time64 > > > > > > +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep > > > > > > +# endif > > > > > > + return INLINE_SYSCALL_CALL (clock_nanosleep_time64, > > > > > > CLOCK_REALTIME, 0, > > > > > > + requested_time, remaining); > > > > > > +#else > > > > > > +# ifdef __NR_clock_nanosleep_time64 > > > > > > + long int ret_64; > > > > > > + > > > > > > + ret_64 = INLINE_SYSCALL_CALL (clock_nanosleep_time64, > > > > > > CLOCK_REALTIME, 0, > > > > > > + requested_time, remaining); > > > > > > + > > > > > > + if (ret_64 == 0 || errno != ENOSYS) > > > > > > + return ret_64; > > > > > > +# endif /* __NR_clock_nanosleep_time64 */ > > > > > > + int ret; > > > > > > + struct timespec ts32, tr32; > > > > > > + > > > > > > + if (! in_time_t_range (requested_time->tv_sec)) > > > > > > + { > > > > > > + __set_errno (EOVERFLOW); > > > > > > + return -1; > > > > > > + } > > > > > > + > > > > > > + valid_timespec64_to_timespec (requested_time, &ts32); > > > > > > + ret = INLINE_SYSCALL_CALL (nanosleep, &ts32, &tr32); > > > > > > + > > > > > > + if (ret == 0 || errno != ENOSYS) > > > > > > + valid_timespec_to_timespec64(&tr32, remaining); > > > > > > + > > > > > > + return ret; > > > > > > +#endif /* __ASSUME_TIME64_SYSCALLS */ > > > > > > +} > > > > > > + > > > > > > +#if __TIMESIZE != 64 > > > > > > int > > > > > > __nanosleep_nocancel (const struct timespec *requested_time, > > > > > > - struct timespec *remaining) > > > > > > + struct timespec *remaining) > > > > > > { > > > > > > - return INLINE_SYSCALL_CALL (nanosleep, requested_time, > > > > > > remaining); > > > > > > + int ret; > > > > > > + timespec64 treq64, trem64; > > > > > > + > > > > > > + valid_timespec_to_timespec64(req, &treq64) > > > > > > + ret = __nanosleep_nocancel_time64 (&treq64, &trem64); > > > > > > + > > > > > > + if (ret == 0 || errno != ENOSYS) > > > > > > + { > > > > > > + if (! in_time_t_range (trem64->tv_sec)) > > > > > > + { > > > > > > + __set_errno (EOVERFLOW); > > > > > > + return -1; > > > > > > + } > > > > > > + > > > > > > + if (remaining) > > > > > > + valid_timespec64_to_timespec(&tr32, remaining); > > > > > > + } > > > > > > + > > > > > > + return ret; > > > > > > } > > > > > > +#endif > > > > > > + > > > > > > hidden_def (__nanosleep_nocancel) > > > > > > > > > > > > > > > > > > > > > > > > > Best regards, > > > > > > > > > > Lukasz Majewski > > > > > > > > > > -- > > > > > > > > > > DENX Software Engineering GmbH, Managing Director: Wolfgang > > > > > Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, > > > > > Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: > > > > > lukma@denx.de > > > > > > > > > > > > > > > Best regards, > > > > > > Lukasz Majewski > > > > > > -- > > > > > > DENX Software Engineering GmbH, Managing Director: Wolfgang Denk > > > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > > > Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
diff --git a/include/time.h b/include/time.h index 95b31429212..6d81f91384b 100644 --- a/include/time.h +++ b/include/time.h @@ -172,6 +172,12 @@ 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 +#endif /* Use in the clock_* functions. Size of the field representing the actual clock ID. */ diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c index 07a51808df2..e85da561c68 100644 --- a/nptl/thrd_sleep.c +++ b/nptl/thrd_sleep.c @@ -22,18 +22,79 @@ #include "thrd_priv.h" int -thrd_sleep (const struct timespec* time_point, struct timespec* remaining) +__thrd_sleep_time64 (const struct timespec* time_point, struct timespec* remaining) { INTERNAL_SYSCALL_DECL (err); - int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, remaining); + int ret = -1; + +#ifdef __ASSUME_TIME64_SYSCALLS +# ifndef __NR_clock_nanosleep_time64 +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep +# endif + ret = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, CLOCK_REALTIME, + 0, time_point, remaining); +#else +# ifdef __NR_clock_nanosleep_time64 + long int ret_64; + + ret_64 = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, CLOCK_REALTIME, + 0, time_point, remaining); + + if (ret_64 == 0 || errno != ENOSYS) + ret = ret_64; +# endif /* __NR_clock_nanosleep_time64 */ + if (ret < 0) + { + struct timespec tp32, tr32; + + if (! in_time_t_range (time_point->tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + valid_timespec64_to_timespec (time_point, &tp32); + ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, &tp32, &tr32); + + if ((ret == 0 || errno != ENOSYS) && remaining) + valid_timespec_to_timespec64(&tr32, remaining); + } +#endif /* __ASSUME_TIME64_SYSCALLS */ + 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. */ + by a signal, or a negative value if it fails. */ ret = INTERNAL_SYSCALL_ERRNO (ret, err); if (ret == EINTR) - return -1; + return -1; return -2; } return 0; } + +#if __TIMESIZE != 64 +int +thrd_sleep (const struct timespec* time_point, struct timespec* remaining) +{ + int ret; + timespec64 tp64, tr64; + + valid_timespec_to_timespec64(time_point, &tp64); + ret = __thrd_sleep_time64 (&tp64, &tr64); + + if (ret == 0 || errno != ENOSYS) + { + if (! in_time_t_range (tr64->tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + if (remaining) + valid_timespec64_to_timespec(&tr32, remaining); + } + + return ret; +} +#endif diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c index 0cb6614dc92..64302fbcc69 100644 --- a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -21,13 +21,14 @@ #include <sysdep-cancel.h> #include "kernel-posix-cpu-timers.h" - /* 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 timespec *req, + struct timespec *rem) { + int r = -1; + if (clock_id == CLOCK_THREAD_CPUTIME_ID) return EINVAL; if (clock_id == CLOCK_PROCESS_CPUTIME_ID) @@ -36,9 +37,70 @@ __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) + r = ret_64; +# endif /* __NR_clock_nanosleep_time64 */ + if (r < 0) + { + struct timespec ts32, tr32; + + if (! in_time_t_range (req->tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + valid_timespec64_to_timespec (req, &ts32); + r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, &ts32, &tr32); + + if ((r == 0 || errno != ENOSYS) && rem) + valid_timespec_to_timespec64(&tr32, rem); + } +#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; + timespec64 treq64, trem64; + + valid_timespec_to_timespec64(req, &treq64) + r = __clock_nanosleep_time64 (clock_id, flags, &treq64, &trem64); + + if (r == 0 || errno != ENOSYS) + { + if (! in_time_t_range (trem64->tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + if (remaining) + valid_timespec64_to_timespec(&tr32, remaining); + } + + return r; +} +#endif + weak_alias (__clock_nanosleep, clock_nanosleep) diff --git a/sysdeps/unix/sysv/linux/nanosleep.c b/sysdeps/unix/sysv/linux/nanosleep.c index f14ae565af5..9a8dd5a4b82 100644 --- a/sysdeps/unix/sysv/linux/nanosleep.c +++ b/sysdeps/unix/sysv/linux/nanosleep.c @@ -22,10 +22,71 @@ /* Pause execution for a number of nanoseconds. */ int +__nanosleep_time64 (const struct timespec *requested_time, + struct timespec *remaining) +{ +#if defined(__ASSUME_TIME64_SYSCALLS) +# ifndef __NR_clock_nanosleep_time64 +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep +# endif + return SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, 0, + requested_time, remaining); +#else +# ifdef __NR_clock_nanosleep_time64 + long int ret_64; + + ret_64 = SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, 0, + requested_time, remaining); + + if (ret_64 == 0 || errno != ENOSYS) + return ret_64; +# endif /* __NR_clock_nanosleep_time64 */ + int ret; + struct timespec ts32, tr32; + + if (! in_time_t_range (requested_time->tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + valid_timespec64_to_timespec (requested_time, &ts32); + ret = SYSCALL_CANCEL (nanosleep, &ts32, &tr32); + + if ((ret == 0 || errno != ENOSYS) && remaining) + valid_timespec_to_timespec64(&tr32, remaining); + + return ret; +#endif /* __ASSUME_TIME64_SYSCALLS */ +} + +#if __TIMESIZE != 64 +int __nanosleep (const struct timespec *requested_time, - struct timespec *remaining) + struct timespec *remaining) { - return SYSCALL_CANCEL (nanosleep, requested_time, remaining); + int r; + timespec64 treq64, trem64; + + + valid_timespec_to_timespec64(req, &treq64); + r = __nanosleep_time64 (&treq64, &trem64); + + if (r == 0 || errno != ENOSYS) + { + if (! in_time_t_range (trem64->tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + if (remaining) + valid_timespec64_to_timespec(&tr32, remaining); + } + + return r; } +#endif + hidden_def (__nanosleep) weak_alias (__nanosleep, nanosleep) diff --git a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c index 122ba627ff3..03f5be2ff9e 100644 --- a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c +++ b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c @@ -20,10 +20,70 @@ #include <sysdep-cancel.h> #include <not-cancel.h> +int +__nanosleep_nocancel_time64 (const struct timespec *requested_time, + struct timespec *remaining) +{ +#ifdef __ASSUME_TIME64_SYSCALLS +# ifndef __NR_clock_nanosleep_time64 +# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep +# endif + return INLINE_SYSCALL_CALL (clock_nanosleep_time64, CLOCK_REALTIME, 0, + requested_time, remaining); +#else +# ifdef __NR_clock_nanosleep_time64 + long int ret_64; + + ret_64 = INLINE_SYSCALL_CALL (clock_nanosleep_time64, CLOCK_REALTIME, 0, + requested_time, remaining); + + if (ret_64 == 0 || errno != ENOSYS) + return ret_64; +# endif /* __NR_clock_nanosleep_time64 */ + int ret; + struct timespec ts32, tr32; + + if (! in_time_t_range (requested_time->tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + valid_timespec64_to_timespec (requested_time, &ts32); + ret = INLINE_SYSCALL_CALL (nanosleep, &ts32, &tr32); + + if (ret == 0 || errno != ENOSYS) + valid_timespec_to_timespec64(&tr32, remaining); + + return ret; +#endif /* __ASSUME_TIME64_SYSCALLS */ +} + +#if __TIMESIZE != 64 int __nanosleep_nocancel (const struct timespec *requested_time, - struct timespec *remaining) + struct timespec *remaining) { - return INLINE_SYSCALL_CALL (nanosleep, requested_time, remaining); + int ret; + timespec64 treq64, trem64; + + valid_timespec_to_timespec64(req, &treq64) + ret = __nanosleep_nocancel_time64 (&treq64, &trem64); + + if (ret == 0 || errno != ENOSYS) + { + if (! in_time_t_range (trem64->tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + if (remaining) + valid_timespec64_to_timespec(&tr32, remaining); + } + + return ret; } +#endif + hidden_def (__nanosleep_nocancel)