This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RFC v3 01/23] sysdeps/nanosleep: Use clock_nanosleep_time64 if avaliable
- From: Alistair Francis <alistair dot francis at wdc dot com>
- To: libc-alpha at sourceware dot org
- Cc: arnd at arndb dot de, adhemerval dot zanella at linaro dot org, fweimer at redhat dot com, palmer at sifive dot com, macro at wdc dot com, zongbox at gmail dot com, alistair dot francis at wdc dot com, alistair23 at gmail dot com
- Date: Tue, 16 Jul 2019 17:08:43 -0700
- Subject: [RFC v3 01/23] sysdeps/nanosleep: Use clock_nanosleep_time64 if avaliable
- Ironport-sdr: pNX1HFqDOgCVMqihFd40AElSNa35zdySPqe3N8n8mI0uuX4KzNZwoQhWNVcy/rAymdIL2WjCkI EOCOH/aDSK508bikIzxZp5lhCoEraj/K4d4iTUsYqgNYVTZ2dMzcuFV5JOpUwb0T5nh1Fg1yme cZICq3sdXkq6C/si6VhrJm6f9TD5fK+9r1Adsmf6JWTp88z4sat9l2/WmyXosykr1iNAJZ+fzs 16ks3HlvxTZq7ljNyB1XTOmznsK8cHnLxEdPX5Q0P5zqySybgUo2A3xI32YfL9MNm4I96127sD 8tY=
- Ironport-sdr: 6rtPU0S3+ZOg3Q94WXHyfPtpdXM8beXu5trBjR44Fg7IPzzICEOyTt9MwxlYR+VJ/mop//7Wm8 467Z9JnpvJai7jtvRz9DaDhc2Hl0ATNg5O6IguP1jYXZEI9HPqUR9sseqX5NQtLQJE3MLb9Myb O5YQDbecocQ6wJn2Cg5wAwDKYZE4ppWKkHh6IHqNwPWmEtWh6MtlOzOxPmAIaizXuAKBN4qZpi 26WOqNLjR+4haFpw4QZFsYYe8UESOq+03JPLwAFZMm5/n530k6atCZoUgCDkBFmpz01KVcqGMS wdC6MD3aPA+0AYqbUhf3xUFy
- Ironport-sdr: qVDLEMOUSy9JMbTwf5dQkwGBhTsceKUWSPBSaPDnih6s20e8fdhiktf5Fl9O/F2SHJEdXsFQOG I1SIsGWYNMJuPeTCSbSRupAL2BTS6/O5VvI6t3er+Tt4IaB2KcwQpQmxImt9GgmWj/4uB7x/1L /g6/uXPHOYRbqvFgdWZFTZktyW4oED5eaYGLurjzto+9YMmYur0WwVSzkAcipGzWsXBRk2iNf3 OvIcJuszN4VXbvi3NRCxZo3txEjDfFXzIIi5OwhuoxQA0Eq2pfEs1lmRXoGhPQ3NFoDV2NCmBh XKo=
- References: <cover.1563321715.git.alistair.francis@wdc.com>
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>
---
ChangeLog | 6 +++
nptl/thrd_sleep.c | 41 +++++++++++++++-
sysdeps/unix/sysv/linux/clock_nanosleep.c | 42 +++++++++++++++-
sysdeps/unix/sysv/linux/nanosleep.c | 50 ++++++++++++++++++++
sysdeps/unix/sysv/linux/nanosleep_nocancel.c | 11 +++++
5 files changed, 147 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index bd57a815b0..477b9b49b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1023,6 +1023,12 @@
* support/xtime.h: Add xclock_now() helper function.
+2019-06-21 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/nanosleep_nocancel.c: Likewise.
+
2019-06-20 Dmitry V. Levin <ldv@altlinux.org>
Florian Weimer <fweimer@redhat.com>
diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c
index 07a51808df..e7873a7170 100644
--- a/nptl/thrd_sleep.c
+++ b/nptl/thrd_sleep.c
@@ -21,11 +21,50 @@
#include "thrd_priv.h"
+#if __TIMESIZE == 32
+struct timespec64
+{
+ long int tv_sec; /* Seconds. */
+ long int tv_nsec; /* Nanoseconds. */
+};
+#endif
+
int
thrd_sleep (const struct timespec* time_point, struct timespec* remaining)
{
INTERNAL_SYSCALL_DECL (err);
- int ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, remaining);
+ int ret;
+
+#ifdef __ASSUME_TIME64_SYSCALLS
+ ret = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, CLOCK_REALTIME,
+ 0, time_point, remaining);
+#else
+# ifdef __NR_clock_nanosleep_time64
+# if __TIMESIZE == 64
+ 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;
+# else
+ timespec64 ts;
+
+ ret = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err,
+ CLOCK_REALTIME, 0, time_point,
+ ts);
+
+ if (ret == 0 || errno != ENOSYS) {
+ remaining->tv_sec = ts.tv_sec;
+ remaining->tv_nsec = ts.tv_nsec;
+ return ret;
+ }
+# endif
+# endif
+ ret = INTERNAL_SYSCALL_CANCEL (nanosleep, err, time_point, remaining);
+#endif
+
if (INTERNAL_SYSCALL_ERROR_P (ret, err))
{
/* C11 states thrd_sleep function returns -1 if it has been interrupted
diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c
index 0cb6614dc9..84bd5f8afc 100644
--- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
+++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
@@ -21,6 +21,13 @@
#include <sysdep-cancel.h>
#include "kernel-posix-cpu-timers.h"
+#if __TIMESIZE == 32
+struct timespec64
+{
+ long int tv_sec; /* Seconds. */
+ long int tv_nsec; /* Nanoseconds. */
+};
+#endif
/* We can simply use the syscall. The CPU clocks are not supported
with this function. */
@@ -28,6 +35,8 @@ int
__clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
struct timespec *rem)
{
+ int r;
+
if (clock_id == CLOCK_THREAD_CPUTIME_ID)
return EINVAL;
if (clock_id == CLOCK_PROCESS_CPUTIME_ID)
@@ -36,8 +45,37 @@ __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
+ r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err, clock_id,
+ flags, req, rem);
+#else
+# ifdef __NR_clock_nanosleep_time64
+# if __TIMESIZE == 64
+ 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;
+# else
+ timespec64 ts;
+
+ r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, err,
+ clock_id, flags, req,
+ ts);
+
+ if (r == 0 || errno != ENOSYS) {
+ rem->tv_sec = ts.tv_sec;
+ rem->tv_nsec = ts.tv_nsec;
+ return r;
+ }
+# endif
+# endif
+ r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep, err, req, rem);
+#endif
+
return (INTERNAL_SYSCALL_ERROR_P (r, err)
? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
}
diff --git a/sysdeps/unix/sysv/linux/nanosleep.c b/sysdeps/unix/sysv/linux/nanosleep.c
index f14ae565af..0c54f21e07 100644
--- a/sysdeps/unix/sysv/linux/nanosleep.c
+++ b/sysdeps/unix/sysv/linux/nanosleep.c
@@ -20,12 +20,62 @@
#include <sysdep-cancel.h>
#include <not-cancel.h>
+#if defined(__ASSUME_TIME64_SYSCALLS) || defined(__NR_clock_nanosleep_time64)
+static int
+__nanosleep_time64_64 (const struct timespec *requested_time,
+ struct timespec *remaining)
+{
+ return SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, 0,
+ requested_time, remaining);
+}
+
+#if __TIMESIZE == 32
+struct timespec64
+{
+ long int tv_sec; /* Seconds. */
+ long int tv_nsec; /* Nanoseconds. */
+};
+
+static int
+__nanosleep_time64_32 (const struct timespec *requested_time,
+ struct timespec *remaining)
+{
+ timespec64 ts;
+
+ long int ret = SYSCALL_CANCEL (clock_nanosleep_time64, CLOCK_REALTIME, 0,
+ requested_time, &ts);
+
+ remaining->tv_sec = ts.tv_sec;
+ remaining->tv_nsec = ts.tv_nsec;
+
+ return ret;
+}
+#endif
+#endif
+
/* Pause execution for a number of nanoseconds. */
int
__nanosleep (const struct timespec *requested_time,
struct timespec *remaining)
{
+#ifdef __ASSUME_TIME64_SYSCALLS
+ return __nanosleep_time64_64 (requested_time, remaining);
+#else
+# ifdef __NR_clock_nanosleep_time64
+# if __TIMESIZE == 64
+ long int ret = __nanosleep_time64_64 (requested_time, remaining);
+
+ if (ret == 0 || errno != ENOSYS)
+ return ret;
+# else
+ long int ret = __nanosleep_time64_32 (requested_time, remaining);
+
+ if (ret == 0 || errno != ENOSYS)
+ return ret;
+# endif
+# endif
return SYSCALL_CANCEL (nanosleep, requested_time, remaining);
+#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 122ba627ff..f411a1c6c2 100644
--- a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c
+++ b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c
@@ -24,6 +24,17 @@ int
__nanosleep_nocancel (const struct timespec *requested_time,
struct timespec *remaining)
{
+#ifdef __ASSUME_TIME64_SYSCALLS
+ return INLINE_SYSCALL_CALL (clock_nanosleep_time64, CLOCK_REALTIME, 0,
+ requested_time, remaining);
+#else
+# ifdef __NR_clock_nanosleep_time64
+ long int ret = INLINE_SYSCALL_CALL (clock_nanosleep_time64, CLOCK_REALTIME, 0,
+ requested_time, remaining);
+ if (ret == 0 || errno != ENOSYS)
+ return ret;
+# endif
return INLINE_SYSCALL_CALL (nanosleep, requested_time, remaining);
+#endif
}
hidden_def (__nanosleep_nocancel)
--
2.22.0