public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls.
  2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
@ 2019-10-25 12:08 ` Adhemerval Zanella
  2019-10-25 13:05   ` Lukasz Majewski
  2019-10-26  1:08   ` Alistair Francis
  2019-10-25 12:08 ` [PATCH v2 03/11] Use clock_settime to implement stime; withdraw stime Adhemerval Zanella
                   ` (9 subsequent siblings)
  10 siblings, 2 replies; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:08 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski, Zack Weinberg

From: Zack Weinberg <zackw@panix.com>

Changes from previous version:

  - Add check usage32 check on __wait4_tv32.

  - Change capitalized functions to lowercase.

--

Linux/Alpha has two versions of several system call wrappers that take
or return data of type "struct timeval" (possibly nested inside a
larger structure).  The GLIBC_2.0 version is a compat symbol that
calls __NR_osf_foo or __NR_old_foo and uses a struct timeval with a
32-bit tv_sec field.  The GLIBC_2.1 version is used for current code,
calls __NR_foo, and uses a struct timeval with a 64-bit tv_sec field.

This patch changes all of the compat symbols of this type to be
wrappers around their GLIBC_2.1 counterparts; the compatibility system
calls will no longer be used.  It serves as a proposal for part of how
we do the transition to 64-bit time_t on systems that currently use
32-bit time_t:

 * The patched glibc will NOT use system calls that involve 32-bit
   time_t to implement its compatibility symbols.  This will make both
   our lives and the kernel maintainers' lives easier.  The primary
   argument I've seen against it is that the kernel could warn about
   uses of the old system calls, helping people find old binaries that
   need to be recompiled.  I think there are several other ways we
   could accomplish this, e.g. scripts to scan the filesystem for
   binaries with references to the old symbol versions, or issuing
   diagnostics ourselves.

 * The compat symbols do NOT report failure after the Y2038 deadline.
   An earlier revision of this patch had them return -1 and set errno
   to EOVERFLOW, but Adhemerval pointed out that many of them have
   already performed side effects at the point where we discover the
   overflow, so that would break more than it fixes.  Also, we don't
   want people to be _checking_ for EOVERFLOW from these functions; we
   want them to recompile with 64-bit time_t.  So it's not actually
   useful for them to report failure to the calling code.

 * What they do do, when they encounter overflow, is saturate the
   overflowed "struct timeval"(s): tv_sec is set to INT32_MAX and
   tv_nsec is set to 999999.  That means time stops advancing for
   programs with 32-bit time_t when they reach the deadline.  That's
   obviously going to break stuff, but I think wrapping around is
   probably going to break _more_ stuff.  I'd be interested to hear
   arguments against, if anyone has one.

The new header file tv32-compat.h is currently Alpha-specific but I
mean for it to be reused to aid in writing wrappers for all affected
architectures.  I only put it in sysdeps/unix/sysv/linux/alpha for now
because I haven't checked whether the various "foo32" structures it
defines agree with the ABI for ports other than Linux/Alpha.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
---
 sysdeps/unix/sysv/linux/Makefile              |   2 +-
 sysdeps/unix/sysv/linux/adjtime.c             |  40 ++---
 sysdeps/unix/sysv/linux/adjtimex.c            |  40 +++++
 sysdeps/unix/sysv/linux/alpha/Makefile        |   2 +-
 sysdeps/unix/sysv/linux/alpha/adjtime.c       |  82 +---------
 sysdeps/unix/sysv/linux/alpha/adjtimex.c      |  22 +++
 sysdeps/unix/sysv/linux/alpha/osf_adjtime.c   | 130 ++++++++++++++++
 sysdeps/unix/sysv/linux/alpha/osf_getitimer.c |  41 +++++
 sysdeps/unix/sysv/linux/alpha/osf_getrusage.c |  39 +++++
 .../unix/sysv/linux/alpha/osf_gettimeofday.c  |  43 ++++++
 sysdeps/unix/sysv/linux/alpha/osf_setitimer.c |  49 ++++++
 .../unix/sysv/linux/alpha/osf_settimeofday.c  |  41 +++++
 sysdeps/unix/sysv/linux/alpha/osf_utimes.c    |  37 +++++
 sysdeps/unix/sysv/linux/alpha/osf_wait4.c     |  41 +++++
 sysdeps/unix/sysv/linux/alpha/syscalls.list   |  27 ++--
 sysdeps/unix/sysv/linux/alpha/tv32-compat.h   | 146 ++++++++++++++++++
 sysdeps/unix/sysv/linux/gettimeofday.c        |  14 +-
 sysdeps/unix/sysv/linux/syscalls.list         |   1 -
 18 files changed, 666 insertions(+), 131 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/adjtimex.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/adjtimex.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_utimes.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_wait4.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/tv32-compat.h

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index bbab8f8cc3..a7623fb390 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -14,7 +14,7 @@ endif
 ifeq ($(subdir),misc)
 include $(firstword $(wildcard $(sysdirs:=/sysctl.mk)))
 
-sysdep_routines += clone umount umount2 readahead \
+sysdep_routines += adjtimex clone umount umount2 readahead \
 		   setfsuid setfsgid epoll_pwait signalfd \
 		   eventfd eventfd_read eventfd_write prlimit \
 		   personality epoll_wait tee vmsplice splice \
diff --git a/sysdeps/unix/sysv/linux/adjtime.c b/sysdeps/unix/sysv/linux/adjtime.c
index 6d1e129ccc..6b8021caa3 100644
--- a/sysdeps/unix/sysv/linux/adjtime.c
+++ b/sysdeps/unix/sysv/linux/adjtime.c
@@ -23,39 +23,14 @@
 #define MAX_SEC	(INT_MAX / 1000000L - 2)
 #define MIN_SEC	(INT_MIN / 1000000L + 2)
 
-#ifndef MOD_OFFSET
-#define modes mode
-#endif
-
-#ifndef TIMEVAL
-#define TIMEVAL timeval
-#endif
-
-#ifndef TIMEX
-#define TIMEX timex
-#endif
-
-#ifndef ADJTIME
-#define ADJTIME __adjtime
-#endif
-
-#ifndef ADJTIMEX
-#define NO_LOCAL_ADJTIME
-#define ADJTIMEX(x) __adjtimex (x)
-#endif
-
-#ifndef LINKAGE
-#define LINKAGE
-#endif
-
-LINKAGE int
-ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
+int
+__adjtime (const struct timeval *itv, struct timeval *otv)
 {
-  struct TIMEX tntx;
+  struct timex tntx;
 
   if (itv)
     {
-      struct TIMEVAL tmp;
+      struct timeval tmp;
 
       /* We will do some check here. */
       tmp.tv_sec = itv->tv_sec + itv->tv_usec / 1000000L;
@@ -68,7 +43,7 @@ ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
   else
     tntx.modes = ADJ_OFFSET_SS_READ;
 
-  if (__glibc_unlikely (ADJTIMEX (&tntx) < 0))
+  if (__glibc_unlikely (__adjtimex (&tntx) < 0))
     return -1;
 
   if (otv)
@@ -87,6 +62,9 @@ ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
   return 0;
 }
 
-#ifdef NO_LOCAL_ADJTIME
+#ifdef VERSION_adjtime
+weak_alias (__adjtime, __wadjtime);
+default_symbol_version (__wadjtime, adjtime, VERSION_adjtime);
+#else
 weak_alias (__adjtime, adjtime)
 #endif
diff --git a/sysdeps/unix/sysv/linux/adjtimex.c b/sysdeps/unix/sysv/linux/adjtimex.c
new file mode 100644
index 0000000000..6d62c72a17
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/adjtimex.c
@@ -0,0 +1,40 @@
+/* Tune kernel clock.  Linux specific syscall.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/timex.h>
+#include <sysdep.h>
+
+int
+___adjtimex (struct timex *buf)
+{
+  return INLINE_SYSCALL_CALL (adjtimex, buf);
+}
+
+#ifdef VERSION_adjtimex
+weak_alias (___adjtimex, __wadjtimex);
+weak_alias (___adjtimex, __wnadjtime);
+default_symbol_version (___adjtimex,  __adjtimex, VERSION_adjtimex);
+default_symbol_version (__wadjtimex,    adjtimex, VERSION_adjtimex);
+default_symbol_version (__wnadjtime, ntp_adjtime, VERSION_adjtimex);
+libc_hidden_ver (___adjtimex, __adjtimex);
+#else
+strong_alias (___adjtimex, __adjtimex)
+weak_alias (___adjtimex, adjtimex)
+weak_alias (___adjtimex, ntp_adjtime)
+libc_hidden_def (__adjtimex)
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile
index fdd089af71..2e132e474b 100644
--- a/sysdeps/unix/sysv/linux/alpha/Makefile
+++ b/sysdeps/unix/sysv/linux/alpha/Makefile
@@ -9,7 +9,7 @@ sysdep_routines += ieee_get_fp_control ieee_set_fp_control \
 		   ioperm
 
 # Support old timeval32 entry points
-sysdep_routines += osf_gettimeofday osf_settimeofday \
+sysdep_routines += osf_adjtime osf_gettimeofday osf_settimeofday \
 		   osf_getitimer osf_setitimer osf_utimes \
 		   osf_getrusage osf_wait4
 
diff --git a/sysdeps/unix/sysv/linux/alpha/adjtime.c b/sysdeps/unix/sysv/linux/alpha/adjtime.c
index 4aede1cc40..9cb058ee55 100644
--- a/sysdeps/unix/sysv/linux/alpha/adjtime.c
+++ b/sysdeps/unix/sysv/linux/alpha/adjtime.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998-2019 Free Software Foundation, Inc.
+/* adjtime -- Adjust the current time of day.  Linux/Alpha/tv64 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -15,80 +16,7 @@
    License along with the GNU C Library.  If not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <shlib-compat.h>
-#include <sysdep.h>
-#include <sys/time.h>
-
-
-#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
-struct timeval32
-{
-    int tv_sec, tv_usec;
-};
-
-struct timex32 {
-	unsigned int modes;	/* mode selector */
-	long offset;		/* time offset (usec) */
-	long freq;		/* frequency offset (scaled ppm) */
-	long maxerror;		/* maximum error (usec) */
-	long esterror;		/* estimated error (usec) */
-	int status;		/* clock command/status */
-	long constant;		/* pll time constant */
-	long precision;		/* clock precision (usec) (read only) */
-	long tolerance;		/* clock frequency tolerance (ppm)
-				 * (read only)
-				 */
-	struct timeval32 time;	/* (read only) */
-	long tick;		/* (modified) usecs between clock ticks */
-
-	long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
-	long jitter;            /* pps jitter (us) (ro) */
-	int shift;              /* interval duration (s) (shift) (ro) */
-	long stabil;            /* pps stability (scaled ppm) (ro) */
-	long jitcnt;            /* jitter limit exceeded (ro) */
-	long calcnt;            /* calibration intervals (ro) */
-	long errcnt;            /* calibration errors (ro) */
-	long stbcnt;            /* stability limit exceeded (ro) */
-
-	int  :32; int  :32; int  :32; int  :32;
-	int  :32; int  :32; int  :32; int  :32;
-	int  :32; int  :32; int  :32; int  :32;
-};
-
-#define TIMEVAL		timeval32
-#define TIMEX		timex32
-#define ADJTIME		attribute_compat_text_section __adjtime_tv32
-#define ADJTIMEX(x)	INLINE_SYSCALL (old_adjtimex, 1, x)
-#define ADJTIMEX32(x)	INLINE_SYSCALL (old_adjtimex, 1, x)
-
+/* We can use the generic Linux implementation, but we have to override its
+   default symbol version.  */
+#define VERSION_adjtime GLIBC_2.1
 #include <sysdeps/unix/sysv/linux/adjtime.c>
-
-int attribute_compat_text_section
-__adjtimex_tv32 (struct timex32 *tx) { return ADJTIMEX (tx); }
-
-strong_alias (__adjtimex_tv32, __adjtimex_tv32_1);
-strong_alias (__adjtimex_tv32, __adjtimex_tv32_2);
-compat_symbol (libc, __adjtimex_tv32_1, __adjtimex, GLIBC_2_0);
-compat_symbol (libc, __adjtimex_tv32_2, adjtimex, GLIBC_2_0);
-compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0);
-#endif /* SHLIB_COMPAT */
-
-#undef TIMEVAL
-#undef TIMEX
-#undef ADJTIME
-#undef ADJTIMEX
-#define TIMEVAL		timeval
-#define TIMEX		timex
-#define ADJTIMEX(x)	INLINE_SYSCALL (adjtimex, 1, x)
-
-#include <sysdeps/unix/sysv/linux/adjtime.c>
-
-int
-__adjtimex_tv64 (struct timex *tx) { return ADJTIMEX (tx); }
-
-libc_hidden_ver (__adjtimex_tv64, __adjtimex)
-strong_alias (__adjtimex_tv64, __adjtimex_tv64p);
-weak_alias (__adjtimex_tv64, ntp_adjtime);
-versioned_symbol (libc, __adjtimex_tv64, __adjtimex, GLIBC_2_1);
-versioned_symbol (libc, __adjtimex_tv64p, adjtimex, GLIBC_2_1);
-versioned_symbol (libc, __adjtime, adjtime, GLIBC_2_1);
diff --git a/sysdeps/unix/sysv/linux/alpha/adjtimex.c b/sysdeps/unix/sysv/linux/alpha/adjtimex.c
new file mode 100644
index 0000000000..1a8e0a9529
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/adjtimex.c
@@ -0,0 +1,22 @@
+/* adjtimex -- Adjust the current time of day.  Linux/Alpha/tv64 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* We can use the generic Linux implementation, but we have to override its
+   default symbol version.  */
+#define VERSION_adjtimex GLIBC_2.1
+#include <sysdeps/unix/sysv/linux/adjtimex.c>
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
new file mode 100644
index 0000000000..c948ac2dda
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
@@ -0,0 +1,130 @@
+/* adjtime -- adjust the system clock.  Linux/Alpha/tv32 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+#include <sys/time.h>
+#include <sys/timex.h>
+#include <tv32-compat.h>
+
+struct timex32 {
+	unsigned int modes;	/* mode selector */
+	long offset;		/* time offset (usec) */
+	long freq;		/* frequency offset (scaled ppm) */
+	long maxerror;		/* maximum error (usec) */
+	long esterror;		/* estimated error (usec) */
+	int status;		/* clock command/status */
+	long constant;		/* pll time constant */
+	long precision;		/* clock precision (usec) (read only) */
+	long tolerance;		/* clock frequency tolerance (ppm)
+				 * (read only)
+				 */
+	struct timeval32 time;	/* (read only) */
+	long tick;		/* (modified) usecs between clock ticks */
+
+	long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
+	long jitter;            /* pps jitter (us) (ro) */
+	int shift;              /* interval duration (s) (shift) (ro) */
+	long stabil;            /* pps stability (scaled ppm) (ro) */
+	long jitcnt;            /* jitter limit exceeded (ro) */
+	long calcnt;            /* calibration intervals (ro) */
+	long errcnt;            /* calibration errors (ro) */
+	long stbcnt;            /* stability limit exceeded (ro) */
+
+	int  :32; int  :32; int  :32; int  :32;
+	int  :32; int  :32; int  :32; int  :32;
+	int  :32; int  :32; int  :32; int  :32;
+};
+
+int
+attribute_compat_text_section
+__adjtime_tv32 (const struct timeval32 *itv, struct timeval32 *otv)
+{
+  struct timeval itv64, otv64;
+  tv32_to_tv64 (&itv64, itv);
+
+  if (__adjtime (&itv64, &otv64) == -1)
+    return -1;
+
+  tv64_to_tv32 (otv, &itv64);
+  return 0;
+}
+
+int
+attribute_compat_text_section
+__adjtimex_tv32 (struct timex32 *tx)
+{
+  struct timex tx64;
+  memset (&tx64, 0, sizeof tx64);
+  tx64.modes     = tx->modes;
+  tx64.offset    = tx->offset;
+  tx64.freq      = tx->freq;
+  tx64.maxerror  = tx->maxerror;
+  tx64.esterror  = tx->esterror;
+  tx64.status    = tx->status;
+  tx64.constant  = tx->constant;
+  tx64.precision = tx->precision;
+  tx64.tolerance = tx->tolerance;
+  tx64.tick      = tx->tick;
+  tx64.ppsfreq   = tx->ppsfreq;
+  tx64.jitter    = tx->jitter;
+  tx64.shift     = tx->shift;
+  tx64.stabil    = tx->stabil;
+  tx64.jitcnt    = tx->jitcnt;
+  tx64.calcnt    = tx->calcnt;
+  tx64.errcnt    = tx->errcnt;
+  tx64.stbcnt    = tx->stbcnt;
+  tv32_to_tv64 (&tx64.time, &tx->time);
+
+  int status = __adjtimex (&tx64);
+  if (status < 0)
+    return status;
+
+  memset (tx, 0, sizeof *tx);
+  tx->modes     = tx64.modes;
+  tx->offset    = tx64.offset;
+  tx->freq      = tx64.freq;
+  tx->maxerror  = tx64.maxerror;
+  tx->esterror  = tx64.esterror;
+  tx->status    = tx64.status;
+  tx->constant  = tx64.constant;
+  tx->precision = tx64.precision;
+  tx->tolerance = tx64.tolerance;
+  tx->tick      = tx64.tick;
+  tx->ppsfreq   = tx64.ppsfreq;
+  tx->jitter    = tx64.jitter;
+  tx->shift     = tx64.shift;
+  tx->stabil    = tx64.stabil;
+  tx->jitcnt    = tx64.jitcnt;
+  tx->calcnt    = tx64.calcnt;
+  tx->errcnt    = tx64.errcnt;
+  tx->stbcnt    = tx64.stbcnt;
+  tv64_to_tv32 (&tx->time, &tx64.time);
+
+  return status;
+}
+
+strong_alias (__adjtimex_tv32, __adjtimex_tv32_1);
+strong_alias (__adjtimex_tv32, __adjtimex_tv32_2);
+compat_symbol (libc, __adjtimex_tv32_1, __adjtimex, GLIBC_2_0);
+compat_symbol (libc, __adjtimex_tv32_2, adjtimex, GLIBC_2_0);
+compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0);
+
+#endif /* SHLIB_COMPAT */
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
new file mode 100644
index 0000000000..f290954783
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
@@ -0,0 +1,41 @@
+/* getitimer -- Get the state of an interval timer.  Linux/Alpha/tv32 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+#include <sys/time.h>
+#include <tv32-compat.h>
+
+int
+attribute_compat_text_section
+__getitimer_tv32 (int which, struct itimerval32 *curr_value)
+{
+  struct itimerval curr_value_64;
+  if (__getitimer (which, &curr_value_64) == -1)
+    return -1;
+
+  /* Write all fields of 'curr_value' regardless of overflow.  */
+  tv64_to_tv32 (&curr_value->it_interval, &curr_value_64.it_interval);
+  tv64_to_tv32 (&curr_value->it_value, &curr_value_64.it_value);
+  return 0;
+}
+
+compat_symbol (libc, __getitimer_tv32, getitimer, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
new file mode 100644
index 0000000000..918e8445d4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
@@ -0,0 +1,39 @@
+/* utimes -- change file timestamps.  Linux/Alpha/tv32 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <tv32-compat.h>
+
+int
+__getrusage_tv32 (int who, struct rusage32 *usage32)
+{
+  struct rusage usage64;
+  if (__getrusage (who, &usage64) == -1)
+    return -1;
+
+  rusage64_to_rusage32 (usage32, &usage64);
+  return 0;
+}
+
+compat_symbol (libc, __getrusage_tv32, getrusage, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
new file mode 100644
index 0000000000..e6cc522dd1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
@@ -0,0 +1,43 @@
+/* gettimeofday -- Get the current time of day.  Linux/Alpha/tv32 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+#include <sys/time.h>
+#include <tv32-compat.h>
+
+/* Get the current time of day and timezone information putting it
+   into *TV and *TZ.  */
+
+int
+attribute_compat_text_section
+__gettimeofday_tv32 (struct timeval32 *restrict tv32, void *restrict tz)
+{
+  struct timeval tv;
+  __gettimeofday (&tv, tz);
+
+  tv64_to_tv32 (tv32, &tv);
+  return 0;
+}
+
+compat_symbol (libc, __gettimeofday_tv32, __gettimeofday, GLIBC_2_0);
+strong_alias (__gettimeofday_tv32, __gettimeofday_tv32_1);
+compat_symbol (libc, __gettimeofday_tv32_1, gettimeofday, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
new file mode 100644
index 0000000000..d6bbcee60a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
@@ -0,0 +1,49 @@
+/* getitimer -- Get the state of an interval timer.  Linux/Alpha/tv32 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+#include <sys/time.h>
+#include <tv32-compat.h>
+
+int
+attribute_compat_text_section
+__setitimer_tv32 (int which, const struct itimerval32 *restrict new_value,
+		  struct itimerval32 *restrict old_value)
+{
+  struct itimerval new_value_64;
+  tv32_to_tv64 (&new_value_64.it_interval, &new_value->it_interval);
+  tv32_to_tv64 (&new_value_64.it_value, &new_value->it_value);
+
+  if (old_value == NULL)
+    return __setitimer (which, &new_value_64, NULL);
+
+  struct itimerval old_value_64;
+  if (__setitimer (which, &new_value_64, &old_value_64) == -1)
+    return -1;
+
+  /* Write all fields of 'old_value' regardless of overflow.  */
+  tv64_to_tv32 (&old_value->it_interval, &old_value_64.it_interval);
+  tv64_to_tv32 (&old_value->it_value, &old_value_64.it_value);
+  return 0;
+}
+
+compat_symbol (libc, __setitimer_tv32, setitimer, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
new file mode 100644
index 0000000000..fb2a36df19
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
@@ -0,0 +1,41 @@
+/* settimeofday -- Set the current time of day.  Linux/Alpha/tv32 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+#include <tv32-compat.h>
+
+/* Set the current time of day and timezone information.
+   This call is restricted to the super-user.  */
+int
+attribute_compat_text_section
+__settimeofday_tv32 (const struct timeval32 *tv32,
+                     const struct timezone *tz)
+{
+  struct timeval tv;
+  tv32_to_tv64 (&tv, tv32);
+  return __settimeofday (&tv, tz);
+}
+
+compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_utimes.c b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
new file mode 100644
index 0000000000..788fb7cd44
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
@@ -0,0 +1,37 @@
+/* utimes -- change file timestamps.  Linux/Alpha/tv32 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+#include <sys/time.h>
+#include <tv32-compat.h>
+
+int
+attribute_compat_text_section
+__utimes_tv32 (const char *filename, const struct timeval32 times32[2])
+{
+  struct timeval times[2];
+  tv32_to_tv64 (&times[0], &times32[0]);
+  tv32_to_tv64 (&times[1], &times32[1]);
+  return __utimes (filename, times);
+}
+
+compat_symbol (libc, __utimes_tv32, utimes, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_wait4.c b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
new file mode 100644
index 0000000000..e8db554660
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
@@ -0,0 +1,41 @@
+/* wait4 -- wait for process to change state.  Linux/Alpha/tv32 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <tv32-compat.h>
+
+pid_t
+attribute_compat_text_section
+__wait4_tv32 (pid_t pid, int *status, int options, struct rusage32 *usage32)
+{
+  struct rusage usage64;
+  pid_t child = __wait4 (pid, status, options, &usage64);
+
+  if (child >= 0 && usage32 != NULL)
+    rusage64_to_rusage32 (usage32, &usage64);
+  return child;
+}
+
+compat_symbol (libc, __wait4_tv32, wait4, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list
index 12cd021b60..c786aa751e 100644
--- a/sysdeps/unix/sysv/linux/alpha/syscalls.list
+++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list
@@ -1,4 +1,4 @@
-# File name	Caller	Syscall name	# args	Strong name	Weak names
+# File name	Caller	Syscall name	Args	Strong name	Weak names
 
 sigstack	-	sigstack	2	sigstack
 
@@ -22,23 +22,14 @@ pciconfig_read	EXTRA	pciconfig_read	5	pciconfig_read
 pciconfig_write	EXTRA	pciconfig_write	5	pciconfig_write
 pciconfig_iobase EXTRA	pciconfig_iobase 3	__pciconfig_iobase pciconfig_iobase
 
-# support old timeval32 entry points
-osf_gettimeofday -	osf_gettimeofday 2	__gettimeofday_tv32  __gettimeofday@GLIBC_2.0 gettimeofday@GLIBC_2.0
-osf_settimeofday -	osf_settimeofday 2	__settimeofday_tv32  settimeofday@GLIBC_2.0
-osf_getitimer	-	osf_getitimer	2	__getitimer_tv32  getitimer@GLIBC_2.0
-osf_setitimer	-	osf_setitimer	3	__setitimer_tv32  setitimer@GLIBC_2.0
-osf_utimes	-	osf_utimes	2	__utimes_tv32  utimes@GLIBC_2.0
-osf_getrusage	-	osf_getrusage	2	__getrusage_tv32  getrusage@GLIBC_2.0
-osf_wait4	-	osf_wait4	4	__wait4_tv32  wait4@GLIBC_2.0
-
-# support new timeval64 entry points
-gettimeofday	-	gettimeofday	2	__GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
-settimeofday	-	settimeofday	2	__settimeofday settimeofday@@GLIBC_2.1
-getitimer	-	getitimer	2	__getitimer getitimer@@GLIBC_2.1
-setitimer	-	setitimer	3	__setitimer setitimer@@GLIBC_2.1
-utimes		-	utimes		2	__utimes utimes@@GLIBC_2.1
-getrusage	-	getrusage	2	__getrusage getrusage@@GLIBC_2.1
-wait4		-	wait4		4	__wait4 wait4@@GLIBC_2.1
+# timeval64 entry points (see osf_*.c for GLIBC_2.0 timeval32 equivalents)
+gettimeofday	-	gettimeofday	i:pP	__GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
+settimeofday	-	settimeofday	i:PP	__settimeofday	settimeofday@@GLIBC_2.1
+getitimer	-	getitimer	i:ip	__getitimer	getitimer@@GLIBC_2.1
+setitimer	-	setitimer	i:ipP	__setitimer	setitimer@@GLIBC_2.1
+utimes		-	utimes		i:sp	__utimes	utimes@@GLIBC_2.1
+getrusage	-	getrusage	i:ip	__getrusage	getrusage@@GLIBC_2.1
+wait4		-	wait4		i:iWiP	__wait4		wait4@@GLIBC_2.1
 
 # avoid 64-bit aliases on 32-bit statfs syscalls
 fstatfs		-	fstatfs		i:ip	__fstatfs	fstatfs
diff --git a/sysdeps/unix/sysv/linux/alpha/tv32-compat.h b/sysdeps/unix/sysv/linux/alpha/tv32-compat.h
new file mode 100644
index 0000000000..e1edb7453a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/tv32-compat.h
@@ -0,0 +1,146 @@
+/* Compatibility definitions for `struct timeval' with 32-bit time_t.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TV32_COMPAT_H
+#define _TV32_COMPAT_H 1
+
+#include <features.h>
+
+#include <bits/types.h>
+#include <bits/types/time_t.h>
+#include <bits/types/struct_timeval.h>
+#include <bits/types/struct_timespec.h>
+#include <bits/types/struct_rusage.h>
+
+#include <stdint.h> // for INT32_MAX
+#include <string.h> // for memset
+
+#define TV_USEC_MAX 999999 // 10**6 - 1
+
+/* A version of 'struct timeval' with 32-bit time_t.  */
+struct timeval32
+{
+  int32_t tv_sec;
+  int32_t tv_usec;
+};
+
+/* Structures containing 'struct timeval' with 32-bit time_t.  */
+struct itimerval32
+{
+  struct timeval32 it_interval;
+  struct timeval32 it_value;
+};
+
+struct rusage32
+{
+  struct timeval32 ru_utime;	/* user time used */
+  struct timeval32 ru_stime;	/* system time used */
+  long ru_maxrss;		/* maximum resident set size */
+  long ru_ixrss;		/* integral shared memory size */
+  long ru_idrss;		/* integral unshared data size */
+  long ru_isrss;		/* integral unshared stack size */
+  long ru_minflt;		/* page reclaims */
+  long ru_majflt;		/* page faults */
+  long ru_nswap;		/* swaps */
+  long ru_inblock;		/* block input operations */
+  long ru_oublock;		/* block output operations */
+  long ru_msgsnd;		/* messages sent */
+  long ru_msgrcv;		/* messages received */
+  long ru_nsignals;		/* signals received */
+  long ru_nvcsw;		/* voluntary context switches */
+  long ru_nivcsw;		/* involuntary " */
+};
+
+/* Conversion functions.  If the seconds field of a timeval32 would
+   overflow, they write { INT32_MAX, TV_USEC_MAX } to the output.  */
+
+static inline void
+tv32_to_tv64 (struct timeval *restrict tv64,
+              const struct timeval32 *restrict tv32)
+{
+  tv64->tv_sec = tv32->tv_sec;
+  tv64->tv_usec = tv32->tv_usec;
+}
+
+static inline void
+tv32_to_ts64 (struct timespec *restrict ts64,
+              const struct timeval32 *restrict tv32)
+{
+  ts64->tv_sec = tv32->tv_sec;
+  ts64->tv_nsec = tv32->tv_usec * 1000;
+}
+
+static inline void
+tv64_to_tv32 (struct timeval32 *restrict tv32,
+              const struct timeval *restrict tv64)
+{
+  if (__glibc_unlikely (tv64->tv_sec > (time_t) INT32_MAX))
+    {
+      tv32->tv_sec = INT32_MAX;
+      tv32->tv_usec = TV_USEC_MAX;
+    }
+  else
+    {
+      tv32->tv_sec = tv64->tv_sec;
+      tv32->tv_usec = tv64->tv_usec;
+    }
+}
+
+static inline void
+ts64_to_tv32 (struct timeval32 *restrict tv32,
+              const struct timespec *restrict ts64)
+{
+  if (__glibc_unlikely (ts64->tv_sec > (time_t) INT32_MAX))
+    {
+      tv32->tv_sec = INT32_MAX;
+      tv32->tv_usec = TV_USEC_MAX;
+    }
+  else
+    {
+      tv32->tv_sec = ts64->tv_sec;
+      tv32->tv_usec = ts64->tv_nsec / 1000;
+    }
+}
+
+static inline void
+rusage64_to_rusage32 (struct rusage32 *restrict r32,
+                      const struct rusage *restrict r64)
+{
+  /* Make sure the entire output structure is cleared, including
+     padding and reserved fields.  */
+  memset (r32, 0, sizeof *r32);
+
+  tv64_to_tv32 (&r32->ru_utime, &r64->ru_utime);
+  tv64_to_tv32 (&r32->ru_stime, &r64->ru_stime);
+  r32->ru_maxrss   = r64->ru_maxrss;
+  r32->ru_ixrss    = r64->ru_ixrss;
+  r32->ru_idrss    = r64->ru_idrss;
+  r32->ru_isrss    = r64->ru_isrss;
+  r32->ru_minflt   = r64->ru_minflt;
+  r32->ru_majflt   = r64->ru_majflt;
+  r32->ru_nswap    = r64->ru_nswap;
+  r32->ru_inblock  = r64->ru_inblock;
+  r32->ru_oublock  = r64->ru_oublock;
+  r32->ru_msgsnd   = r64->ru_msgsnd;
+  r32->ru_msgrcv   = r64->ru_msgrcv;
+  r32->ru_nsignals = r64->ru_nsignals;
+  r32->ru_nvcsw    = r64->ru_nvcsw;
+  r32->ru_nivcsw   = r64->ru_nivcsw;
+}
+
+#endif /* tv32-compat.h */
diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
index d69d4eaa96..c9597d6405 100644
--- a/sysdeps/unix/sysv/linux/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/gettimeofday.c
@@ -30,10 +30,20 @@
    putting it into *tv and *tz.  If tz is null, *tz is not filled.
    Returns 0 on success, -1 on errors.  */
 int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
+___gettimeofday (struct timeval *tv, struct timezone *tz)
 {
   return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
 }
+
+#ifdef VERSION_gettimeofday
+weak_alias (___gettimeofday, __wgettimeofday);
+default_symbol_version (___gettimeofday, __gettimeofday, VERSION_gettimeofday);
+default_symbol_version (__wgettimeofday,   gettimeofday, VERSION_gettimeofday);
+libc_hidden_ver (___gettimeofday, __gettimeofday);
+libc_hidden_ver (___gettimeofday, gettimeofday);
+#else
+strong_alias (___gettimeofday, __gettimeofday)
+weak_alias (___gettimeofday, gettimeofday)
 libc_hidden_def (__gettimeofday)
-weak_alias (__gettimeofday, gettimeofday)
 libc_hidden_weak (gettimeofday)
+#endif
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index e374f97b5f..cdcf6c127b 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -1,6 +1,5 @@
 # File name	Caller	Syscall name	Args	Strong name	Weak names
 
-adjtimex	adjtime	adjtimex	i:p	__adjtimex	adjtimex ntp_adjtime
 alarm		-	alarm		i:i	alarm
 bdflush		EXTRA	bdflush		i:ii	__compat_bdflush	bdflush@GLIBC_2.0:GLIBC_2.23
 capget		EXTRA	capget		i:pp	capget
-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 03/11] Use clock_settime to implement stime; withdraw stime.
  2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
  2019-10-25 12:08 ` [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls Adhemerval Zanella
@ 2019-10-25 12:08 ` Adhemerval Zanella
  2019-10-25 13:59   ` Lukasz Majewski
  2019-10-25 12:09 ` [PATCH v2 10/11] Make second argument of gettimeofday as 'void *' Adhemerval Zanella
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:08 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski, Zack Weinberg

From: Zack Weinberg <zackw@panix.com>

Use clock_settime to implement stime; withdraw stime.

Changes from previous version:

  - Added a NEWS entry.

--

Unconditionally, on all ports, use clock_settime to implement stime,
not settimeofday or a direct syscall.  Then convert stime into a
compatibility symbol and remove its prototype from time.h.

Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
---
 NEWS                                  |  4 +++
 sysdeps/unix/stime.c                  | 39 ---------------------------
 sysdeps/unix/sysv/linux/syscalls.list |  1 -
 time/stime.c                          | 25 ++++++++---------
 time/time.h                           |  6 -----
 5 files changed, 17 insertions(+), 58 deletions(-)
 delete mode 100644 sysdeps/unix/stime.c

diff --git a/NEWS b/NEWS
index d7286841c9..8727b5e7f0 100644
--- a/NEWS
+++ b/NEWS
@@ -30,6 +30,10 @@ Deprecated and removed features, and other changes affecting compatibility:
   Request 25 to TS 18661-1, as applied for C2X.  Existing binaries that pass
   floating-point arguments directly will continue to work.
 
+* The obsolete function stime is no longer available to newly linked
+  binaries and it has been removed from <time.h> header.  This function
+  has been deprecated in favor of clock_settime.
+
 Changes to build and runtime requirements:
 
   [Add changes to build and runtime requirements here]
diff --git a/sysdeps/unix/stime.c b/sysdeps/unix/stime.c
deleted file mode 100644
index b40c33454a..0000000000
--- a/sysdeps/unix/stime.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (C) 1992-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <stddef.h>		/* For NULL.  */
-#include <sys/time.h>
-#include <time.h>
-
-/* Set the system clock to *WHEN.  */
-
-int
-stime (const time_t *when)
-{
-  struct timeval tv;
-
-  if (when == NULL)
-    {
-      __set_errno (EINVAL);
-      return -1;
-    }
-
-  tv.tv_sec = *when;
-  tv.tv_usec = 0;
-  return __settimeofday (&tv, (struct timezone *) 0);
-}
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index cdcf6c127b..70b110979b 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -61,7 +61,6 @@ setfsgid	EXTRA	setfsgid	i:i	setfsgid
 setfsuid	EXTRA	setfsuid	i:i	setfsuid
 setpgid		-	setpgid		i:ii	__setpgid	setpgid
 sigaltstack	-	sigaltstack	i:PP	__sigaltstack	sigaltstack
-stime		-	stime		i:p	stime
 sysinfo		EXTRA	sysinfo		i:p	__sysinfo	sysinfo
 swapon		-	swapon		i:si	__swapon	swapon
 swapoff		-	swapoff		i:s	__swapoff	swapoff
diff --git a/time/stime.c b/time/stime.c
index a53c0e86ae..6ea3b6dcc1 100644
--- a/time/stime.c
+++ b/time/stime.c
@@ -15,23 +15,24 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_31)
+
 #include <time.h>
-#include <stddef.h>
 
 /* Set the system clock to *WHEN.  */
 
 int
-stime (const time_t *when)
+attribute_compat_text_section
+__stime (const time_t *when)
 {
-  if (when == NULL)
-    {
-      __set_errno (EINVAL);
-      return -1;
-    }
-
-  __set_errno (ENOSYS);
-  return -1;
+  struct timespec ts;
+  ts.tv_sec = *when;
+  ts.tv_nsec = 0;
+
+  return __clock_settime (CLOCK_REALTIME, &ts);
 }
 
-stub_warning (stime)
+compat_symbol (libc, __stime, stime, GLIBC_2_0);
+#endif
diff --git a/time/time.h b/time/time.h
index 72a1078d2c..7daaacce16 100644
--- a/time/time.h
+++ b/time/time.h
@@ -175,12 +175,6 @@ extern int daylight;
 extern long int timezone;
 #endif
 
-#ifdef __USE_MISC
-/* Set the system time to *WHEN.
-   This call is restricted to the superuser.  */
-extern int stime (const time_t *__when) __THROW;
-#endif
-
 
 /* Nonzero if YEAR is a leap year (every 4 years,
    except every 100th isn't, and every 400th is).  */
-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions.
@ 2019-10-25 12:08 Adhemerval Zanella
  2019-10-25 12:08 ` [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls Adhemerval Zanella
                   ` (10 more replies)
  0 siblings, 11 replies; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:08 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski

This is an updated version from Zack Weinberg patchset [1].

This patchset aims to make the Y2038 project a little easier by
implementing the other time-getting and time-setting functions
(time, ftime, stime, gettimeofday, and settimeofday) in terms of
clock_gettime and clock_settime.  Internal uses of (__)gettimeofday
are also all changed to __clock_gettime.  I also changed the
internal uses of time(), which allowed some cleanup in arch
specific code.

The user-visible consequences of this patchset are:

 - The obsolete function stime is no longer availabe to new binaries
   and the function ftime is marked as deprecated.
 - gettimeofday and ftime now always report a crude time zone
   corresponding to UTC.
 - settimeofday will fail with EINVAL when both of its arguments are
   non-null.
 - Programs that call gettimeofday with a non-null tzp argument will
   receive compile-time warnings (with GCC and when optimizing).

This patchset also includes a partial revision of manual/time.texi
clock_gettime and clock_settime are now documented, and the
obsolescent status of stime, settimeofday, and gettimeofday is
clearer.  I only documented CLOCK_REALTIME and CLOCK_MONOTONIC,
because most of the other clock constants are either extremely
Linux-specific or they have to do with measuring CPU time, and I
didn't touch the measuring-CPU-time part of time.texi.  (That part
also deserves a rewrite, but I don't know enough about the topic and
this patchset is already long enough.)

I ran build-many-glibcs on most abi targets (aarch64, alpha, arm-eabihf,
csky, hppa, ia64, m68k, m68k-coldfire, microblaze, microblazeel, mips64,
powerpc64, powercp64le, riscv64, s390x, and x86_64), I couldn't run
on i686-gnu due it is currently broken on master.

The patches were tested fully on x86_64-linux-gnu, i686-linux-gnu,
powerpc64le-linux-gnu, powerpc64-linux-gnu, powerpc-linux-gnu, and
aarch64-linux-gnu.

[1] https://sourceware.org/ml/libc-alpha/2019-08/msg00725.html

Adhemerval Zanella (3):
  Use clock_gettime to implement time.
  Change most internal uses of time to __clock_gettime.
  Use clock_gettime to implement gettimeofday.

Zack Weinberg (8):
  Linux/Alpha: don't use timeval32 system calls.
  Change most internal uses of __gettimeofday to __clock_gettime.
  Use clock_settime to implement stime; withdraw stime.
  Use clock_settime to implement settimeofday.
  Consolidate and deprecate ftime
  Use clock_gettime to implement timespec_get.
  Make second argument of gettimeofday as 'void *'
  Revise the documentation of simple calendar time.

 NEWS                                          |   46 +
 include/sys/time.h                            |    7 +-
 include/time.h                                |   11 +-
 inet/deadline.c                               |    8 +-
 login/logout.c                                |    9 +-
 login/logwtmp.c                               |    7 +-
 manual/filesys.texi                           |    2 +-
 manual/llio.texi                              |   10 +-
 manual/threads.texi                           |    2 +-
 manual/time.texi                              | 1072 ++++++++++-------
 misc/syslog.c                                 |    2 +-
 nis/nis_call.c                                |    4 +-
 nptl/pthread_join_common.c                    |    7 +-
 nptl/pthread_mutex_timedlock.c                |    7 +-
 nscd/nscd_gethst_r.c                          |    2 +-
 nscd/nscd_helper.c                            |   28 +-
 resolv/gai_misc.c                             |    6 +-
 resolv/gai_suspend.c                          |    6 +-
 resolv/res_send.c                             |    7 +-
 string/strfry.c                               |    4 +-
 sunrpc/auth_des.c                             |   19 +-
 sunrpc/auth_unix.c                            |    9 +-
 sunrpc/create_xid.c                           |    6 +-
 sunrpc/svcauth_des.c                          |    7 +-
 support/support_test_main.c                   |   23 +-
 sysdeps/generic/memusage.h                    |   16 +-
 sysdeps/{unix => mach}/clock_gettime.c        |   37 +-
 sysdeps/{unix => mach/hurd}/clock_settime.c   |   51 +-
 sysdeps/mach/hurd/getitimer.c                 |   11 +-
 sysdeps/mach/hurd/setitimer.c                 |   13 +-
 sysdeps/mach/hurd/times.c                     |    7 +-
 sysdeps/mach/nanosleep.c                      |   36 +-
 sysdeps/mach/usleep.c                         |    5 -
 sysdeps/posix/gettimeofday.c                  |   67 --
 sysdeps/posix/tempname.c                      |    9 +-
 sysdeps/pthread/aio_misc.c                    |    6 +-
 sysdeps/pthread/aio_suspend.c                 |    6 +-
 sysdeps/unix/make-syscalls.sh                 |    2 +-
 sysdeps/unix/syscalls.list                    |    2 -
 sysdeps/unix/sysv/linux/Makefile              |    2 +-
 .../unix/sysv/linux/aarch64/gettimeofday.c    |   38 +-
 sysdeps/unix/sysv/linux/adjtime.c             |   40 +-
 sysdeps/unix/sysv/linux/adjtimex.c            |   40 +
 sysdeps/unix/sysv/linux/alpha/Makefile        |    2 +-
 sysdeps/unix/sysv/linux/alpha/adjtime.c       |   82 +-
 sysdeps/unix/sysv/linux/alpha/adjtimex.c      |   22 +
 .../linux/{time.c => alpha/gettimeofday.c}    |   31 +-
 sysdeps/unix/sysv/linux/alpha/osf_adjtime.c   |  130 ++
 .../sysv/linux/alpha/osf_getitimer.c}         |   40 +-
 .../linux/alpha/osf_getrusage.c}              |   33 +-
 .../unix/sysv/linux/alpha/osf_gettimeofday.c  |   48 +
 sysdeps/unix/sysv/linux/alpha/osf_setitimer.c |   49 +
 .../sysv/linux/alpha/osf_settimeofday.c}      |   51 +-
 .../gettimeofday.c => alpha/osf_utimes.c}     |   36 +-
 .../sysv/linux/alpha/osf_wait4.c}             |   41 +-
 sysdeps/unix/sysv/linux/alpha/settimeofday.c  |   22 +
 sysdeps/unix/sysv/linux/alpha/syscalls.list   |   26 +-
 sysdeps/unix/sysv/linux/alpha/tv32-compat.h   |  146 +++
 sysdeps/unix/sysv/linux/check_native.c        |    2 +-
 sysdeps/unix/sysv/linux/check_pf.c            |    2 +-
 sysdeps/unix/sysv/linux/ftime.c               |    3 -
 sysdeps/unix/sysv/linux/getsysstats.c         |    2 +-
 sysdeps/unix/sysv/linux/gettimeofday.c        |   39 -
 sysdeps/unix/sysv/linux/ifaddrs.c             |    2 +-
 .../unix/sysv/linux/powerpc/gettimeofday.c    |   71 +-
 sysdeps/unix/sysv/linux/powerpc/time.c        |   71 +-
 sysdeps/unix/sysv/linux/settimezone.c         |   36 +
 sysdeps/unix/sysv/linux/syscalls.list         |    2 -
 .../linux/{i386/time.c => time-internal.h}    |   24 +-
 sysdeps/unix/sysv/linux/timespec_get.c        |   46 -
 sysdeps/unix/sysv/linux/x86/gettimeofday.c    |   47 +-
 sysdeps/unix/sysv/linux/x86/time.c            |   34 +-
 .../unix/sysv/linux/x86_64/x32/gettimeofday.c |    1 +
 .../unix/sysv/linux/x86_64/x32/syscalls.list  |    1 -
 time/Makefile                                 |    8 +-
 time/ftime.c                                  |   26 +-
 time/getdate.c                                |    2 +-
 time/gettimeofday.c                           |   32 +-
 time/settimeofday.c                           |   24 +-
 sysdeps/unix/stime.c => time/settimezone.c    |   23 +-
 time/stime.c                                  |   25 +-
 time/sys/time.h                               |   23 +-
 time/sys/timeb.h                              |    3 +-
 .../timespec_get.c => time/time-internal.h    |   26 +-
 time/time.c                                   |   14 +-
 time/time.h                                   |    6 -
 time/timespec_get.c                           |   14 +-
 time/tst-ftime.c                              |    7 +
 88 files changed, 1681 insertions(+), 1393 deletions(-)
 rename sysdeps/{unix => mach}/clock_gettime.c (65%)
 rename sysdeps/{unix => mach/hurd}/clock_settime.c (65%)
 delete mode 100644 sysdeps/posix/gettimeofday.c
 create mode 100644 sysdeps/unix/sysv/linux/adjtimex.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/adjtimex.c
 rename sysdeps/unix/sysv/linux/{time.c => alpha/gettimeofday.c} (64%)
 create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
 rename sysdeps/{mach/gettimeofday.c => unix/sysv/linux/alpha/osf_getitimer.c} (50%)
 rename sysdeps/unix/{bsd/ftime.c => sysv/linux/alpha/osf_getrusage.c} (59%)
 create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
 rename sysdeps/{mach/hurd/settimeofday.c => unix/sysv/linux/alpha/osf_settimeofday.c} (54%)
 rename sysdeps/unix/sysv/linux/{i386/gettimeofday.c => alpha/osf_utimes.c} (56%)
 rename sysdeps/{posix/time.c => unix/sysv/linux/alpha/osf_wait4.c} (51%)
 create mode 100644 sysdeps/unix/sysv/linux/alpha/settimeofday.c
 create mode 100644 sysdeps/unix/sysv/linux/alpha/tv32-compat.h
 delete mode 100644 sysdeps/unix/sysv/linux/ftime.c
 delete mode 100644 sysdeps/unix/sysv/linux/gettimeofday.c
 create mode 100644 sysdeps/unix/sysv/linux/settimezone.c
 rename sysdeps/unix/sysv/linux/{i386/time.c => time-internal.h} (62%)
 delete mode 100644 sysdeps/unix/sysv/linux/timespec_get.c
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c
 rename sysdeps/unix/stime.c => time/settimezone.c (67%)
 rename sysdeps/posix/timespec_get.c => time/time-internal.h (62%)

-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 07/11] Consolidate and deprecate ftime
  2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
                   ` (4 preceding siblings ...)
  2019-10-25 12:09 ` [PATCH v2 04/11] Use clock_settime to implement settimeofday Adhemerval Zanella
@ 2019-10-25 12:09 ` Adhemerval Zanella
  2019-10-28 13:23   ` Lukasz Majewski
  2019-10-25 12:09 ` [PATCH v2 02/11] Change most internal uses of __gettimeofday to __clock_gettime Adhemerval Zanella
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:09 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski, Zack Weinberg

From: Zack Weinberg <zackw@panix.com>

Consolidate and deprecate ftime

Changes from previous version:

  - Do not remove sys/timeb.h, instead mark ftime as deprecated.  The
    idea is still to remove it eventually on a future release.

--

ftime is an obsolete variation on gettimeofday, offering only
millisecond time resolution; it was probably a system call in ooold
versions of BSD Unix.  For historic reasons, we had three
implementations of it.  These are all consolidated into time/ftime.c,
and then the function is deprecated.

For some reason, the implementation of ftime in terms of gettimeofday
was rounding rather than truncating microseconds to milliseconds.  In
all the other places where we use a higher-resolution time function to
implement a lower-resolution one, we truncate.  ftime is changed to
match, just for tidiness' sake.

Like gettimeofday, ftime tries to report the time zone, and using that
information is always a bug.  This patch dummies out the reported
timezone information; the timezone and dstflag fields of the
returned "struct timeb" will always be zero.

Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
powerpc64-linux-gnu, and powerpc-linux-gnu.

Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
---
 NEWS                            |  3 +++
 sysdeps/unix/bsd/ftime.c        | 40 ---------------------------------
 sysdeps/unix/sysv/linux/ftime.c |  3 ---
 time/ftime.c                    | 26 ++++++++-------------
 time/sys/timeb.h                |  3 ++-
 time/tst-ftime.c                |  7 ++++++
 6 files changed, 21 insertions(+), 61 deletions(-)
 delete mode 100644 sysdeps/unix/bsd/ftime.c
 delete mode 100644 sysdeps/unix/sysv/linux/ftime.c

diff --git a/NEWS b/NEWS
index 0b1476e745..6d109f84f0 100644
--- a/NEWS
+++ b/NEWS
@@ -58,6 +58,9 @@ Deprecated and removed features, and other changes affecting compatibility:
   settimeofday available to newly linked binaries after there is a
   replacement for Linux’s time-zone-like offset API.
 
+* The obsolete functions ftime has been deprecated and will be removed from
+  a future version of glibc.  Application should use clock_gettime instead.
+
 Changes to build and runtime requirements:
 
   [Add changes to build and runtime requirements here]
diff --git a/sysdeps/unix/bsd/ftime.c b/sysdeps/unix/bsd/ftime.c
deleted file mode 100644
index e1f20bc609..0000000000
--- a/sysdeps/unix/bsd/ftime.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (C) 1994-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <sys/timeb.h>
-#include <sys/time.h>
-
-int
-ftime (struct timeb *timebuf)
-{
-  struct timeval tv;
-  struct timezone tz;
-
-  if (__gettimeofday (&tv, &tz) < 0)
-    return -1;
-
-  timebuf->time = tv.tv_sec;
-  timebuf->millitm = (tv.tv_usec + 500) / 1000;
-  if (timebuf->millitm == 1000)
-    {
-      ++timebuf->time;
-      timebuf->millitm = 0;
-    }
-  timebuf->timezone = tz.tz_minuteswest;
-  timebuf->dstflag = tz.tz_dsttime;
-  return 0;
-}
diff --git a/sysdeps/unix/sysv/linux/ftime.c b/sysdeps/unix/sysv/linux/ftime.c
deleted file mode 100644
index 5a5949f608..0000000000
--- a/sysdeps/unix/sysv/linux/ftime.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* Linux defines the ftime system call but doesn't actually implement
-   it.  Use the BSD implementation.  */
-#include <sysdeps/unix/bsd/ftime.c>
diff --git a/time/ftime.c b/time/ftime.c
index 8bedc0d91e..b4bd58ecef 100644
--- a/time/ftime.c
+++ b/time/ftime.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1994-2019 Free Software Foundation, Inc.
+/* Deprecated return date and time.
+   Copyright (C) 1994-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -15,27 +16,18 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <time.h>
 #include <sys/timeb.h>
+#include <time.h>
 
 int
 ftime (struct timeb *timebuf)
 {
-  int save = errno;
-  struct tm tp;
-
-  __set_errno (0);
-  if (time (&timebuf->time) == (time_t) -1 && errno != 0)
-    return -1;
-  timebuf->millitm = 0;
-
-  if (__localtime_r (&timebuf->time, &tp) == NULL)
-    return -1;
-
-  timebuf->timezone = tp.tm_gmtoff / 60;
-  timebuf->dstflag = tp.tm_isdst;
+  struct timespec ts;
+  __clock_gettime (CLOCK_REALTIME, &ts);
 
-  __set_errno (save);
+  timebuf->time = ts.tv_sec;
+  timebuf->millitm = ts.tv_nsec / 1000000;
+  timebuf->timezone = 0;
+  timebuf->dstflag = 0;
   return 0;
 }
diff --git a/time/sys/timeb.h b/time/sys/timeb.h
index b958dc3e4a..5c16f79da2 100644
--- a/time/sys/timeb.h
+++ b/time/sys/timeb.h
@@ -36,7 +36,8 @@ struct timeb
 
 /* Fill in TIMEBUF with information about the current time.  */
 
-extern int ftime (struct timeb *__timebuf);
+extern int ftime (struct timeb *__timebuf)
+  __nonnull ((1)) __attribute_deprecated__;
 
 __END_DECLS
 
diff --git a/time/tst-ftime.c b/time/tst-ftime.c
index 4b7e90cc03..39d94a1b26 100644
--- a/time/tst-ftime.c
+++ b/time/tst-ftime.c
@@ -18,6 +18,7 @@
 
 #include <sys/timeb.h>
 #include <stdio.h>
+#include <libc-diag.h>
 
 static int
 do_test (void)
@@ -29,12 +30,18 @@ do_test (void)
     {
       prev = curr;
 
+      /* ftime was deprecated on 2.31.  */
+      DIAG_PUSH_NEEDS_COMMENT;
+      DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
+
       if (ftime (&curr))
         {
           printf ("ftime returned an error\n");
           return 1;
         }
 
+      DIAG_POP_NEEDS_COMMENT;
+
       if (curr.time < prev.time)
         {
           printf ("ftime's time flowed backwards\n");
-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 09/11] Use clock_gettime to implement gettimeofday.
  2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
                   ` (7 preceding siblings ...)
  2019-10-25 12:09 ` [PATCH v2 06/11] Change most internal uses of time " Adhemerval Zanella
@ 2019-10-25 12:09 ` Adhemerval Zanella
  2019-10-28 14:16   ` Lukasz Majewski
  2019-10-25 12:09 ` [PATCH v2 05/11] Use clock_gettime to implement time Adhemerval Zanella
  2019-10-25 12:09 ` [PATCH v2 08/11] Use clock_gettime to implement timespec_get Adhemerval Zanella
  10 siblings, 1 reply; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:09 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski

Use clock_gettime to implement gettimeofday

Changes from previous version:

  - Do not remove Linux arch-specific implementations.

--

Consolidate generic gettimeofday implementation to use clock_gettime.
Linux ports that still provide gettimeofday through vDSO are not
changed.

Remove sysdeps/unix/clock_gettime.c, which implemented clock_gettime
using gettimeofday; new OS ports must provide a real implementation of
clock_gettime.

Rename sysdeps/mach/gettimeofday.c to sysdeps/mach/clock_gettime.c and
convert into an implementation of clock_gettime.  It only supports
CLOCK_REALTIME; Mach does not appear to have any support for monotonic
clocks.  It uses __host_get_time, which provides at best microsecond
resolution.  Hurd is currently using sysdeps/posix/clock_getres.c for
clock_getres; its output for CLOCK_REALTIME is based on
sysconf (_SC_CLK_TCK), and I do not know whether that gives the
correct result.

Unlike settimeofday, there are no known uses of gettimeofday's
vestigial "get time zone" feature that are not bugs.  (The per-process
timezone support in localtime and friends is unrelated, and the
programs that set the kernel's offset between the hardware clock and
UTC do not need to read it back.)  Therefore, this feature is dummied
out.  Henceforth, if gettimeofday's "struct timezone" argument is not
NULL, it will write zeroes to both fields.  Any program that is
actually looking at this data will thus think it is running in UTC,
which is probably more correct than whatever it was doing before.

[__]gettimeofday no longer has any internal callers, so we can now
remove its internal prototype and PLT bypass aliases.  The
__gettimeofday@GLIBC_2.0 export remains, in case it is used by any
third-party code.

It also allows to simplify the arch-specific implementation on x86 and
powerpc to remove the hack to disable the internal route to non iFUNC
variant for internal symbol.

This patch also fixes a missing optimization on aarch64, powerpc, and
x86 where the code used on static build do not use the vDSO.

Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.

Co-authored-by: Zack Weinberg <zackw@panix.com>
---
 NEWS                                          | 15 ++++
 include/sys/time.h                            |  2 -
 sysdeps/{unix => mach}/clock_gettime.c        | 37 +++++-----
 sysdeps/mach/gettimeofday.c                   | 43 ------------
 sysdeps/posix/gettimeofday.c                  | 67 ------------------
 sysdeps/unix/syscalls.list                    |  1 -
 .../unix/sysv/linux/aarch64/gettimeofday.c    | 34 ++++-----
 .../sysv/linux/{i386 => alpha}/gettimeofday.c | 25 ++-----
 .../unix/sysv/linux/alpha/osf_gettimeofday.c  | 11 ++-
 sysdeps/unix/sysv/linux/gettimeofday.c        | 49 -------------
 .../unix/sysv/linux/powerpc/gettimeofday.c    | 69 +++++--------------
 sysdeps/unix/sysv/linux/x86/gettimeofday.c    | 43 +++++-------
 .../unix/sysv/linux/x86_64/x32/gettimeofday.c |  1 +
 .../unix/sysv/linux/x86_64/x32/syscalls.list  |  1 -
 time/gettimeofday.c                           | 32 ++++++---
 15 files changed, 121 insertions(+), 309 deletions(-)
 rename sysdeps/{unix => mach}/clock_gettime.c (65%)
 delete mode 100644 sysdeps/mach/gettimeofday.c
 delete mode 100644 sysdeps/posix/gettimeofday.c
 rename sysdeps/unix/sysv/linux/{i386 => alpha}/gettimeofday.c (58%)
 delete mode 100644 sysdeps/unix/sysv/linux/gettimeofday.c
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c

diff --git a/NEWS b/NEWS
index 6d109f84f0..12d6af2fc0 100644
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,21 @@ Major new features:
   18661-1:2014 and TS 18661-3:2015 as amended by the resolution of
   Clarification Request 13 to TS 18661-3.
 
+* The gettimeofday function will no longer report information about a
+  system-wide time zone, expect for aarch64, powerpc, and x86 on Linux
+  which still uses the vDSO symbol (when available).
+
+  This 4.2-BSD-era feature has been deprecated for many years, as it cannot
+  handle the full complexity of the world’s timezones, but hitherto we have
+  supported it on a best-effort basis.  Changes required to support 64-bit
+  time_t on 32-bit architectures have made this no longer practical.
+
+  As of this release, callers of gettimeofday with a non-null ‘tzp’ argument
+  will always receive a ‘struct timezone’ whose tz_minuteswest and
+  tz_dsttime fields are zero.  We have also arranged for call sites that
+  pass a non-null ‘tzp’ argument to gettimeofday to receive compile-time
+  warnings, if the compiler makes this possible.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * The totalorder and totalordermag functions, and the corresponding
diff --git a/include/sys/time.h b/include/sys/time.h
index c0e30e70fb..2bf4297e76 100644
--- a/include/sys/time.h
+++ b/include/sys/time.h
@@ -22,8 +22,6 @@
 # ifndef _ISOMAC
 extern int __gettimeofday (struct timeval *__tv,
 			   struct timezone *__tz);
-libc_hidden_proto (__gettimeofday)
-libc_hidden_proto (gettimeofday)
 extern int __settimezone (const struct timezone *__tz)
 	attribute_hidden;
 extern int __adjtime (const struct timeval *__delta,
diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/mach/clock_gettime.c
similarity index 65%
rename from sysdeps/unix/clock_gettime.c
rename to sysdeps/mach/clock_gettime.c
index aa74e11703..0f872e5a45 100644
--- a/sysdeps/unix/clock_gettime.c
+++ b/sysdeps/mach/clock_gettime.c
@@ -1,5 +1,4 @@
-/* clock_gettime -- Get the current time from a POSIX clockid_t.  Unix version.
-   Copyright (C) 1999-2019 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -18,32 +17,28 @@
 
 #include <errno.h>
 #include <time.h>
-#include <sys/time.h>
+#include <mach.h>
 #include <shlib-compat.h>
 
-/* Get current value of CLOCK and store it in TP.  */
+/* Get the current time of day, putting it into *TS.
+   Returns 0 on success, -1 on errors.  */
 int
-__clock_gettime (clockid_t clock_id, struct timespec *tp)
+__clock_gettime (clockid_t clock_id, struct timespec *ts)
 {
-  int retval = -1;
-
-  switch (clock_id)
+  if (clock_id != CLOCK_REALTIME)
     {
-    case CLOCK_REALTIME:
-      {
-	struct timeval tv;
-	retval = __gettimeofday (&tv, NULL);
-	if (retval == 0)
-	  TIMEVAL_TO_TIMESPEC (&tv, tp);
-      }
-      break;
-
-    default:
-      __set_errno (EINVAL);
-      break;
+      errno = EINVAL;
+      return -1;
     }
 
-  return retval;
+  /* __host_get_time can only fail if passed an invalid host_t.
+     __mach_host_self could theoretically fail (producing an
+     invalid host_t) due to resource exhaustion, but we assume
+     this will never happen.  */
+  time_value_t tv;
+  __host_get_time (__mach_host_self (), &tv);
+  TIME_VALUE_TO_TIMESPEC (&tv, ts);
+  return 0;
 }
 libc_hidden_def (__clock_gettime)
 
diff --git a/sysdeps/mach/gettimeofday.c b/sysdeps/mach/gettimeofday.c
deleted file mode 100644
index f6df00306b..0000000000
--- a/sysdeps/mach/gettimeofday.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <stddef.h>
-#include <sys/time.h>
-#include <mach.h>
-
-/* Get the current time of day and timezone information,
-   putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.
-   Returns 0 on success, -1 on errors.  */
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
-  kern_return_t err;
-
-  if (tz != NULL)
-    *tz = (struct timezone){0, 0}; /* XXX */
-
-  if (err = __host_get_time (__mach_host_self (), (time_value_t *) tv))
-    {
-      errno = err;
-      return -1;
-    }
-  return 0;
-}
-libc_hidden_def (__gettimeofday)
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/posix/gettimeofday.c b/sysdeps/posix/gettimeofday.c
deleted file mode 100644
index 6bb98cd018..0000000000
--- a/sysdeps/posix/gettimeofday.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-
-/* Get the current time of day and timezone information,
-   putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.
-   Returns 0 on success, -1 on errors.  */
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
-  if (tv == NULL)
-    {
-      __set_errno (EINVAL);
-      return -1;
-    }
-
-  tv->tv_sec = (long int) time ((time_t *) NULL);
-  tv->tv_usec = 0L;
-
-  if (tz != NULL)
-    {
-      const time_t timer = tv->tv_sec;
-      struct tm tm;
-      const struct tm *tmp;
-
-      const long int save_timezone = __timezone;
-      const long int save_daylight = __daylight;
-      char *save_tzname[2];
-      save_tzname[0] = __tzname[0];
-      save_tzname[1] = __tzname[1];
-
-      tmp = localtime_r (&timer, &tm);
-
-      tz->tz_minuteswest = __timezone / 60;
-      tz->tz_dsttime = __daylight;
-
-      __timezone = save_timezone;
-      __daylight = save_daylight;
-      __tzname[0] = save_tzname[0];
-      __tzname[1] = save_tzname[1];
-
-      if (tmp == NULL)
-	return -1;
-    }
-
-  return 0;
-}
-libc_hidden_def (__gettimeofday)
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list
index 5fedd5733d..e28e801c7a 100644
--- a/sysdeps/unix/syscalls.list
+++ b/sysdeps/unix/syscalls.list
@@ -33,7 +33,6 @@ getrlimit	-	getrlimit	i:ip	__getrlimit	getrlimit
 getrusage	-	getrusage	i:ip	__getrusage	getrusage
 getsockname	-	getsockname	i:ibN	__getsockname	getsockname
 getsockopt	-	getsockopt	i:iiiBN	getsockopt
-gettimeofday	-	gettimeofday	i:pP	__gettimeofday	gettimeofday
 getuid		-	getuid		Ei:	__getuid	getuid
 ioctl		-	ioctl		i:iiI	__ioctl		ioctl
 kill		-	kill		i:ii	__kill		kill
diff --git a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
index 4ff74fa285..075af3d0d3 100644
--- a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
@@ -20,39 +20,39 @@
    putting it into *tv and *tz.  If tz is null, *tz is not filled.
    Returns 0 on success, -1 on errors.  */
 
-#include <sys/time.h>
+#include <time.h>
+#include <sysdep.h>
 
-#ifdef SHARED
-
-# include <dl-vdso.h>
-# include <sysdep-vdso.h>
+#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
+# define HAVE_VSYSCALL
+#endif
+#include <sysdep-vdso.h>
 
 /* Used as a fallback in the ifunc resolver if VDSO is not available
    and for libc.so internal __gettimeofday calls.  */
-
 static int
 __gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
 {
+  if (__glibc_unlikely (tz != 0))
+    memset (tz, 0, sizeof *tz);
+
   return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
 }
 
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <sysdep-vdso.h>
+
 # define INIT_ARCH()
-libc_ifunc_hidden (__gettimeofday, __gettimeofday,
-		   (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
-		    ?: __gettimeofday_vsyscall))
-libc_hidden_def (__gettimeofday)
+libc_ifunc (__gettimeofday,
+	    (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
+	    ?: __gettimeofday_vsyscall))
 
 #else
-
-# include <sysdep.h>
 int
 __gettimeofday (struct timeval *tv, struct timezone *tz)
 {
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+  return __gettimeofday_vsyscall (tv, tz);
 }
-libc_hidden_def (__gettimeofday)
-
 #endif
-
 weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/alpha/gettimeofday.c
similarity index 58%
rename from sysdeps/unix/sysv/linux/i386/gettimeofday.c
rename to sysdeps/unix/sysv/linux/alpha/gettimeofday.c
index f6faecb21e..262a3c2352 100644
--- a/sysdeps/unix/sysv/linux/i386/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/alpha/gettimeofday.c
@@ -1,5 +1,5 @@
-/* gettimeofday - get the time.  Linux/i386 version.
-   Copyright (C) 2015-2019 Free Software Foundation, Inc.
+/* gettimeofday -- Get the current time of day.  Linux/Alpha/tv64 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -16,20 +16,7 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifdef SHARED
-# define __gettimeofday __redirect___gettimeofday
-#endif
-
-#include <sys/time.h>
-
-#ifdef SHARED
-# undef __gettimeofday
-# define __gettimeofday_type __redirect___gettimeofday
-
-# undef libc_hidden_def
-# define libc_hidden_def(name) \
-  __hidden_ver1 (__gettimeofday_syscall, __GI___gettimeofday, \
-	       __gettimeofday_syscall);
-#endif
-
-#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
+/* We can use the generic implementation, but we have to override its
+   default symbol version.  */
+#define VERSION_gettimeofday GLIBC_2.1
+#include <time/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
index e6cc522dd1..f602d8dcf9 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
@@ -20,6 +20,8 @@
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
 
+#include <string.h>
+#include <time.h>
 #include <sys/time.h>
 #include <tv32-compat.h>
 
@@ -30,10 +32,13 @@ int
 attribute_compat_text_section
 __gettimeofday_tv32 (struct timeval32 *restrict tv32, void *restrict tz)
 {
-  struct timeval tv;
-  __gettimeofday (&tv, tz);
+  if (__glibc_unlikely (tz != 0))
+    memset (tz, 0, sizeof (struct timezone));
 
-  tv64_to_tv32 (tv32, &tv);
+  struct timespec ts;
+  __clock_gettime (CLOCK_REALTIME, &ts);
+
+  ts64_to_tv32 (tv32, &ts);
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
deleted file mode 100644
index c9597d6405..0000000000
--- a/sysdeps/unix/sysv/linux/gettimeofday.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
-
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <sys/time.h>
-
-#undef __gettimeofday
-
-#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
-# define HAVE_VSYSCALL
-#endif
-#include <sysdep-vdso.h>
-
-/* Get the current time of day and timezone information,
-   putting it into *tv and *tz.  If tz is null, *tz is not filled.
-   Returns 0 on success, -1 on errors.  */
-int
-___gettimeofday (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
-}
-
-#ifdef VERSION_gettimeofday
-weak_alias (___gettimeofday, __wgettimeofday);
-default_symbol_version (___gettimeofday, __gettimeofday, VERSION_gettimeofday);
-default_symbol_version (__wgettimeofday,   gettimeofday, VERSION_gettimeofday);
-libc_hidden_ver (___gettimeofday, __gettimeofday);
-libc_hidden_ver (___gettimeofday, gettimeofday);
-#else
-strong_alias (___gettimeofday, __gettimeofday)
-weak_alias (___gettimeofday, gettimeofday)
-libc_hidden_def (__gettimeofday)
-libc_hidden_weak (gettimeofday)
-#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 13a1fd292a..02486dee3a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -15,71 +15,40 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if defined SHARED && !defined __powerpc64__
-# define __gettimeofday __redirect___gettimeofday
-#else
-# define __redirect___gettimeofday __gettimeofday
-#endif
-
-#include <sys/time.h>
-
-#ifdef SHARED
-
-# include <dl-vdso.h>
-# include <libc-vdso.h>
-# include <dl-machine.h>
-# include <sysdep.h>
-
-# ifndef __powerpc64__
-#  undef __gettimeofday
-
-int
-__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
-}
-
-/* __GI___gettimeofday is defined as hidden and for ppc32 it enables the
-   compiler make a local call (symbol@local) for internal GLIBC usage. It
-   means the PLT won't be used and the ifunc resolver will be called directly.
-   For ppc64 a call to a function in another translation unit might use a
-   different toc pointer thus disallowing direct branchess and making internal
-   ifuncs calls safe.  */
-#  undef libc_hidden_def
-#  define libc_hidden_def(name)					\
-  __hidden_ver1 (__gettimeofday_vsyscall, __GI___gettimeofday,	\
-	       __gettimeofday_vsyscall);
+#include <time.h>
+#include <sysdep.h>
 
-# endif /* !__powerpc64__  */
+#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
+# define HAVE_VSYSCALL
+#endif
+#include <sysdep-vdso.h>
 
 static int
 __gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
 {
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+  if (__glibc_unlikely (tz != 0))
+    memset (tz, 0, sizeof *tz);
+
+  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
 }
 
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
 # define INIT_ARCH() \
   void *vdso_gettimeofday = get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
 
 /* If the vDSO is not available we fall back syscall.  */
-libc_ifunc_hidden (__redirect___gettimeofday, __gettimeofday,
-		   vdso_gettimeofday
-		   ? VDSO_IFUNC_RET (vdso_gettimeofday)
-		   : (void *) __gettimeofday_syscall);
-libc_hidden_def (__gettimeofday)
-
+libc_ifunc (__gettimeofday,
+	    vdso_gettimeofday
+	    ? VDSO_IFUNC_RET (vdso_gettimeofday)
+	    : (void *) __gettimeofday_syscall);
 #else
-
-# include <sysdep.h>
-# include <errno.h>
-
 int
 __gettimeofday (struct timeval *tv, struct timezone *tz)
 {
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+  return __gettimeofday_syscall (tv, tz);
 }
-libc_hidden_def (__gettimeofday)
-
 #endif
 weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
index 2d9248ee26..cb20e358d8 100644
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -16,47 +16,38 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <sys/time.h>
+#include <time.h>
+#include <sysdep.h>
 
-#ifdef SHARED
-
-# include <dl-vdso.h>
-# include <errno.h>
-# include <sysdep-vdso.h>
-# include <sysdep-vdso.h>
+#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
+# define HAVE_VSYSCALL
+#endif
+#include <sysdep-vdso.h>
 
 static int
 __gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
 {
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+  if (__glibc_unlikely (tz != 0))
+    memset (tz, 0, sizeof *tz);
+
+  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
 }
 
-# ifndef __gettimeofday_type
-/* The i386 gettimeofday.c includes this file with a defined
-   __gettimeofday_type macro.  For x86_64 we have to define it to __gettimeofday
-   as the internal symbol is the ifunc'ed one.  */
-#  define __gettimeofday_type __gettimeofday
-# endif
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <libc-vdso.h>
 
 # define INIT_ARCH()
 /* If the vDSO is not available we fall back to syscall.  */
-libc_ifunc_hidden (__gettimeofday_type, __gettimeofday,
-		   (get_vdso_symbol ("__vdso_gettimeofday")
-		    ?: __gettimeofday_syscall));
-libc_hidden_def (__gettimeofday)
+libc_ifunc (__gettimeofday,
+	    (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
+	    ?: __gettimeofday_syscall));
 
 #else
-
-# include <sysdep.h>
-# include <errno.h>
-
 int
 __gettimeofday (struct timeval *tv, struct timezone *tz)
 {
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+  return __gettimeofday_syscall (tv, tz);
 }
-libc_hidden_def (__gettimeofday)
-
 #endif
 weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c
new file mode 100644
index 0000000000..cd342f33ad
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
index b44f6f99e9..786c884232 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
@@ -1,6 +1,5 @@
 # File name	Caller	Syscall name	# args	Strong name	Weak names
 
-gettimeofday	-	gettimeofday:__vdso_gettimeofday@LINUX_2.6	i:pP	__gettimeofday	gettimeofday
 personality	EXTRA	personality	Ei:i	__personality	personality
 posix_fadvise64	-	fadvise64	Vi:iiii	posix_fadvise	posix_fadvise64
 time		-	time:__vdso_time@LINUX_2.6			Ei:P	time
diff --git a/time/gettimeofday.c b/time/gettimeofday.c
index 1fd2669abd..e8055b397d 100644
--- a/time/gettimeofday.c
+++ b/time/gettimeofday.c
@@ -15,20 +15,32 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
+#include <string.h>
+#include <time.h>
 #include <sys/time.h>
 
-/* Get the current time of day and timezone information,
-   putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.
+/* Get the current time of day, putting it into *TV.
+   If *TZ is not NULL, clear it.
    Returns 0 on success, -1 on errors.  */
 int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
+___gettimeofday (struct timeval *tv, struct timezone *tz)
 {
-  __set_errno (ENOSYS);
-  return -1;
+  if (__glibc_unlikely (tz != 0))
+    memset (tz, 0, sizeof *tz);
+
+  struct timespec ts;
+  if (__clock_gettime (CLOCK_REALTIME, &ts))
+    return -1;
+
+  TIMESPEC_TO_TIMEVAL (tv, &ts);
+  return 0;
 }
-libc_hidden_def (__gettimeofday)
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
 
-stub_warning (gettimeofday)
+#ifdef VERSION_gettimeofday
+weak_alias (___gettimeofday, __wgettimeofday);
+default_symbol_version (___gettimeofday, __gettimeofday, VERSION_gettimeofday);
+default_symbol_version (__wgettimeofday,   gettimeofday, VERSION_gettimeofday);
+#else
+strong_alias (___gettimeofday, __gettimeofday)
+weak_alias (___gettimeofday, gettimeofday)
+#endif
-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 06/11] Change most internal uses of time to __clock_gettime.
  2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
                   ` (6 preceding siblings ...)
  2019-10-25 12:09 ` [PATCH v2 02/11] Change most internal uses of __gettimeofday to __clock_gettime Adhemerval Zanella
@ 2019-10-25 12:09 ` Adhemerval Zanella
  2019-10-25 21:22   ` Lukasz Majewski
  2019-10-25 12:09 ` [PATCH v2 09/11] Use clock_gettime to implement gettimeofday Adhemerval Zanella
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:09 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski

As for gettimeofday, time will be implemented based on clock_gettime
on all platforms and internal code should use clock_gettime
directly.  In addition to removing a layer of indirection, this will
allow us to remove the PLT-bypass gunk for gettimeofday.

The changed code always assumes __clock_gettime (CLOCK_REALTIME)
or __clock_gettime (CLOCK_REALTIME_COURSE) (for Linux case) cannot
fail, using the same rationale for gettimeofday change.  And internal
helper was added (time_now).

Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
powerpc64-linux-gnu, and powerpc-linux-gnu.
---
 include/time.h                         | 11 +++-
 misc/syslog.c                          |  2 +-
 nscd/nscd_gethst_r.c                   |  2 +-
 nscd/nscd_helper.c                     |  4 +-
 string/strfry.c                        |  4 +-
 sysdeps/unix/sysv/linux/check_native.c |  2 +-
 sysdeps/unix/sysv/linux/check_pf.c     |  2 +-
 sysdeps/unix/sysv/linux/getsysstats.c  |  2 +-
 sysdeps/unix/sysv/linux/i386/time.c    | 34 ------------
 sysdeps/unix/sysv/linux/ifaddrs.c      |  2 +-
 sysdeps/unix/sysv/linux/powerpc/time.c | 71 ++++++++------------------
 sysdeps/unix/sysv/linux/x86/time.c     | 34 ++++--------
 time/getdate.c                         |  2 +-
 time/time.c                            |  1 -
 14 files changed, 52 insertions(+), 121 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/i386/time.c

diff --git a/include/time.h b/include/time.h
index d93b16a781..3eac3dcb8d 100644
--- a/include/time.h
+++ b/include/time.h
@@ -7,12 +7,12 @@
 # include <stdbool.h>
 # include <time/mktime-internal.h>
 # include <endian.h>
+# include <time-internal.h>
 
 extern __typeof (strftime_l) __strftime_l;
 libc_hidden_proto (__strftime_l)
 extern __typeof (strptime_l) __strptime_l;
 
-libc_hidden_proto (time)
 libc_hidden_proto (asctime)
 libc_hidden_proto (mktime)
 libc_hidden_proto (timelocal)
@@ -236,5 +236,14 @@ valid_timespec64_to_timeval (const struct __timespec64 ts64)
 
   return tv;
 }
+
+/* Helper function to get time in seconds, similar to time.  */
+static inline time_t
+time_now (void)
+{
+  struct timespec ts;
+  __clock_gettime (TIME_CLOCK_GETTIME_CLOCKID, &ts);
+  return ts.tv_sec;
+}
 #endif
 #endif
diff --git a/misc/syslog.c b/misc/syslog.c
index cf2deef533..fd6537edf6 100644
--- a/misc/syslog.c
+++ b/misc/syslog.c
@@ -205,7 +205,7 @@ __vsyslog_internal(int pri, const char *fmt, va_list ap,
 	  {
 	    __fsetlocking (f, FSETLOCKING_BYCALLER);
 	    fprintf (f, "<%d>", pri);
-	    now = time (NULL);
+	    now = time_now ();
 	    f->_IO_write_ptr += __strftime_l (f->_IO_write_ptr,
 					      f->_IO_write_end
 					      - f->_IO_write_ptr,
diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c
index 18c6be0d48..8eca90fd52 100644
--- a/nscd/nscd_gethst_r.c
+++ b/nscd/nscd_gethst_r.c
@@ -113,7 +113,7 @@ __nscd_get_nl_timestamp (void)
   if (map == NULL
       || (map != NO_MAPPING
 	  && map->head->nscd_certainly_running == 0
-	  && map->head->timestamp + MAPPING_TIMEOUT < time (NULL)))
+	  && map->head->timestamp + MAPPING_TIMEOUT < time_now ()))
     map = __nscd_get_mapping (GETFDHST, "hosts", &__hst_map_handle.mapped);
 
   if (map == NO_MAPPING)
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index 7361fe2e0a..d50615e13e 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -348,7 +348,7 @@ __nscd_get_mapping (request_type type, const char *key,
 	     thread got stuck.  */
 	  || __builtin_expect (! head->nscd_certainly_running
 			       && (head->timestamp + MAPPING_TIMEOUT
-				   < time (NULL)), 0))
+				   < time_now ()), 0))
 	{
 	out_unmap:
 	  __munmap (mapping, mapsize);
@@ -414,7 +414,7 @@ __nscd_get_map_ref (request_type type, const char *name,
       /* If not mapped or timestamp not updated, request new map.  */
       if (cur == NULL
 	  || (cur->head->nscd_certainly_running == 0
-	      && cur->head->timestamp + MAPPING_TIMEOUT < time (NULL))
+	      && cur->head->timestamp + MAPPING_TIMEOUT < time_now ())
 	  || cur->head->data_size > cur->datasize)
 	cur = __nscd_get_mapping (type, name,
 				  (struct mapped_database **) &mapptr->mapped);
diff --git a/string/strfry.c b/string/strfry.c
index 6306f06ae4..8b293af185 100644
--- a/string/strfry.c
+++ b/string/strfry.c
@@ -17,7 +17,7 @@
 
 #include <string.h>
 #include <stdlib.h>
-#include <time.h>
+#include <random-bits.h>
 #include <unistd.h>
 
 char *
@@ -30,7 +30,7 @@ strfry (char *string)
     {
       static char state[32];
       rdata.state = NULL;
-      __initstate_r (time (NULL) ^ getpid (),
+      __initstate_r (random_bits (),
 		     state, sizeof (state), &rdata);
       init = 1;
     }
diff --git a/sysdeps/unix/sysv/linux/check_native.c b/sysdeps/unix/sysv/linux/check_native.c
index 3e57629d8c..82e2a0d83f 100644
--- a/sysdeps/unix/sysv/linux/check_native.c
+++ b/sysdeps/unix/sysv/linux/check_native.c
@@ -69,7 +69,7 @@ __check_native (uint32_t a1_index, int *a1_native,
   req.nlh.nlmsg_type = RTM_GETLINK;
   req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
   req.nlh.nlmsg_pid = 0;
-  req.nlh.nlmsg_seq = time (NULL);
+  req.nlh.nlmsg_seq = time_now ();
   req.g.rtgen_family = AF_UNSPEC;
 
   assert (sizeof (req) - offsetof (struct req, pad) == 3);
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
index 97a30f63fc..bcb9c602aa 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -126,7 +126,7 @@ make_request (int fd, pid_t pid)
   req.nlh.nlmsg_type = RTM_GETADDR;
   req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
   req.nlh.nlmsg_pid = 0;
-  req.nlh.nlmsg_seq = time (NULL);
+  req.nlh.nlmsg_seq = time_now ();
   req.g.rtgen_family = AF_UNSPEC;
 
   assert (sizeof (req) - offsetof (struct req, pad) == 3);
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index 41ceb9a320..6457193227 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -128,7 +128,7 @@ __get_nprocs (void)
   static int cached_result = -1;
   static time_t timestamp;
 
-  time_t now = time (NULL);
+  time_t now = time_now ();
   time_t prev = timestamp;
   atomic_read_barrier ();
   if (now == prev && cached_result > -1)
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
deleted file mode 100644
index 1bbe079f65..0000000000
--- a/sysdeps/unix/sysv/linux/i386/time.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* time -- Get number of seconds since Epoch.  Linux/i386 version.
-   Copyright (C) 2015-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifdef SHARED
-# define time __redirect_time
-#endif
-
-#include <time.h>
-
-#ifdef SHARED
-# undef time
-# define time_type __redirect_time
-
-# undef libc_hidden_def
-# define libc_hidden_def(name)  \
-  __hidden_ver1 (__time_syscall, __GI_time, __time_syscall);
-#endif
-
-#include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
index 0c36001660..2b89c7a3af 100644
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
@@ -102,7 +102,7 @@ __netlink_sendreq (struct netlink_handle *h, int type)
   struct sockaddr_nl nladdr;
 
   if (h->seq == 0)
-    h->seq = time (NULL);
+    h->seq = time_now ();
 
   req.nlh.nlmsg_len = sizeof (req);
   req.nlh.nlmsg_type = type;
diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c
index e957b81751..80a4c73416 100644
--- a/sysdeps/unix/sysv/linux/powerpc/time.c
+++ b/sysdeps/unix/sysv/linux/powerpc/time.c
@@ -16,68 +16,37 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifdef SHARED
-# ifndef __powerpc64__
-#  define time __redirect_time
-# else
-#  define __redirect_time time
-# endif
-
-# include <time.h>
-# include <sysdep.h>
-# include <dl-vdso.h>
-# include <libc-vdso.h>
-# include <dl-machine.h>
+#include <time.h>
+#include <sysdep.h>
 
-# ifndef __powerpc64__
-#  undef time
+#ifdef HAVE_TIME_VSYSCALL
+# define HAVE_VSYSCALL
+#endif
+#include <sysdep-vdso.h>
 
-time_t
-__time_vsyscall (time_t *t)
+static time_t
+time_vsyscall (time_t *t)
 {
   return INLINE_VSYSCALL (time, 1, t);
 }
 
-/* __GI_time is defined as hidden and for ppc32 it enables the
-   compiler make a local call (symbol@local) for internal GLIBC usage. It
-   means the PLT won't be used and the ifunc resolver will be called directly.
-   For ppc64 a call to a function in another translation unit might use a
-   different toc pointer thus disallowing direct branchess and making internal
-   ifuncs calls safe.  */
-#  undef libc_hidden_def
-#  define libc_hidden_def(name)					\
-  __hidden_ver1 (__time_vsyscall, __GI_time, __time_vsyscall);
-
-# endif /* !__powerpc64__  */
-
-static time_t
-time_syscall (time_t *t)
-{
-  struct timeval tv;
-  time_t result;
-
-  if (INLINE_VSYSCALL (gettimeofday, 2, &tv, NULL) < 0)
-    result = (time_t) -1;
-  else
-    result = (time_t) tv.tv_sec;
-
-  if (t != NULL)
-    *t = result;
-  return result;
-}
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <libc-vdso.h>
 
 # define INIT_ARCH() \
   void *vdso_time = get_vdso_symbol (HAVE_TIME_VSYSCALL);
 
 /* If the vDSO is not available we fall back to the syscall.  */
-libc_ifunc_hidden (__redirect_time, time,
-		   vdso_time
-		   ? VDSO_IFUNC_RET (vdso_time)
-		   : (void *) time_syscall);
-libc_hidden_def (time)
+libc_ifunc (time,
+	    vdso_time
+	    ? VDSO_IFUNC_RET (vdso_time)
+	    : (void *) time_vsyscall);
 
 #else
-
-#include <time/time.c>
-
+time_t
+time (time_t *t)
+{
+  return time_vsyscall (t);
+}
 #endif /* !SHARED */
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
index 2e47661be3..4a03c46d21 100644
--- a/sysdeps/unix/sysv/linux/x86/time.c
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -17,43 +17,31 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <time.h>
+#include <sysdep.h>
 
-#ifdef SHARED
-
-#include <dl-vdso.h>
-#include <errno.h>
+#ifdef HAVE_TIME_VSYSCALL
+# define HAVE_VSYSCALL
+#endif
 #include <sysdep-vdso.h>
 
 static time_t
-__time_syscall (time_t *t)
+time_vsyscall (time_t *t)
 {
-  INTERNAL_SYSCALL_DECL (err);
-  return INTERNAL_SYSCALL (time, err, 1, t);
+  return INLINE_VSYSCALL (time, 1, t);
 }
 
-# ifndef time_type
-/* The i386 time.c includes this file with a defined time_type macro.
-   For x86_64 we have to define it to time as the internal symbol is the
-   ifunc'ed one.  */
-#  define time_type time
-# endif
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <libc-vdso.h>
 
 #undef INIT_ARCH
 #define INIT_ARCH()
 /* If the vDSO is not available we fall back on the syscall.  */
-libc_ifunc_hidden (time_type, time,
-		   (get_vdso_symbol ("__vdso_time") ?: __time_syscall))
-libc_hidden_def (time)
-
+libc_ifunc (time, (get_vdso_symbol ("__vdso_time") ?: time_vsyscall))
 #else
-
-# include <sysdep.h>
-
 time_t
 time (time_t *t)
 {
-  INTERNAL_SYSCALL_DECL (err);
-  return INTERNAL_SYSCALL (time, err, 1, t);
+  return time_vsyscall (t);
 }
-
 #endif
diff --git a/time/getdate.c b/time/getdate.c
index 305e7d9dc4..8e15af9f15 100644
--- a/time/getdate.c
+++ b/time/getdate.c
@@ -219,7 +219,7 @@ __getdate_r (const char *string, struct tm *tp)
     return 7;
 
   /* Get current time.  */
-  timer = time (NULL);
+  timer = time_now ();
   __localtime_r (&timer, &tm);
 
   /* If only the weekday is given, today is assumed if the given day
diff --git a/time/time.c b/time/time.c
index 09a2b4fc88..cfa92cbbb8 100644
--- a/time/time.c
+++ b/time/time.c
@@ -29,4 +29,3 @@ time (time_t *timer)
     *timer = ts.tv_sec;
   return ts.tv_sec;
 }
-libc_hidden_def (time)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 04/11] Use clock_settime to implement settimeofday.
  2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2019-10-25 12:09 ` [PATCH v2 11/11] Revise the documentation of simple calendar time Adhemerval Zanella
@ 2019-10-25 12:09 ` Adhemerval Zanella
  2019-10-25 15:28   ` Lukasz Majewski
                     ` (2 more replies)
  2019-10-25 12:09 ` [PATCH v2 07/11] Consolidate and deprecate ftime Adhemerval Zanella
                   ` (5 subsequent siblings)
  10 siblings, 3 replies; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:09 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski, Zack Weinberg

From: Zack Weinberg <zackw@panix.com>

Use clock_settime to implement settimeofday.

Changes from previous version:

  - Added a NEWS entry.

--

Unconditionally, on all ports, use clock_settime to implement
settimeofday.  Remove sysdeps/unix/clock_settime.c, which implemented
clock_settime by calling settimeofday; new OS ports must henceforth
provide a real implementation of clock_settime.

Hurd had a real implementation of settimeofday but not of
clock_settime; this patch converts it into an implementation of
clock_settime.  It only supports CLOCK_REALTIME and microsecond
resolution; Hurd/Mach does not appear to have any support for
finer-resolution clocks.

The vestigial "set time zone" feature of settimeofday complicates the
generic settimeofday implementation a little.  The only remaining uses
of this feature that aren't just bugs, are using it to inform the
Linux kernel of the offset between the hardware clock and UTC, on
systems where the hardware clock doesn't run in UTC (usually because
of dual-booting with Windows).  There currently isn't any other way to
do this.  However, the callers that do this call settimeofday with
_only_ the timezone argument non-NULL.  Therefore, glibc's new
behavior is: callers of settimeofday must supply one and only one of
the two arguments.  If both arguments are non-NULL, or both arguments
are NULL, the call fails and sets errno to EINVAL.

When only the timeval argument is supplied, settimeofday calls
__clock_settime(CLOCK_REALTIME), same as stime.

When only the timezone argument is supplied, settimeofday calls a new
internal function called __settimezone.  On Linux, only, this function
will pass the timezone structure to the settimeofday system call.  On
all other operating systems, and on Linux architectures that don't
define __NR_settimeofday, __settimezone is a stub that always sets
errno to ENOSYS and returns -1.

The settimeoday syscall is enabled on Linux by the flag
COMPAT_32BIT_TIME, which is an option to either 32-bits ABIs or COMPAT
builds (defined usually by 64-bit kernels that want to support 32-bit
 ABIs, such as x86).  The idea to future 64-bit time_t only ABIs
is to not provide settimeofday syscall.

The same semantics are implemented for Linux/Alpha's GLIBC_2.0 compat
symbol for settimeofday.

There are no longer any internal callers of __settimeofday, so the
internal prototype is removed.

Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
---
 NEWS                                          | 24 +++++++++
 include/sys/time.h                            |  3 +-
 sysdeps/{unix => mach/hurd}/clock_settime.c   | 51 ++++++++-----------
 sysdeps/unix/syscalls.list                    |  1 -
 .../unix/sysv/linux/alpha/osf_settimeofday.c  | 16 ++++--
 sysdeps/unix/sysv/linux/alpha/settimeofday.c  | 22 ++++++++
 sysdeps/unix/sysv/linux/alpha/syscalls.list   |  1 -
 sysdeps/unix/sysv/linux/settimezone.c         | 36 +++++++++++++
 time/Makefile                                 |  8 +--
 time/settimeofday.c                           | 24 +++++++--
 .../hurd/settimeofday.c => time/settimezone.c | 34 ++-----------
 11 files changed, 147 insertions(+), 73 deletions(-)
 rename sysdeps/{unix => mach/hurd}/clock_settime.c (65%)
 create mode 100644 sysdeps/unix/sysv/linux/alpha/settimeofday.c
 create mode 100644 sysdeps/unix/sysv/linux/settimezone.c
 rename sysdeps/mach/hurd/settimeofday.c => time/settimezone.c (52%)

diff --git a/NEWS b/NEWS
index 8727b5e7f0..0b1476e745 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,30 @@ Deprecated and removed features, and other changes affecting compatibility:
   binaries and it has been removed from <time.h> header.  This function
   has been deprecated in favor of clock_settime.
 
+* The settimeofday function can still be used to set a system-wide time
+  zone when the operating system supports it.  This is because the Linux
+  kernel reused the API, on some architectures, to describe a system-wide
+  time-zone-like offset between the software clock maintained by the kernel,
+  and the “RTC” clock that keeps time when the system is shut down.
+
+  However, to reduce the odds of this offset being set by accident,
+  settimeofday can no longer be used to set the time and the offset
+  simultaneously.  If both of its two arguments are non-null, the call
+  will fail (setting errno to EINVAL).
+
+  Callers attempting to set this offset should also be prepared for the call
+  to fail and set errno to ENOSYS; this already happens on the Hurd and on
+  some Linux architectures.  The Linux kernel maintainers are discussing a
+  more principled replacement for the reused API.  After a replacement
+  becomes available, we will change settimeofday to fail with ENOSYS on all
+  platforms when its ‘tzp’ argument is not a null pointer.
+
+  Note that settimeofday itself is obsolescent according to POSIX.
+  Programs that set the system time should use clock_settime and/or
+  the adjtime family of functions instead.  We may also cease to make
+  settimeofday available to newly linked binaries after there is a
+  replacement for Linux’s time-zone-like offset API.
+
 Changes to build and runtime requirements:
 
   [Add changes to build and runtime requirements here]
diff --git a/include/sys/time.h b/include/sys/time.h
index 57208afa82..c0e30e70fb 100644
--- a/include/sys/time.h
+++ b/include/sys/time.h
@@ -24,8 +24,7 @@ extern int __gettimeofday (struct timeval *__tv,
 			   struct timezone *__tz);
 libc_hidden_proto (__gettimeofday)
 libc_hidden_proto (gettimeofday)
-extern int __settimeofday (const struct timeval *__tv,
-			   const struct timezone *__tz)
+extern int __settimezone (const struct timezone *__tz)
 	attribute_hidden;
 extern int __adjtime (const struct timeval *__delta,
 		      struct timeval *__olddelta);
diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/mach/hurd/clock_settime.c
similarity index 65%
rename from sysdeps/unix/clock_settime.c
rename to sysdeps/mach/hurd/clock_settime.c
index 18d7c99864..02239c097a 100644
--- a/sysdeps/unix/clock_settime.c
+++ b/sysdeps/mach/hurd/clock_settime.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2019 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -17,38 +17,31 @@
 
 #include <errno.h>
 #include <time.h>
-#include <sys/time.h>
+#include <hurd.h>
+#include <hurd/port.h>
 #include <shlib-compat.h>
 
-/* Set CLOCK to value TP.  */
+/* Set the current time of day.
+   This call is restricted to the super-user.  */
 int
-__clock_settime (clockid_t clock_id, const struct timespec *tp)
+__clock_settime (clockid_t clock_id, const struct timespec *ts)
 {
-  int retval = -1;
-
-  /* Make sure the time cvalue is OK.  */
-  if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000)
-    {
-      __set_errno (EINVAL);
-      return -1;
-    }
-
-  switch (clock_id)
-    {
-    case CLOCK_REALTIME:
-      {
-	struct timeval tv;
-	TIMESPEC_TO_TIMEVAL (&tv, tp);
-	retval = __settimeofday (&tv, NULL);
-      }
-      break;
-
-    default:
-      __set_errno (EINVAL);
-      break;
-    }
-
-  return retval;
+  error_t err;
+  mach_port_t hostpriv;
+  time_value_t tv;
+
+  if (clock_id != CLOCK_REALTIME)
+    return __hurd_fail (EINVAL);
+
+  err = __get_privileged_ports (&hostpriv, NULL);
+  if (err)
+    return __hurd_fail (EPERM);
+
+  TIMESPEC_TO_TIME_VALUE (&tv, ts);
+  err = __host_set_time (hostpriv, tv);
+  __mach_port_deallocate (__mach_task_self (), hostpriv);
+
+  return __hurd_fail (err);
 }
 libc_hidden_def (__clock_settime)
 
diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list
index 61e5360b4d..5fedd5733d 100644
--- a/sysdeps/unix/syscalls.list
+++ b/sysdeps/unix/syscalls.list
@@ -76,7 +76,6 @@ setreuid	-	setreuid	i:ii	__setreuid	setreuid
 setrlimit	-	setrlimit	i:ip	__setrlimit setrlimit
 setsid		-	setsid		i:	__setsid	setsid
 setsockopt	-	setsockopt	i:iiibn	setsockopt	__setsockopt
-settimeofday	-	settimeofday	i:PP	__settimeofday	settimeofday
 setuid		-	setuid		i:i	__setuid	setuid
 shutdown	-	shutdown	i:ii	shutdown
 sigaction	-	sigaction	i:ipp	__sigaction	sigaction
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
index fb2a36df19..914f5ac57b 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
@@ -32,9 +32,19 @@ attribute_compat_text_section
 __settimeofday_tv32 (const struct timeval32 *tv32,
                      const struct timezone *tz)
 {
-  struct timeval tv;
-  tv32_to_tv64 (&tv, tv32);
-  return __settimeofday (&tv, tz);
+  if (__glibc_unlikely (tz != 0))
+    {
+      if (tv32 != 0)
+	{
+	  __set_errno (EINVAL);
+	  return -1;
+	}
+      return __settimezone (tz);
+    }
+
+  struct timespec ts;
+  tv32_to_ts64 (&ts, tv32);
+  return __clock_settime (CLOCK_REALTIME, &ts);
 }
 
 compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0);
diff --git a/sysdeps/unix/sysv/linux/alpha/settimeofday.c b/sysdeps/unix/sysv/linux/alpha/settimeofday.c
new file mode 100644
index 0000000000..36a6901e4e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/settimeofday.c
@@ -0,0 +1,22 @@
+/* settimeofday -- Set the current time of day.  Linux/Alpha/tv64 version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* We can use the generic implementation, but we have to override its
+   default symbol version.  */
+#define VERSION_settimeofday GLIBC_2.1
+#include <time/settimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list
index c786aa751e..95a27e18e8 100644
--- a/sysdeps/unix/sysv/linux/alpha/syscalls.list
+++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list
@@ -24,7 +24,6 @@ pciconfig_iobase EXTRA	pciconfig_iobase 3	__pciconfig_iobase pciconfig_iobase
 
 # timeval64 entry points (see osf_*.c for GLIBC_2.0 timeval32 equivalents)
 gettimeofday	-	gettimeofday	i:pP	__GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
-settimeofday	-	settimeofday	i:PP	__settimeofday	settimeofday@@GLIBC_2.1
 getitimer	-	getitimer	i:ip	__getitimer	getitimer@@GLIBC_2.1
 setitimer	-	setitimer	i:ipP	__setitimer	setitimer@@GLIBC_2.1
 utimes		-	utimes		i:sp	__utimes	utimes@@GLIBC_2.1
diff --git a/sysdeps/unix/sysv/linux/settimezone.c b/sysdeps/unix/sysv/linux/settimezone.c
new file mode 100644
index 0000000000..90b38307c6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/settimezone.c
@@ -0,0 +1,36 @@
+/* Obsolete set system time.  Linux version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <sys/time.h>
+#include <sysdep.h>
+
+/* Set the system-wide timezone.
+   This call is restricted to the super-user.
+   This operation is considered obsolete, kernel support may not be
+   available on all architectures.  */
+int
+__settimezone (const struct timezone *tz)
+{
+#ifdef __NR_settimeofday
+  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
+#else
+  __set_errno (ENOSYS);
+  return -1
+#endif
+}
diff --git a/time/Makefile b/time/Makefile
index ad8844ea34..6de4e418d9 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -31,13 +31,13 @@ headers := time.h sys/time.h sys/timeb.h bits/time.h			\
 
 routines := offtime asctime clock ctime ctime_r difftime \
 	    gmtime localtime mktime time		 \
-	    gettimeofday settimeofday adjtime tzset	 \
-	    tzfile getitimer setitimer			 \
+	    gettimeofday settimeofday settimezone	 \
+	    adjtime tzset tzfile getitimer setitimer	 \
 	    stime dysize timegm ftime			 \
 	    getdate strptime strptime_l			 \
 	    strftime wcsftime strftime_l wcsftime_l	 \
-	    timespec_get 	 			 \
-	    clock_getcpuclockid clock_getres 		 \
+	    timespec_get				 \
+	    clock_getcpuclockid clock_getres		 \
 	    clock_gettime clock_settime clock_nanosleep
 
 aux :=	    era alt_digit lc-time-cleanup
diff --git a/time/settimeofday.c b/time/settimeofday.c
index 6aa4832d65..ad57ad41a1 100644
--- a/time/settimeofday.c
+++ b/time/settimeofday.c
@@ -16,6 +16,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
+#include <time.h>
 #include <sys/time.h>
 
 /* Set the current time of day and timezone information.
@@ -23,9 +24,24 @@
 int
 __settimeofday (const struct timeval *tv, const struct timezone *tz)
 {
-  __set_errno (ENOSYS);
-  return -1;
+  if (__glibc_unlikely (tz != 0))
+    {
+      if (tv != 0)
+	{
+	  __set_errno (EINVAL);
+	  return -1;
+	}
+      return __settimezone (tz);
+    }
+
+  struct timespec ts;
+  TIMEVAL_TO_TIMESPEC (tv, &ts);
+  return __clock_settime (CLOCK_REALTIME, &ts);
 }
-stub_warning (settimeofday)
 
-weak_alias (__settimeofday, settimeofday)
+#ifdef VERSION_settimeofday
+weak_alias (__settimeofday, __settimeofday_w);
+default_symbol_version (__settimeofday_w, settimeofday, VERSION_settimeofday);
+#else
+weak_alias (__settimeofday, settimeofday);
+#endif
diff --git a/sysdeps/mach/hurd/settimeofday.c b/time/settimezone.c
similarity index 52%
rename from sysdeps/mach/hurd/settimeofday.c
rename to time/settimezone.c
index 31bffcad9d..b9969c9dd5 100644
--- a/sysdeps/mach/hurd/settimeofday.c
+++ b/time/settimezone.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
+/* Copyright (C) 2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -17,36 +17,12 @@
 
 #include <errno.h>
 #include <sys/time.h>
-#include <hurd.h>
-#include <hurd/port.h>
 
-/* Set the current time of day and timezone information.
+/* Set the system-wide timezone.
    This call is restricted to the super-user.  */
 int
-__settimeofday (const struct timeval *tv, const struct timezone *tz)
+__settimezone (const struct timezone *tz)
 {
-  error_t err;
-  mach_port_t hostpriv;
-
-  if (tz != NULL)
-    {
-      errno = ENOSYS;
-      return -1;
-    }
-
-  err = __get_privileged_ports (&hostpriv, NULL);
-  if (err)
-    return __hurd_fail (EPERM);
-
-  /* `time_value_t' and `struct timeval' are in fact identical with the
-     names changed.  */
-  err = __host_set_time (hostpriv, *(time_value_t *) tv);
-  __mach_port_deallocate (__mach_task_self (), hostpriv);
-
-  if (err)
-    return __hurd_fail (err);
-
-  return 0;
+  __set_errno (ENOSYS);
+  return -1;
 }
-
-weak_alias (__settimeofday, settimeofday)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 05/11] Use clock_gettime to implement time.
  2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
                   ` (8 preceding siblings ...)
  2019-10-25 12:09 ` [PATCH v2 09/11] Use clock_gettime to implement gettimeofday Adhemerval Zanella
@ 2019-10-25 12:09 ` Adhemerval Zanella
  2019-10-25 20:59   ` Lukasz Majewski
  2019-10-25 12:09 ` [PATCH v2 08/11] Use clock_gettime to implement timespec_get Adhemerval Zanella
  10 siblings, 1 reply; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:09 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski

Use clock_gettime to implement time.

Changes from previous version:

  - Do not remove Linux arch-specific implementations.

  - Use CLOCK_REALTIME_COARSE for Linux.

--

Change the default implementation of time to call clock_gettime,
to align with new Linux ports that are expected to only implement
__NR_clock_gettime.  Arch-specific implementation that either call
the time vDSO or route to gettimeofday vDSO are not removed.

Also for Linux, CLOCK_REALTIME_COARSE is used instead of generic
CLOCK_REALTIME clockid.  This takes less CPU time and its behavior
better matches what the current glibc does.

Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.

Co-authored-by: Zack Weinberg <zackw@panix.com>
---
 sysdeps/unix/sysv/linux/powerpc/time.c        |  2 +-
 .../sysv/linux/{time.c => time-internal.h}    | 31 ++++---------------
 sysdeps/posix/time.c => time/time-internal.h  | 28 +++--------------
 time/time.c                                   | 13 ++++----
 4 files changed, 17 insertions(+), 57 deletions(-)
 rename sysdeps/unix/sysv/linux/{time.c => time-internal.h} (64%)
 rename sysdeps/posix/time.c => time/time-internal.h (57%)

diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c
index c35b80fad1..e957b81751 100644
--- a/sysdeps/unix/sysv/linux/powerpc/time.c
+++ b/sysdeps/unix/sysv/linux/powerpc/time.c
@@ -78,6 +78,6 @@ libc_hidden_def (time)
 
 #else
 
-#include <sysdeps/posix/time.c>
+#include <time/time.c>
 
 #endif /* !SHARED */
diff --git a/sysdeps/unix/sysv/linux/time.c b/sysdeps/unix/sysv/linux/time-internal.h
similarity index 64%
rename from sysdeps/unix/sysv/linux/time.c
rename to sysdeps/unix/sysv/linux/time-internal.h
index f461733678..c4c5f6b643 100644
--- a/sysdeps/unix/sysv/linux/time.c
+++ b/sysdeps/unix/sysv/linux/time-internal.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
+/* Internals of time and related functions.  Linux version.
+   Copyright 2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -15,27 +16,7 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <stddef.h>
-#include <time.h>
-
-#include <sysdep.h>
-
-#ifdef __NR_time
-
-time_t
-time (time_t *t)
-{
-  INTERNAL_SYSCALL_DECL (err);
-  time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
-  /* There cannot be any error.  */
-  if (t != NULL)
-    *t = res;
-  return res;
-}
-libc_hidden_def (time)
-
-#else
-
-# include <sysdeps/posix/time.c>
-
-#endif
+/* Timer used on clock_gettime for time implementation.  For Linux
+   it uses the coarse version which returns the time at the last tick
+   and mimic what time as syscall should return.  */
+#define TIME_CLOCK_GETTIME_CLOCKID CLOCK_REALTIME_COARSE
diff --git a/sysdeps/posix/time.c b/time/time-internal.h
similarity index 57%
rename from sysdeps/posix/time.c
rename to time/time-internal.h
index 0ab31bd7b6..f448f64191 100644
--- a/sysdeps/posix/time.c
+++ b/time/time-internal.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
+/* Internals of time and related functions.
+   Copyright 2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -15,26 +16,5 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <stddef.h>		/* For NULL.  */
-#include <time.h>
-#include <sys/time.h>
-
-
-/* Return the current time as a `time_t' and also put it in *T if T is
-   not NULL.  Time is represented as seconds from Jan 1 00:00:00 1970.  */
-time_t
-time (time_t *t)
-{
-  struct timeval tv;
-  time_t result;
-
-  if (__gettimeofday (&tv, (struct timezone *) NULL))
-    result = (time_t) -1;
-  else
-    result = (time_t) tv.tv_sec;
-
-  if (t != NULL)
-    *t = result;
-  return result;
-}
-libc_hidden_def (time)
+/* Timer used on clock_gettime for time implementation.  */
+#define TIME_CLOCK_GETTIME_CLOCKID CLOCK_REALTIME
diff --git a/time/time.c b/time/time.c
index b53a06e29c..09a2b4fc88 100644
--- a/time/time.c
+++ b/time/time.c
@@ -15,19 +15,18 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
 #include <time.h>
+#include <time-internal.h>
 
 /* Return the time now, and store it in *TIMER if not NULL.  */
 time_t
 time (time_t *timer)
 {
-  __set_errno (ENOSYS);
+  struct timespec ts;
+  __clock_gettime (TIME_CLOCK_GETTIME_CLOCKID, &ts);
 
-  if (timer != NULL)
-    *timer = (time_t) -1;
-  return (time_t) -1;
+  if (timer)
+    *timer = ts.tv_sec;
+  return ts.tv_sec;
 }
 libc_hidden_def (time)
-
-stub_warning (time)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 11/11] Revise the documentation of simple calendar time.
  2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2019-10-25 12:09 ` [PATCH v2 10/11] Make second argument of gettimeofday as 'void *' Adhemerval Zanella
@ 2019-10-25 12:09 ` Adhemerval Zanella
  2019-10-25 12:09 ` [PATCH v2 04/11] Use clock_settime to implement settimeofday Adhemerval Zanella
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:09 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski, Zack Weinberg

From: Zack Weinberg <zackw@panix.com>

Changes from previous version:

  - Added suggestion from Paul Eggert.

--

This is a thorough revision of all the material relating to the
functions time, stime, gettimeofday, settimeofday, clock_gettime,
clock_getres, clock_settime, and difftime, spilling over into the
discussion of time-related data types (which now get their own
section) and touching the adjtime family as well (which deserves its
own thorough revision, but I'd have to do a bunch of research first).

Substantive changes are:

 * Document clock_gettime, clock_getres, and clock_settime.  (Only
   CLOCK_REALTIME and CLOCK_MONOTONIC are documented; the others are
   either a bit too Linux-specific, or have more to do with measuring
   CPU/processor time.  That section _also_ deserves its own thorough
   revision but again I'd have to do a bunch of research first.)

 * Present gettimeofday, settimeofday, and struct timeval as obsolete
   relative to clock_*.

 * Remove the documentation of struct timezone.  Matching POSIX,
   say that the type of the second argument to gettimeofday and
   settimeofday is [const] void *.

 * Clarify ISO C and POSIX's requirements on time_t.  Clarify the
   circumstances under which difftime is equivalent to simple
   subtraction.

 * Consolidate documentation of most of the time-related data types
   into a new section "Time Types," right after "Time Basics."  (The
   exceptions are struct tm, which stays in "Broken-down Time," and
   struct times, which stays in "Processor And CPU Time."

 * The "Elapsed Time" section is now called "Calculating Elapsed Time"
   and includes only difftime and the discussion of how to compute
   timeval differences by hand.

 * Fold the "Simple Calendar Time," "High Resolution Calendar," and
   "High Accuracy Clock" sections together into two new sections titled
   "Getting the Time" and "Setting and Adjusting the Time."
---
 manual/filesys.texi |    2 +-
 manual/llio.texi    |   10 +-
 manual/threads.texi |    2 +-
 manual/time.texi    | 1072 ++++++++++++++++++++++++-------------------
 4 files changed, 613 insertions(+), 473 deletions(-)

diff --git a/manual/filesys.texi b/manual/filesys.texi
index d31dbb24b4..73e630842e 100644
--- a/manual/filesys.texi
+++ b/manual/filesys.texi
@@ -2899,7 +2899,7 @@ which extends its resolution.  These fields are called
 @code{st_atime_usec}, @code{st_mtime_usec}, and @code{st_ctime_usec};
 each has a value between 0 and 999,999, which indicates the time in
 microseconds.  They correspond to the @code{tv_usec} field of a
-@code{timeval} structure; see @ref{High-Resolution Calendar}.
+@code{timeval} structure; see @ref{Time Types}.
 
 The @code{utimes} function is like @code{utime}, but also lets you specify
 the fractional part of the file times.  The prototype for this function is
diff --git a/manual/llio.texi b/manual/llio.texi
index 447126b7eb..fe59002915 100644
--- a/manual/llio.texi
+++ b/manual/llio.texi
@@ -2094,11 +2094,11 @@ descriptors.  The usual thing is to pass @code{FD_SETSIZE} as the value
 of this argument.
 
 The @var{timeout} specifies the maximum time to wait.  If you pass a
-null pointer for this argument, it means to block indefinitely until one
-of the file descriptors is ready.  Otherwise, you should provide the
-time in @code{struct timeval} format; see @ref{High-Resolution
-Calendar}.  Specify zero as the time (a @code{struct timeval} containing
-all zeros) if you want to find out which descriptors are ready without
+null pointer for this argument, it means to block indefinitely until
+one of the file descriptors is ready.  Otherwise, you should provide
+the time in @code{struct timeval} format; see @ref{Time Types}.
+Specify zero as the time (a @code{struct timeval} containing all
+zeros) if you want to find out which descriptors are ready without
 waiting if none are ready.
 
 The normal return value from @code{select} is the total number of ready file
diff --git a/manual/threads.texi b/manual/threads.texi
index 0e5e84ab0a..bfe1e5b50b 100644
--- a/manual/threads.texi
+++ b/manual/threads.texi
@@ -128,7 +128,7 @@ function returns @math{0}; otherwise, the return value is non-zero.
 least until the elapsed time pointed to by @var{time_point} has been
 reached.  This function does not take an absolute time, but a duration
 that the thread is required to be blocked.  @xref{Time Basics}, and
-@ref{Elapsed Time}.
+@ref{Time Types}.
 
 The thread may wake early if a signal that is not ignored is received.
 In such a case, if @code{remaining} is not NULL, the remaining time
diff --git a/manual/time.texi b/manual/time.texi
index c5f5b94b67..164c150f64 100644
--- a/manual/time.texi
+++ b/manual/time.texi
@@ -8,7 +8,8 @@ between different time representations.
 
 @menu
 * Time Basics::                 Concepts and definitions.
-* Elapsed Time::                Data types to represent elapsed times
+* Time Types::                  Data types to represent time.
+* Calculating Elapsed Time::    How to calculate the length of an interval.
 * Processor And CPU Time::      Time a program has spent executing.
 * Calendar Time::               Manipulation of ``real'' dates and times.
 * Setting an Alarm::            Sending a signal after a specified time.
@@ -55,100 +56,186 @@ especially when they are part of a sequence of regularly repeating
 events.
 @cindex period of time
 
-@dfn{CPU time} is like calendar time, except that it is based on the
-subset of the time continuum when a particular process is actively
-using a CPU.  CPU time is, therefore, relative to a process.
+A @dfn{simple calendar time} is a calendar time represented as an
+elapsed time since a fixed, implementation-specific calendar time
+called the @dfn{epoch}.  This representation is convenient for doing
+calculations on calendar times, such as finding the elapsed time
+between two calendar times.  Simple calendar times are independent of
+time zone; they represent the same instant in time regardless of where
+on the globe the computer is.
+
+POSIX says that simple calendar times do not include leap seconds, but
+some (otherwise POSIX-conformant) systems can be configured to include
+leap seconds in simple calendar times.
+@cindex leap seconds
+@cindex seconds, leap
+@cindex simple time
+@cindex simple calendar time
+@cindex calendar time, simple
+@cindex epoch
+
+A @dfn{broken-down time} is a calendar time represented by its
+components in the Gregorian calendar: year, month, day, hour, minute,
+and second.  A broken-down time value is relative to a specific time
+zone, and so it is also sometimes called a @dfn{local time}.
+Broken-down times are most useful for input and output, as they are
+easier for people to understand, but more difficult to calculate with.
+@cindex broken-down time
+@cindex local time
+@cindex Gregorian calendar
+@cindex calendar, Gregorian
+
+@dfn{CPU time} measures the amount of time that a single process has
+actively used a CPU to perform computations.  It does not include the
+time that process has spent waiting for external events.  The system
+tracks the CPU time used by each process separately.
 @cindex CPU time
 
-@dfn{Processor time} is an amount of time that a CPU is in use.  In
-fact, it's a basic system resource, since there's a limit to how much
-can exist in any given interval (that limit is the elapsed time of the
-interval times the number of CPUs in the processor).  People often call
-this CPU time, but we reserve the latter term in this manual for the
-definition above.
+@dfn{Processor time} measures the amount of time @emph{any} CPU has
+been in use by @emph{any} process.  It is a basic system resource,
+since there's a limit to how much can exist in any given interval (the
+elapsed time of the interval times the number of CPUs in the computer)
+
+People often call this CPU time, but we reserve the latter term in
+this manual for the definition above.
 @cindex processor time
 
-@node Elapsed Time
-@section Elapsed Time
-@cindex elapsed time
+@node Time Types
+@section Time Types
 
-One way to represent an elapsed time is with a simple arithmetic data
-type, as with the following function to compute the elapsed time between
-two calendar times.  This function is declared in @file{time.h}.
+ISO C and POSIX define several data types for representing elapsed
+times, simple calendar times, and broken-down times.
 
-@deftypefun double difftime (time_t @var{time1}, time_t @var{time0})
+@deftp {Data Type} clock_t
 @standards{ISO, time.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-The @code{difftime} function returns the number of seconds of elapsed
-time between calendar time @var{time1} and calendar time @var{time0}, as
-a value of type @code{double}.  The difference ignores leap seconds
-unless leap second support is enabled.
+@code{clock_t} is used to measure processor and CPU time.
+It may be an integer or a floating-point type.
+Its values are counts of @dfn{clock ticks} since some arbitrary event
+in the past.
+The number of clock ticks per second is system-specific.
+@xref{Processor And CPU Time}, for further detail.
+@cindex clock ticks
+@cindex ticks, clock
+@end deftp
 
-In @theglibc{}, you can simply subtract @code{time_t} values.  But on
-other systems, the @code{time_t} data type might use some other encoding
-where subtraction doesn't work directly.
-@end deftypefun
+@deftp {Data Type} time_t
+@standards{ISO, time.h}
+@code{time_t} is the simplest data type used to represent simple
+calendar time.
+
+In ISO C, @code{time_t} can be either an integer or a floating-point
+type, and the meaning of @code{time_t} values is not specified.  The
+only things a strictly conforming program can do with @code{time_t}
+values are: pass them to @code{difftime} to get the elapsed time
+between two simple calendar times (@pxref{Calculating Elapsed Time}),
+and pass them to the functions that convert them to broken-down time
+(@pxref{Broken-down Time}).
+
+On POSIX-conformant systems, @code{time_t} is an integer type and its
+values represent the number of seconds elapsed since the @dfn{epoch},
+which is 00:00:00 on January 1, 1970, Coordinated Universal Time.
+
+@Theglibc{} additionally guarantees that @code{time_t} is a signed
+type, and that all of its functions operate correctly on negative
+@code{time_t} values, which are interpreted as times before the epoch.
+@cindex epoch
+@end deftp
 
-@Theglibc{} provides two data types specifically for representing
-an elapsed time.  They are used by various @glibcadj{} functions, and
-you can use them for your own purposes too.  They're exactly the same
-except that one has a resolution in microseconds, and the other, newer
-one, is in nanoseconds.
+@deftp {Data Type} {struct timespec}
+@standards{POSIX.1, time.h}
+@cindex timespec
+@code{struct timespec} represents a simple calendar time, or an
+elapsed time, with sub-second resolution.  It is declared in
+@file{time.h} and has the following members:
+
+@table @code
+@item time_t tv_sec
+The number of whole seconds elapsed since the epoch (for a simple
+calendar time) or since some other starting point (for an elapsed
+time).
+
+@item long int tv_nsec
+The number of nanoseconds elapsed since the time given by the
+@code{tv_sec} member.
+
+When @code{struct timespec} values are produced by @glibcadj{}
+functions, the value in this field will always be greater than or
+equal to zero, and less than 1,000,000,000.
+When @code{struct timespec} values are supplied to @glibcadj{}
+functions, the value in this field must be in the same range.
+@end table
+@end deftp
 
 @deftp {Data Type} {struct timeval}
 @standards{BSD, sys/time.h}
 @cindex timeval
-The @code{struct timeval} structure represents an elapsed time.  It is
-declared in @file{sys/time.h} and has the following members:
+@code{struct timeval} is an older type for representing a simple
+calendar time, or an elapsed time, with sub-second resolution. It is
+almost the same as @code{struct timespec}, but provides only
+microsecond resolution.  It is declared in @file{sys/time.h} and has
+the following members:
 
 @table @code
 @item time_t tv_sec
-This represents the number of whole seconds of elapsed time.
+The number of whole seconds elapsed since the epoch (for a simple
+calendar time) or since some other starting point (for an elapsed
+time).
 
 @item long int tv_usec
-This is the rest of the elapsed time (a fraction of a second),
-represented as the number of microseconds.  It is always less than one
-million.
-
+The number of microseconds elapsed since the time given by the
+@code{tv_sec} member.
+
+When @code{struct timeval} values are produced by @glibcadj{}
+functions, the value in this field will always be greater than or
+equal to zero, and less than 1,000,000.
+When @code{struct timeval} values are supplied to @glibcadj{}
+functions, the value in this field must be in the same range.
 @end table
 @end deftp
 
-@deftp {Data Type} {struct timespec}
-@standards{POSIX.1, sys/time.h}
-@cindex timespec
-The @code{struct timespec} structure represents an elapsed time.  It is
-declared in @file{time.h} and has the following members:
+@deftp {Data Type} {struct tm}
+@standards{ISO, time.h}
+This is the data type used to represent a broken-down time.  It has
+separate fields for year, month, day, and so on.
+@xref{Broken-down Time}, for further details.
+@end deftp
 
-@table @code
-@item time_t tv_sec
-This represents the number of whole seconds of elapsed time.
+@node Calculating Elapsed Time
+@section Calculating Elapsed Time
 
-@item long int tv_nsec
-This is the rest of the elapsed time (a fraction of a second),
-represented as the number of nanoseconds.  It is always less than one
-billion.
+Often, one wishes to calculate an elapsed time as the difference
+between two simple calendar times.  @Theglibc{} provides only one
+function for this purpose.
 
-@end table
-@end deftp
+@deftypefun double difftime (time_t @var{end}, time_t @var{begin})
+@standards{ISO, time.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+The @code{difftime} function returns the number of seconds of elapsed
+time from calendar time @var{begin} to calendar time @var{end}, as
+a value of type @code{double}.
+
+On POSIX-conformant systems, the advantage of using
+@samp{difftime (@var{end}, @var{begin})} over @samp{@var{end} - @var{begin}}
+is that it will produce the mathematically correct result even if
+@var{end} and @var{begin} are so far apart that a simple subtraction
+would overflow.  However, if they are so far apart that a @code{double}
+cannot exactly represent the difference, the result will be inexact.
+
+On other systems, @code{time_t} values might be encoded in a way that
+prevents subtraction from working directly, and then @code{difftime}
+would be the only way to compute their difference.
+@end deftypefun
 
-It is often necessary to subtract two values of type @w{@code{struct
-timeval}} or @w{@code{struct timespec}}.  Here is the best way to do
-this.  It works even on some peculiar operating systems where the
-@code{tv_sec} member has an unsigned type.
+@Theglibc{} does not provide any functions for computing the
+difference between two values of type @w{@code{struct timeval}} or
+@w{@code{struct timespec}}.  Here is the recommended way to do this
+calculation by hand.  It works even on some peculiar operating systems
+where the @code{tv_sec} member has an unsigned type.
 
 @smallexample
 @include timeval_subtract.c.texi
 @end smallexample
 
-Common functions that use @code{struct timeval} are @code{gettimeofday}
-and @code{settimeofday}.
-
-
-There are no @glibcadj{} functions specifically oriented toward
-dealing with elapsed times, but the calendar time, processor time, and
-alarm and sleeping functions have a lot to do with them.
-
-
 @node Processor And CPU Time
 @section Processor And CPU Time
 
@@ -233,12 +320,6 @@ by the @code{clock} function.  POSIX requires that this value be one
 million independent of the actual resolution.
 @end deftypevr
 
-@deftp {Data Type} clock_t
-@standards{ISO, time.h}
-This is the type of the value returned by the @code{clock} function.
-Values of type @code{clock_t} are numbers of clock ticks.
-@end deftp
-
 @deftypefun clock_t clock (void)
 @standards{ISO, time.h}
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@@ -331,43 +412,15 @@ and @code{tms_stime} fields returned by @code{times}.
 @node Calendar Time
 @section Calendar Time
 
-This section describes facilities for keeping track of calendar time.
-@xref{Time Basics}.
-
-@Theglibc{} represents calendar time three ways:
-
-@itemize @bullet
-@item
-@dfn{Simple time} (the @code{time_t} data type) is a compact
-representation, typically giving the number of seconds of elapsed time
-since some implementation-specific base time.
-@cindex simple time
-
-@item
-There is also a "high-resolution time" representation.  Like simple
-time, this represents a calendar time as an elapsed time since a base
-time, but instead of measuring in whole seconds, it uses a @code{struct
-timeval} data type, which includes fractions of a second.  Use this time
-representation instead of simple time when you need greater precision.
-@cindex high-resolution time
-
-@item
-@dfn{Local time} or @dfn{broken-down time} (the @code{struct tm} data
-type) represents a calendar time as a set of components specifying the
-year, month, and so on in the Gregorian calendar, for a specific time
-zone.  This calendar time representation is usually used only to
-communicate with people.
-@cindex local time
-@cindex broken-down time
-@cindex Gregorian calendar
-@cindex calendar, Gregorian
-@end itemize
+This section describes the functions for getting, setting, and
+manipulating calendar times.
 
 @menu
-* Simple Calendar Time::        Facilities for manipulating calendar time.
-* High-Resolution Calendar::    A time representation with greater precision.
+* Getting the Time::            Functions for finding out what time it is.
+* Setting and Adjusting the Time::
+                                Functions for setting and adjusting
+                                  the system clock.
 * Broken-down Time::            Facilities for manipulating local time.
-* High Accuracy Clock::         Maintaining a high accuracy system clock.
 * Formatting Calendar Time::    Converting times to strings.
 * Parsing Date and Time::       Convert textual time and date information back
                                  into broken-down time values.
@@ -377,175 +430,419 @@ communicate with people.
 				 the time functions.
 @end menu
 
-@node Simple Calendar Time
-@subsection Simple Calendar Time
+@node Getting the Time
+@subsection Getting the Time
 
-This section describes the @code{time_t} data type for representing calendar
-time as simple time, and the functions which operate on simple time objects.
-These facilities are declared in the header file @file{time.h}.
-@pindex time.h
+@Theglibc{} provides several functions for getting the current
+calendar time, with different levels of resolution.
 
-@cindex epoch
-@deftp {Data Type} time_t
+@deftypefun time_t time (time_t *@var{result})
 @standards{ISO, time.h}
-This is the data type used to represent simple time.  Sometimes, it also
-represents an elapsed time.  When interpreted as a calendar time value,
-it represents the number of seconds elapsed since 00:00:00 on January 1,
-1970, Coordinated Universal Time.  (This calendar time is sometimes
-referred to as the @dfn{epoch}.)  POSIX requires that this count not
-include leap seconds, but on some systems this count includes leap seconds
-if you set @code{TZ} to certain values (@pxref{TZ Variable}).
-
-Note that a simple time has no concept of local time zone.  Calendar
-Time @var{T} is the same instant in time regardless of where on the
-globe the computer is.
-
-In @theglibc{}, @code{time_t} is equivalent to @code{long int}.
-In other systems, @code{time_t} might be either an integer or
-floating-point type.
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+This is the simplest function for getting the current calendar time.
+It returns the calendar time as a value of type @code{time_t}; on
+POSIX systems, that means it has a resolution of one second.  It
+uses the same clock as @w{@samp{clock_gettime (CLOCK_REALTIME_COARSE)}},
+when the clock is available or @w{@samp{clock_gettime (CLOCK_REALTIME)}}
+otherwise.
+
+If the argument @var{result} is not a null pointer, the calendar time
+value is also stored in @code{*@var{result}}.
+
+This function cannot fail.
+@end deftypefun
+
+Some applications need more precise timekeeping than is possible with
+a @code{time_t} alone.  Some applications also need more control over
+what is meant by ``the current time.''  For these applications, POSIX
+provides a function @code{clock_gettime} that can retrieve the time
+with up to nanosecond precision, from a variety of different clocks.
+Clocks can be system-wide, measuring time the same for all processes;
+or they can be per-process or per-thread, measuring CPU time consumed
+by a particular process, or some other similar resource.  Each clock
+has its own resolution and epoch.  You can find the resolution of a
+clock with the function @code{clock_getres}.  There is no function to
+get the epoch for a clock; either it is fixed and documented, or the
+clock is not meant to be used to measure absolute times.
+
+@deftp {Data Type} clockid_t
+@standards{POSIX.1, time.h}
+The type @code{clockid_t} is used for constants that indicate which of
+several system clocks one wishes to use.
 @end deftp
 
-The function @code{difftime} tells you the elapsed time between two
-simple calendar times, which is not always as easy to compute as just
-subtracting.  @xref{Elapsed Time}.
+All systems that support this family of functions will define at least
+this clock constant:
 
-@deftypefun time_t time (time_t *@var{result})
-@standards{ISO, time.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-The @code{time} function returns the current calendar time as a value of
-type @code{time_t}.  If the argument @var{result} is not a null pointer,
-the calendar time value is also stored in @code{*@var{result}}.  If the
-current calendar time is not available, the value
-@w{@code{(time_t)(-1)}} is returned.
+@deftypevr Macro clockid_t CLOCK_REALTIME
+@standards{POSIX.1, time.h}
+This clock uses the POSIX epoch, 00:00:00 on January 1, 1970, Coordinated
+Universal Time. It is close to, but not necessarily in lock-step with, the
+clocks of @code{time} (above) and of @code{gettimeofday} (below).
+@end deftypevr
+
+@cindex monotonic time
+A second clock constant which is not universal, but still very common,
+is for a clock measuring @dfn{monotonic time}.  Monotonic time is
+useful for measuring elapsed times, because it guarantees that those
+measurements are not affected by changes to the system clock.
+
+@deftypevr Macro clockid_t CLOCK_MONOTONIC
+@standards{POSIX.1, time.h}
+System-wide clock that continuously measures the advancement of
+calendar time, ignoring discontinuous changes to the system's
+setting for absolute calendar time.
+
+The epoch for this clock is an unspecified point in the past.
+The epoch may change if the system is rebooted or suspended.
+Therefore, @code{CLOCK_MONOTONIC} cannot be used to measure
+absolute time, only elapsed time.
+@end deftypevr
+
+Systems may support more than just these two clocks.
+
+@deftypefun int clock_gettime (clockid_t @var{clock}, struct timespec *@var{ts})
+@standards{POSIX.1, time.h}
+Get the current time accoding to the clock identified by @var{clock},
+storing it as seconds and nanoseconds in @code{*@var{ts}}.
+@xref{Time Types}, for a description of @code{struct timespec}.
+
+The return value is @code{0} on success and @code{-1} on failure.  The
+following @code{errno} error condition is defined for this function:
+
+@table @code
+@item EINVAL
+The clock identified by @var{clock} is not supported.
+@end table
 @end deftypefun
 
-@c The GNU C library implements stime() with a call to settimeofday() on
-@c Linux.
-@deftypefun int stime (const time_t *@var{newtime})
-@standards{SVID, time.h}
-@standards{XPG, time.h}
+@code{clock_gettime} reports the time scaled to seconds and
+nanoseconds, but the actual resolution of each clock may not be as
+fine as one nanosecond, and may not be the same for all clocks.  POSIX
+also provides a function for finding out the actual resolution of a
+clock:
+
+@deftypefun int clock_getres (clockid_t @var{clock}, struct timespec *@var{res})
+@standards{POSIX.1, time.h}
+Get the actual resolution of the clock identified by @var{clock},
+storing it in @code{*@var{ts}}.
+
+For instance, if the clock hardware for @code{CLOCK_REALTIME}
+uses a quartz crystal that oscillates at 32.768 kHz,
+then its resolution would be 30.518 microseconds,
+and @w{@samp{clock_getres (CLOCK_REALTIME, &r)}} would set
+@code{r.tv_sec} to 0 and @code{r.tv_nsec} to 30518.
+
+The return value is @code{0} on success and @code{-1} on failure.  The
+following @code{errno} error condition is defined for this function:
+
+@table @code
+@item EINVAL
+The clock identified by @var{clock} is not supported.
+@end table
+@end deftypefun
+
+These functions, and the constants that identify particular clocks,
+are declared in @file{time.h}.
+
+@strong{Portability Note:} On some systems, including systems that use
+older versions of @theglibc{}, programs that use @code{clock_gettime}
+or @code{clock_setres} must be linked with the @code{-lrt} library.
+This has not been necessary with @theglibc{} since version 2.17.
+
+@Theglibc{} also provides an older, but still widely used, function
+for getting the current time with a resolution of microseconds.  This
+function is declared in @file{sys/time.h}.
+
+@deftypefun int gettimeofday (struct timeval *@var{tp}, void *@var{tzp})
+@standards{BSD, sys/time.h}
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-@c On unix, this is implemented in terms of settimeofday.
-@code{stime} sets the system clock, i.e., it tells the system that the
-current calendar time is @var{newtime}, where @code{newtime} is
-interpreted as described in the above definition of @code{time_t}.
+Get the current calendar time, storing it as seconds and microseconds
+in @code{*@var{tp}}.  @xref{Time Types}, for a description of
+@code{struct timeval}.  The clock of @code{gettimeofday} is close to,
+but not necessarily in lock-step with, the clocks of @code{time} and of
+@w{@samp{clock_gettime (CLOCK_REALTIME)}} (see above).
+
+On some historic systems, if @var{tzp} was not a null pointer,
+information about a system-wide time zone would be written to
+@code{*@var{tzp}}.  This feature is obsolete and not supported on
+@gnusystems{}.  You should always supply a null pointer for this
+argument.  Instead, use the facilities described in @ref{Time Zone
+Functions} and in @ref{Broken-down Time} for working with time zones.
+
+This function cannot fail, and its return value is always @code{0}.
+
+@strong{Portability Note:} As of the 2008 revision of POSIX, this
+function is considered obsolete.  @Theglibc{} will continue to provide
+this function indefinitely, but new programs should use
+@code{clock_gettime} instead.
+@end deftypefun
+
+@node Setting and Adjusting the Time
+@subsection Setting and Adjusting the Time
 
-@code{settimeofday} is a newer function which sets the system clock to
-better than one second precision.  @code{settimeofday} is generally a
-better choice than @code{stime}.  @xref{High-Resolution Calendar}.
+The clock hardware inside a modern computer is quite reliable, but it
+can still be wrong.  The functions in this section allow one to set
+the system's idea of the current calendar time, and to adjust the rate
+at which the system counts seconds, so that the calendar time will
+both be accurate, and remain accurate.
 
-Only the superuser can set the system clock.
+The functions in this section require special privileges to use.
+@xref{Users and Groups}.
 
-If the function succeeds, the return value is zero.  Otherwise, it is
-@code{-1} and @code{errno} is set accordingly:
+@deftypefun int clock_settime (clockid_t @var{clock}, const struct timespec *@var{ts})
+@standards{POSIX, time.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+Change the current calendar time, according to the clock identified by
+@var{clock}, to be the simple calendar time in @code{*@var{ts}}.
+
+Not all of the system's clocks can be changed.  For instance, the
+@code{CLOCK_REALTIME} clock can be changed (with the appropriate
+privileges), but the @code{CLOCK_MONOTONIC} clock cannot.
+
+Because simple calendar times are independent of time zone, this
+function should not be used when the time zone changes (e.g.@: if the
+computer is physically moved from one zone to another).  Instead, use
+the facilities described in @ref{Time Zone Functions}.
+
+@code{clock_settime} causes the clock to jump forwards or backwards,
+which can cause a variety of problems.  Changing the
+@code{CLOCK_REALTIME} clock with @code{clock_settime} does not affect
+when timers expire (@pxref{Setting an Alarm}) or when sleeping
+processes wake up (@pxref{Sleeping}), which avoids some of the
+problems.  Still, for small changes made while the system is running,
+it is better to use @code{ntp_adjtime} (below) to make a smooth
+transition from one time to another.
+
+The return value is @code{0} on success and @code{-1} on failure.  The
+following @code{errno} error conditions are defined for this function:
 
 @table @code
+@item EINVAL
+The clock identified by @var{clock} is not supported or cannot be set
+at all, or the simple calendar time in @code{*@var{ts}} is invalid
+(for instance, @code{ts->tv_nsec} is negative or greater than 999,999,999).
+
 @item EPERM
-The process is not superuser.
+This process does not have the privileges required to set the clock
+identified by @var{clock}.
 @end table
+
+@strong{Portability Note}: On some systems, including systems that use
+older versions of @theglibc{}, programs that use @code{clock_settime}
+must be linked with the @code{-lrt} library.  This has not been
+necessary with @theglibc{} since version 2.17.
 @end deftypefun
 
+@cindex time, high precision
+@cindex clock, high accuracy
+@cindex clock, disciplining
+@pindex sys/timex.h
+For systems that remain up and running for long periods, it is not
+enough to set the time once; one should also @dfn{discipline} the
+clock so that it does not drift away from the true calendar time.
 
+The @code{ntp_gettime} and @code{ntp_adjtime} functions provide an
+interface to monitor and discipline the system clock.  For example,
+you can fine-tune the rate at which the clock ``ticks,'' and make
+small adjustments to the current reported calendar time smoothly, by
+temporarily speeding up or slowing down the clock.
 
-@node High-Resolution Calendar
-@subsection High-Resolution Calendar
+These functions' names begin with @samp{ntp_} because they were
+designed for use by programs implementing the Network Time Protocol to
+synchronize a system's clock with other systems' clocks and/or with
+external high-precision clock hardware.
 
-The @code{time_t} data type used to represent simple times has a
-resolution of only one second.  Some applications need more precision.
+These functions, and the constants and structures they use, are
+declared in @file{sys/timex.h}.
 
-So, @theglibc{} also contains functions which are capable of
-representing calendar times to a higher resolution than one second.  The
-functions and the associated data types described in this section are
-declared in @file{sys/time.h}.
-@pindex sys/time.h
+@tindex struct ntptimeval
+@deftp {Data Type} {struct ntptimeval}
+This structure is used to report information about the system clock.
+It contains the following members:
+@table @code
+@item struct timeval time
+The current calendar time, as if retrieved by @code{gettimeofday}.
+The @code{struct timeval} data type is described in
+@ref{Time Types}.
 
-@deftp {Data Type} {struct timezone}
-@standards{BSD, sys/time.h}
-The @code{struct timezone} structure is used to hold minimal information
-about the local time zone.  It has the following members:
+@item long int maxerror
+This is the maximum error, measured in microseconds.  Unless updated
+via @code{ntp_adjtime} periodically, this value will reach some
+platform-specific maximum value.
+
+@item long int esterror
+This is the estimated error, measured in microseconds.  This value can
+be set by @code{ntp_adjtime} to indicate the estimated offset of the
+system clock from the true calendar time.
+@end table
+@end deftp
+
+@deftypefun int ntp_gettime (struct ntptimeval *@var{tptr})
+@standards{GNU, sys/timex.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Wrapper for adjtimex.
+The @code{ntp_gettime} function sets the structure pointed to by
+@var{tptr} to current values.  The elements of the structure afterwards
+contain the values the timer implementation in the kernel assumes.  They
+might or might not be correct.  If they are not, an @code{ntp_adjtime}
+call is necessary.
 
+The return value is @code{0} on success and other values on failure.  The
+following @code{errno} error conditions are defined for this function:
+
+@vtable @code
+@item TIME_ERROR
+The precision clock model is not properly set up at the moment, thus the
+clock must be considered unsynchronized, and the values should be
+treated with care.
+@end vtable
+@end deftypefun
+
+@tindex struct timex
+@deftp {Data Type} {struct timex}
+This structure is used to control and monitor the system clock.  It
+contains the following members:
 @table @code
-@item int tz_minuteswest
-This is the number of minutes west of UTC.
+@item unsigned int modes
+This variable controls whether and which values are set.  Several
+symbolic constants have to be combined with @emph{binary or} to specify
+the effective mode.  These constants start with @code{MOD_}.
 
-@item int tz_dsttime
-If nonzero, Daylight Saving Time applies during some part of the year.
-@end table
+@item long int offset
+This value indicates the current offset of the system clock from the true
+calendar time.  The value is given in microseconds.  If bit
+@code{MOD_OFFSET} is set in @code{modes}, the offset (and possibly other
+dependent values) can be set.  The offset's absolute value must not
+exceed @code{MAXPHASE}.
+
+
+@item long int frequency
+This value indicates the difference in frequency between the true
+calendar time and the system clock.  The value is expressed as scaled
+PPM (parts per million, 0.0001%).  The scaling is @code{1 <<
+SHIFT_USEC}.  The value can be set with bit @code{MOD_FREQUENCY}, but
+the absolute value must not exceed @code{MAXFREQ}.
+
+@item long int maxerror
+This is the maximum error, measured in microseconds.  A new value can be
+set using bit @code{MOD_MAXERROR}.  Unless updated via
+@code{ntp_adjtime} periodically, this value will increase steadily
+and reach some platform-specific maximum value.
+
+@item long int esterror
+This is the estimated error, measured in microseconds.  This value can
+be set using bit @code{MOD_ESTERROR}.
+
+@item int status
+This variable reflects the various states of the clock machinery.  There
+are symbolic constants for the significant bits, starting with
+@code{STA_}.  Some of these flags can be updated using the
+@code{MOD_STATUS} bit.
+
+@item long int constant
+This value represents the bandwidth or stiffness of the PLL (phase
+locked loop) implemented in the kernel.  The value can be changed using
+bit @code{MOD_TIMECONST}.
+
+@item long int precision
+This value represents the accuracy or the maximum error when reading the
+system clock.  The value is expressed in microseconds.
+
+@item long int tolerance
+This value represents the maximum frequency error of the system clock in
+scaled PPM.  This value is used to increase the @code{maxerror} every
+second.
+
+@item struct timeval time
+The current calendar time.
+
+@item long int tick
+The elapsed time between clock ticks in microseconds.  A clock tick is a
+periodic timer interrupt on which the system clock is based.
+
+@item long int ppsfreq
+This is the first of a few optional variables that are present only if
+the system clock can use a PPS (pulse per second) signal to discipline
+the system clock.  The value is expressed in scaled PPM and it denotes
+the difference in frequency between the system clock and the PPS signal.
+
+@item long int jitter
+This value expresses a median filtered average of the PPS signal's
+dispersion in microseconds.
 
-The @code{struct timezone} type is obsolete and should never be used.
-Instead, use the facilities described in @ref{Time Zone Functions}.
+@item int shift
+This value is a binary exponent for the duration of the PPS calibration
+interval, ranging from @code{PPS_SHIFT} to @code{PPS_SHIFTMAX}.
+
+@item long int stabil
+This value represents the median filtered dispersion of the PPS
+frequency in scaled PPM.
+
+@item long int jitcnt
+This counter represents the number of pulses where the jitter exceeded
+the allowed maximum @code{MAXTIME}.
+
+@item long int calcnt
+This counter reflects the number of successful calibration intervals.
+
+@item long int errcnt
+This counter represents the number of calibration errors (caused by
+large offsets or jitter).
+
+@item long int stbcnt
+This counter denotes the number of calibrations where the stability
+exceeded the threshold.
+@end table
 @end deftp
 
-@deftypefun int gettimeofday (struct timeval *@var{tp}, struct timezone *@var{tzp})
-@standards{BSD, sys/time.h}
+@deftypefun int ntp_adjtime (struct timex *@var{tptr})
+@standards{GNU, sys/timex.h}
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-@c On most GNU/Linux systems this is a direct syscall, but the posix/
-@c implementation (not used on GNU/Linux or GNU/Hurd) relies on time and
-@c localtime_r, saving and restoring tzname in an unsafe manner.
-@c On some GNU/Linux variants, ifunc resolvers are used in shared libc
-@c for vdso resolution.  ifunc-vdso-revisit.
-The @code{gettimeofday} function returns the current calendar time as
-the elapsed time since the epoch in the @code{struct timeval} structure
-indicated by @var{tp}.  (@pxref{Elapsed Time} for a description of
-@code{struct timeval}).  Information about the time zone is returned in
-the structure pointed to by @var{tzp}.  If the @var{tzp} argument is a null
-pointer, time zone information is ignored.
+@c Alias to adjtimex syscall.
+The @code{ntp_adjtime} function sets the structure specified by
+@var{tptr} to current values.
+
+In addition, @code{ntp_adjtime} updates some settings to match what you
+pass to it in *@var{tptr}.  Use the @code{modes} element of *@var{tptr}
+to select what settings to update.  You can set @code{offset},
+@code{freq}, @code{maxerror}, @code{esterror}, @code{status},
+@code{constant}, and @code{tick}.
 
-The return value is @code{0} on success and @code{-1} on failure.  The
-following @code{errno} error condition is defined for this function:
+@code{modes} = zero means set nothing.
 
-@table @code
-@item ENOSYS
-The operating system does not support getting time zone information, and
-@var{tzp} is not a null pointer.  @gnusystems{} do not
-support using @w{@code{struct timezone}} to represent time zone
-information; that is an obsolete feature of 4.3 BSD.
-Instead, use the facilities described in @ref{Time Zone Functions}.
-@end table
-@end deftypefun
+Only the superuser can update settings.
 
-@deftypefun int settimeofday (const struct timeval *@var{tp}, const struct timezone *@var{tzp})
-@standards{BSD, sys/time.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-@c On HURD, it calls host_set_time with a privileged port.  On other
-@c unix systems, it's a syscall.
-The @code{settimeofday} function sets the current calendar time in the
-system clock according to the arguments.  As for @code{gettimeofday},
-the calendar time is represented as the elapsed time since the epoch.
-As for @code{gettimeofday}, time zone information is ignored if
-@var{tzp} is a null pointer.
-
-You must be a privileged user in order to use @code{settimeofday}.
-
-Some kernels automatically set the system clock from some source such as
-a hardware clock when they start up.  Others, including Linux, place the
-system clock in an ``invalid'' state (in which attempts to read the clock
-fail).  A call of @code{stime} removes the system clock from an invalid
-state, and system startup scripts typically run a program that calls
-@code{stime}.
-
-@code{settimeofday} causes a sudden jump forwards or backwards, which
-can cause a variety of problems in a system.  Use @code{adjtime} (below)
-to make a smooth transition from one time to another by temporarily
-speeding up or slowing down the clock.
-
-With a Linux kernel, @code{adjtimex} does the same thing and can also
-make permanent changes to the speed of the system clock so it doesn't
-need to be corrected as often.
+@c On Linux, ntp_adjtime() also does the adjtime() function if you set
+@c modes = ADJ_OFFSET_SINGLESHOT (in fact, that is how GNU libc implements
+@c adjtime()).  But this should be considered an internal function because
+@c it's so inconsistent with the rest of what ntp_adjtime() does and is
+@c forced in an ugly way into the struct timex.  So we don't document it
+@c and instead document adjtime() as the way to achieve the function.
 
-The return value is @code{0} on success and @code{-1} on failure.  The
+The return value is @code{0} on success and other values on failure.  The
 following @code{errno} error conditions are defined for this function:
 
 @table @code
+@item TIME_ERROR
+The high accuracy clock model is not properly set up at the moment, thus the
+clock must be considered unsynchronized, and the values should be
+treated with care.  Another reason could be that the specified new values
+are not allowed.
+
 @item EPERM
-This process cannot set the clock because it is not privileged.
+The process specified a settings update, but is not superuser.
 
-@item ENOSYS
-The operating system does not support setting time zone information, and
-@var{tzp} is not a null pointer.
 @end table
+
+For more details see RFC1305 (Network Time Protocol, Version 3) and
+related documents.
+
+@strong{Portability note:} Early versions of @theglibc{} did not
+have this function, but did have the synonymous @code{adjtimex}.
 @end deftypefun
 
+
 @c On Linux, GNU libc implements adjtime() as a call to adjtimex().
 @deftypefun int adjtime (const struct timeval *@var{delta}, struct timeval *@var{olddelta})
 @standards{BSD, sys/time.h}
@@ -553,10 +850,11 @@ The operating system does not support setting time zone information, and
 @c On hurd and mach, call host_adjust_time with a privileged port.  On
 @c Linux, it's implemented in terms of adjtimex.  On other unixen, it's
 @c a syscall.
-This function speeds up or slows down the system clock in order to make
-a gradual adjustment.  This ensures that the calendar time reported by
-the system clock is always monotonically increasing, which might not
-happen if you simply set the clock.
+This simpler version of @code{ntp_adjtime} speeds up or slows down the
+system clock for a short time, in order to correct it by a small
+amount.  This avoids a discontinuous change in the calendar time
+reported by the @code{CLOCK_REALTIME} clock, at the price of having to
+wait longer for the time to become correct.
 
 The @var{delta} argument specifies a relative adjustment to be made to
 the clock time.  If negative, the system clock is slowed down for a
@@ -567,37 +865,86 @@ If the @var{olddelta} argument is not a null pointer, the @code{adjtime}
 function returns information about any previous time adjustment that
 has not yet completed.
 
-This function is typically used to synchronize the clocks of computers
-in a local network.  You must be a privileged user to use it.
-
-With a Linux kernel, you can use the @code{adjtimex} function to
-permanently change the clock speed.
-
 The return value is @code{0} on success and @code{-1} on failure.  The
 following @code{errno} error condition is defined for this function:
 
 @table @code
 @item EPERM
-You do not have privilege to set the time.
+This process does not have the privileges required to adjust the
+@code{CLOCK_REALTIME} clock.
 @end table
 @end deftypefun
 
-@strong{Portability Note:}  The @code{gettimeofday}, @code{settimeofday},
-and @code{adjtime} functions are derived from BSD.
+For compatibility, @theglibc{} also provides several older functions
+for controlling the system time.  New programs should prefer to use
+the functions above.
+
+@deftypefun int stime (const time_t *@var{newtime})
+@standards{SVID, time.h}
+@standards{XPG, time.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+Change the @code{CLOCK_REALTIME} calendar time to be the simple
+calendar time in @code{*@var{newtime}}.  Calling this function is
+exactly the same as calling @w{@samp{clock_settime (CLOCK_REALTIME)}},
+except that the new time can only be set to a precision of one second.
+
+This function is no longer available on @gnusystems{}, but it may be
+the @emph{only} way to set the time on very old Unix systems, so we
+continue to document it.  If it is available, it is declared in
+@file{time.h}.
 
+The return value is @code{0} on success and @code{-1} on failure.  The
+following @code{errno} error condition is defined for this function:
 
-Symbols for the following function are declared in @file{sys/timex.h}.
+@table @code
+@item EPERM
+This process does not have the privileges required to adjust the
+@code{CLOCK_REALTIME} clock.
+@end table
+@end deftypefun
 
 @deftypefun int adjtimex (struct timex *@var{timex})
 @standards{GNU, sys/timex.h}
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-@c It's a syscall, only available on linux.
+@code{adjtimex} is an older name for @code{ntp_adjtime}.
+This function is only available on @gnulinuxsystems{}.
+It is declared in @file{sys/timex.h}.
+@end deftypefun
+
+@deftypefun int settimeofday (const struct timeval *@var{tp}, const void *@var{tzp})
+@standards{BSD, sys/time.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+Change the @code{CLOCK_REALTIME} calendar time to be the simple
+calendar time in @code{*@var{newtime}}.  This function is declared in
+@file{sys/time.h}.
+
+When @var{tzp} is a null pointer, calling this function is exactly the
+same as calling @w{@samp{clock_settime (CLOCK_REALTIME)}}, except that
+the new time can only be set to a precision of one microsecond.
+
+When @var{tzp} is not a null pointer, the data it points to @emph{may}
+be used to set a system-wide idea of the current timezone.  This
+feature is obsolete and not supported on @gnusystems{}.  Instead, use
+the facilities described in @ref{Time Zone Functions} and in
+@ref{Broken-down Time} for working with time zones.
+
+The return value is @code{0} on success and @code{-1} on failure.  The
+following @code{errno} error conditions are defined for this function:
 
-@code{adjtimex} is functionally identical to @code{ntp_adjtime}.
-@xref{High Accuracy Clock}.
+@table @code
+@item EPERM
+This process does not have the privileges required to set the
+@code{CLOCK_REALTIME} clock.
 
-This function is present only with a Linux kernel.
+@item EINVAL
+Neither @var{tp} nor @var{tzp} is a null pointer.  (For historical
+reasons, it is not possible to set the current time and the current
+time zone in the same call.)
 
+@item ENOSYS
+The operating system does not support setting time zone information, and
+@var{tzp} is not a null pointer.
+@end table
 @end deftypefun
 
 @node Broken-down Time
@@ -605,13 +952,13 @@ This function is present only with a Linux kernel.
 @cindex broken-down time
 @cindex calendar time and broken-down time
 
-Calendar time is represented by the usual @glibcadj{} functions as an
-elapsed time since a fixed base calendar time.  This is convenient for
-computation, but has no relation to the way people normally think of
-calendar time.  By contrast, @dfn{broken-down time} is a binary
-representation of calendar time separated into year, month, day, and so
-on.  Broken-down time values are not useful for calculations, but they
-are useful for printing human readable time information.
+Simple calendar times represent absolute times as elapsed times since
+an epoch.  This is convenient for computation, but has no relation to
+the way people normally think of calendar time.  By contrast,
+@dfn{broken-down time} is a binary representation of calendar time
+separated into year, month, day, and so on.  Broken-down time values
+are not useful for calculations, but they are useful for printing
+human readable time information.
 
 A broken-down time value is always relative to a choice of time
 zone, and it also indicates which time zone that is.
@@ -937,213 +1284,6 @@ the @code{TZ} environment variable to UTC, call @code{mktime}, then set
 
 
 
-@node High Accuracy Clock
-@subsection High Accuracy Clock
-
-@cindex time, high precision
-@cindex clock, high accuracy
-@pindex sys/timex.h
-@c On Linux, GNU libc implements ntp_gettime() and npt_adjtime() as calls
-@c to adjtimex().
-The @code{ntp_gettime} and @code{ntp_adjtime} functions provide an
-interface to monitor and manipulate the system clock to maintain high
-accuracy time.  For example, you can fine tune the speed of the clock
-or synchronize it with another time source.
-
-A typical use of these functions is by a server implementing the Network
-Time Protocol to synchronize the clocks of multiple systems and high
-precision clocks.
-
-These functions are declared in @file{sys/timex.h}.
-
-@tindex struct ntptimeval
-@deftp {Data Type} {struct ntptimeval}
-This structure is used for information about the system clock.  It
-contains the following members:
-@table @code
-@item struct timeval time
-This is the current calendar time, expressed as the elapsed time since
-the epoch.  The @code{struct timeval} data type is described in
-@ref{Elapsed Time}.
-
-@item long int maxerror
-This is the maximum error, measured in microseconds.  Unless updated
-via @code{ntp_adjtime} periodically, this value will reach some
-platform-specific maximum value.
-
-@item long int esterror
-This is the estimated error, measured in microseconds.  This value can
-be set by @code{ntp_adjtime} to indicate the estimated offset of the
-system clock from the true calendar time.
-@end table
-@end deftp
-
-@deftypefun int ntp_gettime (struct ntptimeval *@var{tptr})
-@standards{GNU, sys/timex.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-@c Wrapper for adjtimex.
-The @code{ntp_gettime} function sets the structure pointed to by
-@var{tptr} to current values.  The elements of the structure afterwards
-contain the values the timer implementation in the kernel assumes.  They
-might or might not be correct.  If they are not, an @code{ntp_adjtime}
-call is necessary.
-
-The return value is @code{0} on success and other values on failure.  The
-following @code{errno} error conditions are defined for this function:
-
-@vtable @code
-@item TIME_ERROR
-The precision clock model is not properly set up at the moment, thus the
-clock must be considered unsynchronized, and the values should be
-treated with care.
-@end vtable
-@end deftypefun
-
-@tindex struct timex
-@deftp {Data Type} {struct timex}
-This structure is used to control and monitor the system clock.  It
-contains the following members:
-@table @code
-@item unsigned int modes
-This variable controls whether and which values are set.  Several
-symbolic constants have to be combined with @emph{binary or} to specify
-the effective mode.  These constants start with @code{MOD_}.
-
-@item long int offset
-This value indicates the current offset of the system clock from the true
-calendar time.  The value is given in microseconds.  If bit
-@code{MOD_OFFSET} is set in @code{modes}, the offset (and possibly other
-dependent values) can be set.  The offset's absolute value must not
-exceed @code{MAXPHASE}.
-
-
-@item long int frequency
-This value indicates the difference in frequency between the true
-calendar time and the system clock.  The value is expressed as scaled
-PPM (parts per million, 0.0001%).  The scaling is @code{1 <<
-SHIFT_USEC}.  The value can be set with bit @code{MOD_FREQUENCY}, but
-the absolute value must not exceed @code{MAXFREQ}.
-
-@item long int maxerror
-This is the maximum error, measured in microseconds.  A new value can be
-set using bit @code{MOD_MAXERROR}.  Unless updated via
-@code{ntp_adjtime} periodically, this value will increase steadily
-and reach some platform-specific maximum value.
-
-@item long int esterror
-This is the estimated error, measured in microseconds.  This value can
-be set using bit @code{MOD_ESTERROR}.
-
-@item int status
-This variable reflects the various states of the clock machinery.  There
-are symbolic constants for the significant bits, starting with
-@code{STA_}.  Some of these flags can be updated using the
-@code{MOD_STATUS} bit.
-
-@item long int constant
-This value represents the bandwidth or stiffness of the PLL (phase
-locked loop) implemented in the kernel.  The value can be changed using
-bit @code{MOD_TIMECONST}.
-
-@item long int precision
-This value represents the accuracy or the maximum error when reading the
-system clock.  The value is expressed in microseconds.
-
-@item long int tolerance
-This value represents the maximum frequency error of the system clock in
-scaled PPM.  This value is used to increase the @code{maxerror} every
-second.
-
-@item struct timeval time
-The current calendar time.
-
-@item long int tick
-The elapsed time between clock ticks in microseconds.  A clock tick is a
-periodic timer interrupt on which the system clock is based.
-
-@item long int ppsfreq
-This is the first of a few optional variables that are present only if
-the system clock can use a PPS (pulse per second) signal to discipline
-the system clock.  The value is expressed in scaled PPM and it denotes
-the difference in frequency between the system clock and the PPS signal.
-
-@item long int jitter
-This value expresses a median filtered average of the PPS signal's
-dispersion in microseconds.
-
-@item int shift
-This value is a binary exponent for the duration of the PPS calibration
-interval, ranging from @code{PPS_SHIFT} to @code{PPS_SHIFTMAX}.
-
-@item long int stabil
-This value represents the median filtered dispersion of the PPS
-frequency in scaled PPM.
-
-@item long int jitcnt
-This counter represents the number of pulses where the jitter exceeded
-the allowed maximum @code{MAXTIME}.
-
-@item long int calcnt
-This counter reflects the number of successful calibration intervals.
-
-@item long int errcnt
-This counter represents the number of calibration errors (caused by
-large offsets or jitter).
-
-@item long int stbcnt
-This counter denotes the number of calibrations where the stability
-exceeded the threshold.
-@end table
-@end deftp
-
-@deftypefun int ntp_adjtime (struct timex *@var{tptr})
-@standards{GNU, sys/timex.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-@c Alias to adjtimex syscall.
-The @code{ntp_adjtime} function sets the structure specified by
-@var{tptr} to current values.
-
-In addition, @code{ntp_adjtime} updates some settings to match what you
-pass to it in *@var{tptr}.  Use the @code{modes} element of *@var{tptr}
-to select what settings to update.  You can set @code{offset},
-@code{freq}, @code{maxerror}, @code{esterror}, @code{status},
-@code{constant}, and @code{tick}.
-
-@code{modes} = zero means set nothing.
-
-Only the superuser can update settings.
-
-@c On Linux, ntp_adjtime() also does the adjtime() function if you set
-@c modes = ADJ_OFFSET_SINGLESHOT (in fact, that is how GNU libc implements
-@c adjtime()).  But this should be considered an internal function because
-@c it's so inconsistent with the rest of what ntp_adjtime() does and is
-@c forced in an ugly way into the struct timex.  So we don't document it
-@c and instead document adjtime() as the way to achieve the function.
-
-The return value is @code{0} on success and other values on failure.  The
-following @code{errno} error conditions are defined for this function:
-
-@table @code
-@item TIME_ERROR
-The high accuracy clock model is not properly set up at the moment, thus the
-clock must be considered unsynchronized, and the values should be
-treated with care.  Another reason could be that the specified new values
-are not allowed.
-
-@item EPERM
-The process specified a settings update, but is not superuser.
-
-@end table
-
-For more details see RFC1305 (Network Time Protocol, Version 3) and
-related documents.
-
-@strong{Portability note:} Early versions of @theglibc{} did not
-have this function but did have the synonymous @code{adjtimex}.
-
-@end deftypefun
-
-
 @node Formatting Calendar Time
 @subsection Formatting Calendar Time
 
@@ -2700,7 +2840,7 @@ This is the period between now and the first timer interrupt.  If zero,
 the alarm is disabled.
 @end table
 
-The @code{struct timeval} data type is described in @ref{Elapsed Time}.
+The @code{struct timeval} data type is described in @ref{Time Types}.
 @end deftp
 
 @deftypefun int setitimer (int @var{which}, const struct itimerval *@var{new}, struct itimerval *@var{old})
@@ -2885,7 +3025,7 @@ The function returns as *@code{remaining} the elapsed time left in the
 interval for which you requested to sleep.  If the interval completed
 without getting interrupted by a signal, this is zero.
 
-@code{struct timespec} is described in @xref{Elapsed Time}.
+@code{struct timespec} is described in @ref{Time Types}.
 
 If the function returns because the interval is over the return value is
 zero.  If the function returns @math{-1} the global variable @code{errno}
-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 02/11] Change most internal uses of __gettimeofday to __clock_gettime.
  2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
                   ` (5 preceding siblings ...)
  2019-10-25 12:09 ` [PATCH v2 07/11] Consolidate and deprecate ftime Adhemerval Zanella
@ 2019-10-25 12:09 ` Adhemerval Zanella
  2019-10-25 13:26   ` Lukasz Majewski
  2019-10-25 12:09 ` [PATCH v2 06/11] Change most internal uses of time " Adhemerval Zanella
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:09 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski, Zack Weinberg

From: Zack Weinberg <zackw@panix.com>

Changes from previous version:

  - Fixed some indentation and style issues.

  - Use external clock_gettime on memusage.h.

  - Fixed some conformant issues on Hurd.

--

Since gettimeofday will shortly be implemented in terms of
clock_gettime on all platforms, internal code should use clock_gettime
directly; in addition to removing a layer of indirection, this will
allow us to remove the PLT-bypass gunk for gettimeofday.  (We can't
quite do that yet, but it'll be coming later in this patch series.)
In many cases, the changed code does fewer conversions.

The changed code always assumes __clock_gettime (CLOCK_REALTIME)
cannot fail.  Most of the call sites were assuming gettimeofday could
not fail, but a few places were checking for errors.  POSIX says
clock_gettime can only fail if the clock constant is invalid or
unsupported, and CLOCK_REALTIME is the one and only clock constant
that's required to be supported.  For consistency I grepped the entire
source tree for any other places that checked for errors from
__clock_gettime (CLOCK_REALTIME), found one, and changed it too.

(For the record, POSIX also says gettimeofday can never fail.)

(It would be nice if we could declare that GNU systems will always
support CLOCK_MONOTONIC as well as CLOCK_REALTIME; there are several
places where we are using CLOCK_REALTIME where _MONOTONIC would be
more appropriate, and/or trying to use _MONOTONIC and then falling
back to _REALTIME.  But the Hurd doesn't support CLOCK_MONOTONIC yet,
and it looks like adding it would involve substantial changes to
gnumach's internals and API.  Oh well.)

A few Hurd-specific files were changed to use __host_get_time instead
of __clock_gettime, as this seemed tidier.  We also assume this cannot
fail.  Skimming the code in gnumach leads me to believe the only way
it could fail is if __mach_host_self also failed, and our
Hurd-specific code consistently assumes that can't happen, so I'm
going with that.

With the exception of support/support_test_main.c, test cases are not
modified, mainly because I didn't want to have to figure out which
test cases were testing gettimeofday specifically.

The definition of GETTIME in sysdeps/generic/memusage.h had a typo and
was not reading tv_sec at all.  I fixed this.  It appears nobody has been
generating malloc traces on a machine that doesn't have a superseding
definition.

There are a whole bunch of places where the code could be simplified
by factoring out timespec subtraction and/or comparison logic, but I
want to keep this patch as mechanical as possible.

Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
---
 inet/deadline.c                |  8 +-------
 login/logout.c                 |  9 +++++----
 login/logwtmp.c                |  7 +++----
 nis/nis_call.c                 |  4 +++-
 nptl/pthread_join_common.c     |  7 +++----
 nptl/pthread_mutex_timedlock.c |  7 +++----
 nscd/nscd_helper.c             | 24 +++++++++++------------
 resolv/gai_misc.c              |  6 +++---
 resolv/gai_suspend.c           |  6 +++---
 resolv/res_send.c              |  7 +------
 sunrpc/auth_des.c              | 19 ++++++++++--------
 sunrpc/auth_unix.c             |  9 +++++----
 sunrpc/create_xid.c            |  6 +++---
 sunrpc/svcauth_des.c           |  7 ++++++-
 support/support_test_main.c    | 23 +++++++++++-----------
 sysdeps/generic/memusage.h     | 16 +++++++--------
 sysdeps/mach/hurd/getitimer.c  | 11 ++++++++---
 sysdeps/mach/hurd/setitimer.c  | 13 ++++++------
 sysdeps/mach/hurd/times.c      |  7 +++----
 sysdeps/mach/nanosleep.c       | 36 ++++++++++++++++++++++------------
 sysdeps/mach/usleep.c          |  5 -----
 sysdeps/posix/tempname.c       |  9 ++++-----
 sysdeps/posix/timespec_get.c   | 14 ++++---------
 sysdeps/pthread/aio_misc.c     |  6 +++---
 sysdeps/pthread/aio_suspend.c  |  6 +++---
 sysdeps/unix/make-syscalls.sh  |  2 +-
 26 files changed, 137 insertions(+), 137 deletions(-)

diff --git a/inet/deadline.c b/inet/deadline.c
index 6051f1fe0c..541c16bd9a 100644
--- a/inet/deadline.c
+++ b/inet/deadline.c
@@ -29,13 +29,7 @@ __deadline_current_time (void)
 {
   struct deadline_current_time result;
   if (__clock_gettime (CLOCK_MONOTONIC, &result.current) != 0)
-    {
-      struct timeval current_tv;
-      if (__gettimeofday (&current_tv, NULL) == 0)
-        __libc_fatal ("Fatal error: gettimeofday system call failed\n");
-      result.current.tv_sec = current_tv.tv_sec;
-      result.current.tv_nsec = current_tv.tv_usec * 1000;
-    }
+    __clock_gettime (CLOCK_REALTIME, &result.current);
   assert (result.current.tv_sec >= 0);
   return result;
 }
diff --git a/login/logout.c b/login/logout.c
index d0d421cbf7..b8b38df19d 100644
--- a/login/logout.c
+++ b/login/logout.c
@@ -19,6 +19,7 @@
 #include <errno.h>
 #include <string.h>
 #include <utmp.h>
+#include <time.h>
 #include <sys/time.h>
 
 int
@@ -45,10 +46,10 @@ logout (const char *line)
       /* Clear information about who & from where.  */
       memset (ut->ut_name, '\0', sizeof ut->ut_name);
       memset (ut->ut_host, '\0', sizeof ut->ut_host);
-      struct timeval tv;
-      __gettimeofday (&tv, NULL);
-      ut->ut_tv.tv_sec = tv.tv_sec;
-      ut->ut_tv.tv_usec = tv.tv_usec;
+
+      struct timespec ts;
+      __clock_gettime (CLOCK_REALTIME, &ts);
+      TIMESPEC_TO_TIMEVAL (&ut->ut_tv, &ts);
       ut->ut_type = DEAD_PROCESS;
 
       if (pututline (ut) != NULL)
diff --git a/login/logwtmp.c b/login/logwtmp.c
index 654f412ecb..eddba96f35 100644
--- a/login/logwtmp.c
+++ b/login/logwtmp.c
@@ -36,10 +36,9 @@ logwtmp (const char *line, const char *name, const char *host)
   strncpy (ut.ut_name, name, sizeof ut.ut_name);
   strncpy (ut.ut_host, host, sizeof ut.ut_host);
 
-  struct timeval tv;
-  __gettimeofday (&tv, NULL);
-  ut.ut_tv.tv_sec = tv.tv_sec;
-  ut.ut_tv.tv_usec = tv.tv_usec;
+  struct timespec ts;
+  __clock_gettime (CLOCK_REALTIME, &ts);
+  TIMESPEC_TO_TIMEVAL (&ut.ut_tv, &ts);
 
   updwtmp (_PATH_WTMP, &ut);
 }
diff --git a/nis/nis_call.c b/nis/nis_call.c
index 1684de1c6d..5097e614ea 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -709,6 +709,7 @@ __nisfind_server (const_nis_name name, int search_parent,
   nis_error status;
   directory_obj *obj;
   struct timeval now;
+  struct timespec ts;
   unsigned int server_used = ~0;
   unsigned int current_ep = ~0;
 
@@ -718,7 +719,8 @@ __nisfind_server (const_nis_name name, int search_parent,
   if (*dir != NULL)
     return NIS_SUCCESS;
 
-  (void) gettimeofday (&now, NULL);
+  __clock_gettime (CLOCK_REALTIME, &ts);
+  TIMESPEC_TO_TIMEVAL (&now, &ts);
 
   if ((flags & NO_CACHE) == 0)
     *dir = nis_server_cache_search (name, search_parent, &server_used,
diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c
index 9545ae4bd3..ad3073e32d 100644
--- a/nptl/pthread_join_common.c
+++ b/nptl/pthread_join_common.c
@@ -46,15 +46,14 @@ timedwait_tid (pid_t *tidp, const struct timespec *abstime)
   /* Repeat until thread terminated.  */
   while ((tid = *tidp) != 0)
     {
-      struct timeval tv;
       struct timespec rt;
 
       /* Get the current time.  */
-      __gettimeofday (&tv, NULL);
+      __clock_gettime (CLOCK_REALTIME, &rt);
 
       /* Compute relative timeout.  */
-      rt.tv_sec = abstime->tv_sec - tv.tv_sec;
-      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+      rt.tv_sec = abstime->tv_sec - rt.tv_sec;
+      rt.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
       if (rt.tv_nsec < 0)
         {
           rt.tv_nsec += 1000000000;
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index a0ce044dd4..7a5be6b997 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -567,15 +567,14 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex,
 			goto failpp;
 		      }
 
-		    struct timeval tv;
 		    struct timespec rt;
 
 		    /* Get the current time.  */
-		    (void) __gettimeofday (&tv, NULL);
+		    __clock_gettime (CLOCK_REALTIME, &rt);
 
 		    /* Compute relative timeout.  */
-		    rt.tv_sec = abstime->tv_sec - tv.tv_sec;
-		    rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+		    rt.tv_sec = abstime->tv_sec - rt.tv_sec;
+		    rt.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
 		    if (rt.tv_nsec < 0)
 		      {
 			rt.tv_nsec += 1000000000;
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index d326a380ee..7361fe2e0a 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -59,9 +59,10 @@ wait_on_socket (int sock, long int usectmo)
       /* Handle the case where the poll() call is interrupted by a
 	 signal.  We cannot just use TEMP_FAILURE_RETRY since it might
 	 lead to infinite loops.  */
-      struct timeval now;
-      (void) __gettimeofday (&now, NULL);
-      long int end = now.tv_sec * 1000 + usectmo + (now.tv_usec + 500) / 1000;
+      struct timespec now;
+      __clock_gettime (CLOCK_REALTIME, &now);
+      long int end = (now.tv_sec * 1000 + usectmo
+                      + (now.tv_nsec + 500000) / 1000000);
       long int timeout = usectmo;
       while (1)
 	{
@@ -70,8 +71,9 @@ wait_on_socket (int sock, long int usectmo)
 	    break;
 
 	  /* Recompute the timeout time.  */
-	  (void) __gettimeofday (&now, NULL);
-	  timeout = end - (now.tv_sec * 1000 + (now.tv_usec + 500) / 1000);
+          __clock_gettime (CLOCK_REALTIME, &now);
+	  timeout = end - ((now.tv_sec * 1000
+                            + (now.tv_nsec + 500000) / 1000000));
 	}
     }
 
@@ -191,9 +193,7 @@ open_socket (request_type type, const char *key, size_t keylen)
   memcpy (reqdata->key, key, keylen);
 
   bool first_try = true;
-  struct timeval tvend;
-  /* Fake initializing tvend.  */
-  asm ("" : "=m" (tvend));
+  struct timespec tvend = { 0, 0 };
   while (1)
     {
 #ifndef MSG_NOSIGNAL
@@ -212,18 +212,18 @@ open_socket (request_type type, const char *key, size_t keylen)
 
       /* The daemon is busy wait for it.  */
       int to;
-      struct timeval now;
-      (void) __gettimeofday (&now, NULL);
+      struct timespec now;
+      __clock_gettime (CLOCK_REALTIME, &now);
       if (first_try)
 	{
-	  tvend.tv_usec = now.tv_usec;
+	  tvend.tv_nsec = now.tv_nsec;
 	  tvend.tv_sec = now.tv_sec + 5;
 	  to = 5 * 1000;
 	  first_try = false;
 	}
       else
 	to = ((tvend.tv_sec - now.tv_sec) * 1000
-	      + (tvend.tv_usec - now.tv_usec) / 1000);
+	      + (tvend.tv_nsec - now.tv_nsec) / 1000000);
 
       struct pollfd fds[1];
       fds[0].fd = sock;
diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c
index 8738359d81..760c33ac29 100644
--- a/resolv/gai_misc.c
+++ b/resolv/gai_misc.c
@@ -357,13 +357,13 @@ handle_requests (void *arg)
 	 something to arrive in it. */
       if (runp == NULL && optim.gai_idle_time >= 0)
 	{
-	  struct timeval now;
+	  struct timespec now;
 	  struct timespec wakeup_time;
 
 	  ++idle_thread_count;
-	  gettimeofday (&now, NULL);
+          __clock_gettime (CLOCK_REALTIME, &now);
 	  wakeup_time.tv_sec = now.tv_sec + optim.gai_idle_time;
-	  wakeup_time.tv_nsec = now.tv_usec * 1000;
+	  wakeup_time.tv_nsec = now.tv_nsec;
 	  if (wakeup_time.tv_nsec >= 1000000000)
 	    {
 	      wakeup_time.tv_nsec -= 1000000000;
diff --git a/resolv/gai_suspend.c b/resolv/gai_suspend.c
index 16d6998980..b8c642bddc 100644
--- a/resolv/gai_suspend.c
+++ b/resolv/gai_suspend.c
@@ -91,11 +91,11 @@ gai_suspend (const struct gaicb *const list[], int ent,
 	{
 	  /* We have to convert the relative timeout value into an
 	     absolute time value with pthread_cond_timedwait expects.  */
-	  struct timeval now;
+	  struct timespec now;
 	  struct timespec abstime;
 
-	  __gettimeofday (&now, NULL);
-	  abstime.tv_nsec = timeout->tv_nsec + now.tv_usec * 1000;
+          __clock_gettime (CLOCK_REALTIME, &now);
+	  abstime.tv_nsec = timeout->tv_nsec + now.tv_nsec;
 	  abstime.tv_sec = timeout->tv_sec + now.tv_sec;
 	  if (abstime.tv_nsec >= 1000000000)
 	    {
diff --git a/resolv/res_send.c b/resolv/res_send.c
index 6b9c73f820..47bfba6747 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -172,12 +172,7 @@ evCmpTime(struct timespec a, struct timespec b) {
 
 static void
 evNowTime(struct timespec *res) {
-	struct timeval now;
-
-	if (gettimeofday(&now, NULL) < 0)
-		evConsTime(res, 0, 0);
-	else
-		TIMEVAL_TO_TIMESPEC (&now, res);
+	__clock_gettime(CLOCK_REALTIME, res);
 }
 
 
diff --git a/sunrpc/auth_des.c b/sunrpc/auth_des.c
index 5b6f985bc2..d26820a701 100644
--- a/sunrpc/auth_des.c
+++ b/sunrpc/auth_des.c
@@ -41,6 +41,7 @@
 #include <rpc/xdr.h>
 #include <netinet/in.h>		/* XXX: just to get htonl() and ntohl() */
 #include <sys/socket.h>
+#include <time.h>
 #include <shlib-compat.h>
 
 #define MILLION		1000000L
@@ -246,15 +247,15 @@ authdes_marshal (AUTH *auth, XDR *xdrs)
   int status;
   int len;
   register int32_t *ixdr;
-  struct timeval tval;
+  struct timespec now;
 
   /*
    * Figure out the "time", accounting for any time difference
    * with the server if necessary.
    */
-  __gettimeofday (&tval, (struct timezone *) NULL);
-  ad->ad_timestamp.tv_sec = tval.tv_sec + ad->ad_timediff.tv_sec;
-  ad->ad_timestamp.tv_usec = tval.tv_usec + ad->ad_timediff.tv_usec;
+  __clock_gettime (CLOCK_REALTIME, &now);
+  ad->ad_timestamp.tv_sec = now.tv_sec + ad->ad_timediff.tv_sec;
+  ad->ad_timestamp.tv_usec = (now.tv_nsec / 1000) + ad->ad_timediff.tv_usec;
   if (ad->ad_timestamp.tv_usec >= MILLION)
     {
       ad->ad_timestamp.tv_usec -= MILLION;
@@ -445,21 +446,23 @@ authdes_destroy (AUTH *auth)
 static bool_t
 synchronize (struct sockaddr *syncaddr, struct rpc_timeval *timep)
 {
-  struct timeval mytime;
+  struct timespec mytime;
   struct rpc_timeval timeout;
+  long int myusec;
 
   timeout.tv_sec = RTIME_TIMEOUT;
   timeout.tv_usec = 0;
   if (rtime ((struct sockaddr_in *) syncaddr, timep, &timeout) < 0)
     return FALSE;
 
-  __gettimeofday (&mytime, (struct timezone *) NULL);
+  __clock_gettime (CLOCK_REALTIME, &mytime);
   timep->tv_sec -= mytime.tv_sec;
-  if (mytime.tv_usec > timep->tv_usec)
+  myusec = mytime.tv_nsec / 1000;
+  if (myusec > timep->tv_usec)
     {
       timep->tv_sec -= 1;
       timep->tv_usec += MILLION;
     }
-  timep->tv_usec -= mytime.tv_usec;
+  timep->tv_usec -= myusec;
   return TRUE;
 }
diff --git a/sunrpc/auth_unix.c b/sunrpc/auth_unix.c
index b035fdd870..ff0d2eb933 100644
--- a/sunrpc/auth_unix.c
+++ b/sunrpc/auth_unix.c
@@ -43,6 +43,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <time.h>
 #include <libintl.h>
 #include <sys/param.h>
 #include <wchar.h>
@@ -96,7 +97,7 @@ authunix_create (char *machname, uid_t uid, gid_t gid, int len,
 {
   struct authunix_parms aup;
   char mymem[MAX_AUTH_BYTES];
-  struct timeval now;
+  struct timespec now;
   XDR xdrs;
   AUTH *auth;
   struct audata *au;
@@ -122,7 +123,7 @@ no_memory:
   /*
    * fill in param struct from the given params
    */
-  (void) __gettimeofday (&now, (struct timezone *) 0);
+  __clock_gettime (CLOCK_REALTIME, &now);
   aup.aup_time = now.tv_sec;
   aup.aup_machname = machname;
   aup.aup_uid = uid;
@@ -276,7 +277,7 @@ authunix_refresh (AUTH *auth)
 {
   struct audata *au = AUTH_PRIVATE (auth);
   struct authunix_parms aup;
-  struct timeval now;
+  struct timespec now;
   XDR xdrs;
   int stat;
 
@@ -297,7 +298,7 @@ authunix_refresh (AUTH *auth)
     goto done;
 
   /* update the time and serialize in place */
-  (void) __gettimeofday (&now, (struct timezone *) 0);
+  __clock_gettime (CLOCK_REALTIME, &now);
   aup.aup_time = now.tv_sec;
   xdrs.x_op = XDR_ENCODE;
   XDR_SETPOS (&xdrs, 0);
diff --git a/sunrpc/create_xid.c b/sunrpc/create_xid.c
index 1339615a1b..c692c1eb92 100644
--- a/sunrpc/create_xid.c
+++ b/sunrpc/create_xid.c
@@ -39,10 +39,10 @@ _create_xid (void)
   pid_t pid = getpid ();
   if (is_initialized != pid)
     {
-      struct timeval now;
+      struct timespec now;
 
-      __gettimeofday (&now, (struct timezone *) 0);
-      __srand48_r (now.tv_sec ^ now.tv_usec ^ pid,
+      __clock_gettime (CLOCK_REALTIME, &now);
+      __srand48_r (now.tv_sec ^ now.tv_nsec ^ pid,
 		   &__rpc_lrand48_data);
       is_initialized = pid;
     }
diff --git a/sunrpc/svcauth_des.c b/sunrpc/svcauth_des.c
index c5a512d6f8..7607abc818 100644
--- a/sunrpc/svcauth_des.c
+++ b/sunrpc/svcauth_des.c
@@ -44,6 +44,7 @@
 #include <limits.h>
 #include <string.h>
 #include <stdint.h>
+#include <time.h>
 #include <sys/param.h>
 #include <netinet/in.h>
 #include <rpc/rpc.h>
@@ -295,7 +296,11 @@ _svcauth_des (register struct svc_req *rqst, register struct rpc_msg *msg)
 	debug ("timestamp before last seen");
 	return AUTH_REJECTEDVERF;	/* replay */
       }
-    __gettimeofday (&current, (struct timezone *) NULL);
+    {
+      struct timespec now;
+      __clock_gettime (CLOCK_REALTIME, &now);
+      TIMESPEC_TO_TIMEVAL (&current, &now);
+    }
     current.tv_sec -= window;	/* allow for expiration */
     if (!BEFORE (&current, &timestamp))
       {
diff --git a/support/support_test_main.c b/support/support_test_main.c
index 05ad92e688..d6b3a8d45f 100644
--- a/support/support_test_main.c
+++ b/support/support_test_main.c
@@ -88,16 +88,18 @@ static pid_t test_pid;
 static void (*cleanup_function) (void);
 
 static void
-print_timestamp (const char *what, struct timeval tv)
+print_timestamp (const char *what, struct timespec tv)
 {
   struct tm tm;
+  /* Casts of tv.tv_nsec below are necessary because the type of
+     tv_nsec is not literally long int on all supported platforms.  */
   if (gmtime_r (&tv.tv_sec, &tm) == NULL)
-    printf ("%s: %lld.%06d\n",
-            what, (long long int) tv.tv_sec, (int) tv.tv_usec);
+    printf ("%s: %lld.%09ld\n",
+            what, (long long int) tv.tv_sec, (long int) tv.tv_nsec);
   else
-    printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%06d\n",
+    printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%09ld\n",
             what, 1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
-            tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec);
+            tm.tm_hour, tm.tm_min, tm.tm_sec, (long int) tv.tv_nsec);
 }
 
 /* Timeout handler.  We kill the child and exit with an error.  */
@@ -110,8 +112,8 @@ signal_handler (int sig)
 
   /* Do this first to avoid further interference from the
      subprocess.  */
-  struct timeval now;
-  bool now_available = gettimeofday (&now, NULL) == 0;
+  struct timespec now;
+  clock_gettime (CLOCK_REALTIME, &now);
   struct stat64 st;
   bool st_available = fstat64 (STDOUT_FILENO, &st) == 0 && st.st_mtime != 0;
 
@@ -165,12 +167,9 @@ signal_handler (int sig)
     printf ("Timed out: killed the child process but it exited %d\n",
             WEXITSTATUS (status));
 
-  if (now_available)
-    print_timestamp ("Termination time", now);
+  print_timestamp ("Termination time", now);
   if (st_available)
-    print_timestamp ("Last write to standard output",
-                     (struct timeval) { st.st_mtim.tv_sec,
-                         st.st_mtim.tv_nsec / 1000 });
+    print_timestamp ("Last write to standard output", st.st_mtim);
 
   /* Exit with an error.  */
   exit (1);
diff --git a/sysdeps/generic/memusage.h b/sysdeps/generic/memusage.h
index 400fe23f29..88b291e3fa 100644
--- a/sysdeps/generic/memusage.h
+++ b/sysdeps/generic/memusage.h
@@ -26,14 +26,14 @@
 #endif
 
 #ifndef GETTIME
-# define GETTIME(low,high) \
-  {									      \
-    struct timeval tval;						      \
-    uint64_t usecs;							      \
-    gettimeofday (&tval, NULL);						      \
-    usecs = (uint64_t) tval.tv_usec + (uint64_t) tval.tv_usec * 1000000;      \
-    low = usecs & 0xffffffff;						      \
-    high = usecs >> 32;							      \
+# define GETTIME(low,high)						   \
+  {									   \
+    struct timespec now;						   \
+    uint64_t usecs;							   \
+    clock_gettime (CLOCK_REALTIME, &now);				   \
+    usecs = (uint64_t)now.tv_nsec / 1000 + (uint64_t)now.tv_sec * 1000000; \
+    low = usecs & 0xffffffff;						   \
+    high = usecs >> 32;							   \
   }
 #endif
 
diff --git a/sysdeps/mach/hurd/getitimer.c b/sysdeps/mach/hurd/getitimer.c
index f332f0e681..0982357815 100644
--- a/sysdeps/mach/hurd/getitimer.c
+++ b/sysdeps/mach/hurd/getitimer.c
@@ -19,8 +19,9 @@
 #include <errno.h>
 #include <sys/time.h>
 #include <hurd.h>
+#include <mach.h>
 
-/* XXX Temporary cheezoid implementation; see __setitmr.c.  */
+/* XXX Temporary cheezoid implementation; see setitimer.c.  */
 
 /* These are defined in __setitmr.c.  */
 extern spin_lock_t _hurd_itimer_lock;
@@ -61,8 +62,12 @@ __getitimer (enum __itimer_which which, struct itimerval *value)
     }
 
   /* Get the time now.  */
-  if (__gettimeofday (&elapsed, NULL) < 0)
-    return -1;
+  {
+     time_value_t tv;
+     __host_get_time (__mach_host_self (), &tv);
+     elapsed.tv_sec = tv.seconds;
+     elapsed.tv_usec = tv.microseconds;
+  }
 
   /* Extract the current timer setting; and the time it was set, so we can
      calculate the time elapsed so far.  */
diff --git a/sysdeps/mach/hurd/setitimer.c b/sysdeps/mach/hurd/setitimer.c
index 34b433914c..2aab365c31 100644
--- a/sysdeps/mach/hurd/setitimer.c
+++ b/sysdeps/mach/hurd/setitimer.c
@@ -23,6 +23,7 @@
 #include <hurd/signal.h>
 #include <hurd/sigpreempt.h>
 #include <hurd/msg_request.h>
+#include <mach.h>
 #include <mach/message.h>
 
 /* XXX Temporary cheezoid implementation of ITIMER_REAL/SIGALRM.  */
@@ -243,12 +244,12 @@ setitimer_locked (const struct itimerval *new, struct itimerval *old,
   if ((newval.it_value.tv_sec | newval.it_value.tv_usec) != 0 || old != NULL)
     {
       /* Calculate how much time is remaining for the pending alarm.  */
-      if (__gettimeofday (&now, NULL) < 0)
-	{
-	  __spin_unlock (&_hurd_itimer_lock);
-	  _hurd_critical_section_unlock (crit);
-	  return -1;
-	}
+      {
+	time_value_t tv;
+	__host_get_time (__mach_host_self (), &tv);
+	now.tv_sec = tv.seconds;
+	now.tv_usec = tv.microseconds;
+      }
       elapsed = now;
       subtract_timeval (&elapsed, &_hurd_itimer_started);
       remaining = _hurd_itimerval.it_value;
diff --git a/sysdeps/mach/hurd/times.c b/sysdeps/mach/hurd/times.c
index 3aac803c51..56a0062cd5 100644
--- a/sysdeps/mach/hurd/times.c
+++ b/sysdeps/mach/hurd/times.c
@@ -42,7 +42,7 @@ __times (struct tms *tms)
   struct task_basic_info bi;
   struct task_thread_times_info tti;
   mach_msg_type_number_t count;
-  union { time_value_t tvt; struct timeval tv; } now;
+  time_value_t now;
   error_t err;
 
   count = TASK_BASIC_INFO_COUNT;
@@ -65,10 +65,9 @@ __times (struct tms *tms)
   /* XXX This can't be implemented until getrusage(RUSAGE_CHILDREN) can be.  */
   tms->tms_cutime = tms->tms_cstime = 0;
 
-  if (__gettimeofday (&now.tv, NULL) < 0)
-    return -1;
+  __host_get_time (__mach_host_self (), &now);
 
-  return (clock_from_time_value (&now.tvt)
+  return (clock_from_time_value (&now)
 	  - clock_from_time_value (&bi.creation_time));
 }
 weak_alias (__times, times)
diff --git a/sysdeps/mach/nanosleep.c b/sysdeps/mach/nanosleep.c
index 67caa3ea8a..36fb14598e 100644
--- a/sysdeps/mach/nanosleep.c
+++ b/sysdeps/mach/nanosleep.c
@@ -18,16 +18,26 @@
 
 #include <errno.h>
 #include <mach.h>
-#include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
 
+# define timespec_sub(a, b, result)					      \
+  do {									      \
+    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;			      \
+    (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec;			      \
+    if ((result)->tv_nsec < 0) {					      \
+      --(result)->tv_sec;						      \
+      (result)->tv_nsec += 1000000000;					      \
+    }									      \
+  } while (0)
+
 int
 __libc_nanosleep (const struct timespec *requested_time,
-	     struct timespec *remaining)
+                  struct timespec *remaining)
 {
   mach_port_t recv;
-  struct timeval before, after;
+  struct timespec before;
+  error_t err;
 
   if (requested_time->tv_sec < 0
       || requested_time->tv_nsec < 0
@@ -43,20 +53,20 @@ __libc_nanosleep (const struct timespec *requested_time,
 
   recv = __mach_reply_port ();
 
-  if (remaining && __gettimeofday (&before, NULL) < 0)
-    return -1;
-  error_t err = __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
-			    0, 0, recv, ms, MACH_PORT_NULL);
+  if (remaining != 0)
+    __clock_gettime (CLOCK_REALTIME, &before);
+
+  err = __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
+                    0, 0, recv, ms, MACH_PORT_NULL);
   __mach_port_destroy (mach_task_self (), recv);
   if (err == EMACH_RCV_INTERRUPTED)
     {
-      if (remaining && __gettimeofday (&after, NULL) >= 0)
+      if (remaining != 0)
 	{
-	  struct timeval req_time, elapsed, rem;
-	  TIMESPEC_TO_TIMEVAL (&req_time, requested_time);
-	  timersub (&after, &before, &elapsed);
-	  timersub (&req_time, &elapsed, &rem);
-	  TIMEVAL_TO_TIMESPEC (&rem, remaining);
+	  struct timespec after, elapsed;
+	  __clock_gettime (CLOCK_REALTIME, &after);
+	  timespec_sub (&after, &before, &elapsed);
+	  timespec_sub (requested_time, &elapsed, remaining);
 	}
 
       errno = EINTR;
diff --git a/sysdeps/mach/usleep.c b/sysdeps/mach/usleep.c
index 3b79857c5d..578540d065 100644
--- a/sysdeps/mach/usleep.c
+++ b/sysdeps/mach/usleep.c
@@ -25,17 +25,12 @@ int
 usleep (useconds_t useconds)
 {
   mach_port_t recv;
-  struct timeval before, after;
 
   recv = __mach_reply_port ();
 
-  if (__gettimeofday (&before, NULL) < 0)
-    return -1;
   (void) __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
 		     0, 0, recv, (useconds + 999) / 1000, MACH_PORT_NULL);
   __mach_port_destroy (mach_task_self (), recv);
-  if (__gettimeofday (&after, NULL) < 0)
-    return -1;
 
   return 0;
 }
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index a248472540..692c336452 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -50,7 +50,7 @@
 #include <string.h>
 
 #include <fcntl.h>
-#include <sys/time.h>
+#include <time.h>
 #include <stdint.h>
 #include <unistd.h>
 
@@ -63,7 +63,6 @@
 # define struct_stat64 struct stat
 # define __gen_tempname gen_tempname
 # define __getpid getpid
-# define __gettimeofday gettimeofday
 # define __mkdir mkdir
 # define __open open
 # define __lxstat64(version, file, buf) lstat (file, buf)
@@ -76,9 +75,9 @@
 # else
 # define RANDOM_BITS(Var) \
     {                                                                         \
-      struct timeval tv;                                                      \
-      __gettimeofday (&tv, NULL);                                             \
-      (Var) = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;                      \
+      struct timespec ts;                                                     \
+      clock_gettime (CLOCK_REALTIME, &ts);                                    \
+      (Var) = ((uint64_t) tv.tv_nsec << 16) ^ tv.tv_sec;                      \
     }
 #endif
 
diff --git a/sysdeps/posix/timespec_get.c b/sysdeps/posix/timespec_get.c
index 1fc18ac648..e3146da2d3 100644
--- a/sysdeps/posix/timespec_get.c
+++ b/sysdeps/posix/timespec_get.c
@@ -23,16 +23,10 @@
 int
 timespec_get (struct timespec *ts, int base)
 {
-  switch (base)
+  if (base == TIME_UTC)
     {
-    case TIME_UTC:
-      if (__clock_gettime (CLOCK_REALTIME, ts) < 0)
-        return 0;
-      break;
-
-    default:
-      return 0;
+      __clock_gettime (CLOCK_REALTIME, ts);
+      return base;
     }
-
-  return base;
+  return 0;
 }
diff --git a/sysdeps/pthread/aio_misc.c b/sysdeps/pthread/aio_misc.c
index 6ff0132ecb..65b4b1ade8 100644
--- a/sysdeps/pthread/aio_misc.c
+++ b/sysdeps/pthread/aio_misc.c
@@ -614,13 +614,13 @@ handle_fildes_io (void *arg)
 	 something to arrive in it. */
       if (runp == NULL && optim.aio_idle_time >= 0)
 	{
-	  struct timeval now;
+	  struct timespec now;
 	  struct timespec wakeup_time;
 
 	  ++idle_thread_count;
-	  __gettimeofday (&now, NULL);
+	  __clock_gettime (CLOCK_REALTIME, &now);
 	  wakeup_time.tv_sec = now.tv_sec + optim.aio_idle_time;
-	  wakeup_time.tv_nsec = now.tv_usec * 1000;
+	  wakeup_time.tv_nsec = now.tv_nsec;
 	  if (wakeup_time.tv_nsec >= 1000000000)
 	    {
 	      wakeup_time.tv_nsec -= 1000000000;
diff --git a/sysdeps/pthread/aio_suspend.c b/sysdeps/pthread/aio_suspend.c
index ad654e1d08..bb324a5fe6 100644
--- a/sysdeps/pthread/aio_suspend.c
+++ b/sysdeps/pthread/aio_suspend.c
@@ -183,11 +183,11 @@ aio_suspend (const struct aiocb *const list[], int nent,
 	{
 	  /* We have to convert the relative timeout value into an
 	     absolute time value with pthread_cond_timedwait expects.  */
-	  struct timeval now;
+	  struct timespec now;
 	  struct timespec abstime;
 
-	  __gettimeofday (&now, NULL);
-	  abstime.tv_nsec = timeout->tv_nsec + now.tv_usec * 1000;
+	  __clock_gettime (CLOCK_REALTIME, &now);
+	  abstime.tv_nsec = timeout->tv_nsec + now.tv_nsec;
 	  abstime.tv_sec = timeout->tv_sec + now.tv_sec;
 	  if (abstime.tv_nsec >= 1000000000)
 	    {
diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh
index b49e6b6305..fe24bbc78f 100644
--- a/sysdeps/unix/make-syscalls.sh
+++ b/sysdeps/unix/make-syscalls.sh
@@ -27,7 +27,7 @@
 # n: scalar buffer length (e.g., 3rd arg to read)
 # N: pointer to value/return scalar buffer length (e.g., 6th arg to recvfrom)
 # p: non-NULL pointer to typed object (e.g., any non-void* arg)
-# P: optionally-NULL pointer to typed object (e.g., 2nd argument to gettimeofday)
+# P: optionally-NULL pointer to typed object (e.g., 3rd argument to sigaction)
 # s: non-NULL string (e.g., 1st arg to open)
 # S: optionally-NULL string (e.g., 1st arg to acct)
 # v: vararg scalar (e.g., optional 3rd arg to open)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 08/11] Use clock_gettime to implement timespec_get.
  2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
                   ` (9 preceding siblings ...)
  2019-10-25 12:09 ` [PATCH v2 05/11] Use clock_gettime to implement time Adhemerval Zanella
@ 2019-10-25 12:09 ` Adhemerval Zanella
  2019-10-28 13:30   ` Lukasz Majewski
  10 siblings, 1 reply; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:09 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski, Zack Weinberg

From: Zack Weinberg <zackw@panix.com>

Use clock_gettime to implement timespec_get.

Changes from previous version:

  - Change commit message remove the rationale to not promote it.

--

timespec_get is the same function as clock_gettime, with an obnoxious
coating of NIH painted on it by the ISO C committee.  In addition to
the rename, it takes its arguments in a different order, it returns 0
on *failure* or a positive number on *success*, and it requires that
all of its TIME_* constants be positive.  This last means we cannot
directly reuse the existing CLOCK_* constants for it, because
those have been allocated starting with CLOCK_REALTIME = 0 on all
existing platforms.

This patch simply promotes the sysdeps/posix implementation to
universal, and removes the Linux-specific implementation, whose
apparent reason for existing was to cut out one function call's worth
of overhead.

Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.
---
 sysdeps/posix/timespec_get.c           | 32 ------------------
 sysdeps/unix/sysv/linux/timespec_get.c | 46 --------------------------
 time/timespec_get.c                    | 14 +++-----
 3 files changed, 4 insertions(+), 88 deletions(-)
 delete mode 100644 sysdeps/posix/timespec_get.c
 delete mode 100644 sysdeps/unix/sysv/linux/timespec_get.c

diff --git a/sysdeps/posix/timespec_get.c b/sysdeps/posix/timespec_get.c
deleted file mode 100644
index e3146da2d3..0000000000
--- a/sysdeps/posix/timespec_get.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* timespec_get -- C11 interface to sample a clock.  Generic POSIX.1 version.
-   Copyright (C) 2013-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <time.h>
-
-
-/* Set TS to calendar time based in time base BASE.  */
-int
-timespec_get (struct timespec *ts, int base)
-{
-  if (base == TIME_UTC)
-    {
-      __clock_gettime (CLOCK_REALTIME, ts);
-      return base;
-    }
-  return 0;
-}
diff --git a/sysdeps/unix/sysv/linux/timespec_get.c b/sysdeps/unix/sysv/linux/timespec_get.c
deleted file mode 100644
index 629827d0f9..0000000000
--- a/sysdeps/unix/sysv/linux/timespec_get.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (C) 2011-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <time.h>
-#include <sysdep.h>
-#include <errno.h>
-
-#ifdef HAVE_CLOCK_GETTIME_VSYSCALL
-# define HAVE_VSYSCALL
-#endif
-#include <sysdep-vdso.h>
-
-/* Set TS to calendar time based in time base BASE.  */
-int
-timespec_get (struct timespec *ts, int base)
-{
-  switch (base)
-    {
-      int res;
-      INTERNAL_SYSCALL_DECL (err);
-    case TIME_UTC:
-      res = INTERNAL_VSYSCALL (clock_gettime, err, 2, CLOCK_REALTIME, ts);
-      if (INTERNAL_SYSCALL_ERROR_P (res, err))
-	return 0;
-      break;
-
-    default:
-      return 0;
-    }
-
-  return base;
-}
diff --git a/time/timespec_get.c b/time/timespec_get.c
index cef9a4263c..5124c747c2 100644
--- a/time/timespec_get.c
+++ b/time/timespec_get.c
@@ -22,16 +22,10 @@
 int
 timespec_get (struct timespec *ts, int base)
 {
-  switch (base)
+  if (base == TIME_UTC)
     {
-    case TIME_UTC:
-      /* Not supported.  */
-      return 0;
-
-    default:
-      return 0;
+      __clock_gettime (CLOCK_REALTIME, ts);
+      return base;
     }
-
-  return base;
+  return 0;
 }
-stub_warning (timespec_get)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 10/11] Make second argument of gettimeofday as 'void *'
  2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
  2019-10-25 12:08 ` [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls Adhemerval Zanella
  2019-10-25 12:08 ` [PATCH v2 03/11] Use clock_settime to implement stime; withdraw stime Adhemerval Zanella
@ 2019-10-25 12:09 ` Adhemerval Zanella
  2019-10-28 14:23   ` Lukasz Majewski
  2019-10-25 12:09 ` [PATCH v2 11/11] Revise the documentation of simple calendar time Adhemerval Zanella
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-25 12:09 UTC (permalink / raw)
  To: libc-alpha; +Cc: Lukasz Majewski, Zack Weinberg

From: Zack Weinberg <zackw@panix.com>

Changes from previous version:

  - Remove warning for use of gettimeofday with a non-null __tz argument,
    the conditionals of making this work without false-positive seems quite 
    specific and fragile (gcc-only, optimized build, workaround for gcc
    bug).

--

Also make the public prototype of gettimeofday declare its second
argument with type "void *" unconditionally, consistent with POSIX.

It is also consistent with POSIX.

Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.

Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
---
 include/sys/time.h                            |  2 +-
 .../unix/sysv/linux/aarch64/gettimeofday.c    |  4 ++--
 .../unix/sysv/linux/powerpc/gettimeofday.c    |  4 ++--
 sysdeps/unix/sysv/linux/x86/gettimeofday.c    |  4 ++--
 time/gettimeofday.c                           |  4 ++--
 time/sys/time.h                               | 23 ++++++++++---------
 6 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/include/sys/time.h b/include/sys/time.h
index 2bf4297e76..a461295c6a 100644
--- a/include/sys/time.h
+++ b/include/sys/time.h
@@ -21,7 +21,7 @@
 
 # ifndef _ISOMAC
 extern int __gettimeofday (struct timeval *__tv,
-			   struct timezone *__tz);
+			   void *__tz);
 extern int __settimezone (const struct timezone *__tz)
 	attribute_hidden;
 extern int __adjtime (const struct timeval *__delta,
diff --git a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
index 075af3d0d3..7e772e05ce 100644
--- a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
@@ -31,7 +31,7 @@
 /* Used as a fallback in the ifunc resolver if VDSO is not available
    and for libc.so internal __gettimeofday calls.  */
 static int
-__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
+__gettimeofday_vsyscall (struct timeval *restrict tv, void *restrict tz)
 {
   if (__glibc_unlikely (tz != 0))
     memset (tz, 0, sizeof *tz);
@@ -50,7 +50,7 @@ libc_ifunc (__gettimeofday,
 
 #else
 int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
+__gettimeofday (struct timeval *restrict tv, void *restrict tz)
 {
   return __gettimeofday_vsyscall (tv, tz);
 }
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 02486dee3a..18d8f7cb7a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -24,7 +24,7 @@
 #include <sysdep-vdso.h>
 
 static int
-__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+__gettimeofday_syscall (struct timeval *restrict tv, void *restrict tz)
 {
   if (__glibc_unlikely (tz != 0))
     memset (tz, 0, sizeof *tz);
@@ -46,7 +46,7 @@ libc_ifunc (__gettimeofday,
 	    : (void *) __gettimeofday_syscall);
 #else
 int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
+__gettimeofday (struct timeval *restrict tv, void *restrict tz)
 {
   return __gettimeofday_syscall (tv, tz);
 }
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
index cb20e358d8..190127d31e 100644
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -25,7 +25,7 @@
 #include <sysdep-vdso.h>
 
 static int
-__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+__gettimeofday_syscall (struct timeval *restrict tv, void *restrict tz)
 {
   if (__glibc_unlikely (tz != 0))
     memset (tz, 0, sizeof *tz);
@@ -45,7 +45,7 @@ libc_ifunc (__gettimeofday,
 
 #else
 int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
+__gettimeofday (struct timeval *restrict tv, void *restrict tz)
 {
   return __gettimeofday_syscall (tv, tz);
 }
diff --git a/time/gettimeofday.c b/time/gettimeofday.c
index e8055b397d..ddaf46f481 100644
--- a/time/gettimeofday.c
+++ b/time/gettimeofday.c
@@ -23,10 +23,10 @@
    If *TZ is not NULL, clear it.
    Returns 0 on success, -1 on errors.  */
 int
-___gettimeofday (struct timeval *tv, struct timezone *tz)
+___gettimeofday (struct timeval *restrict tv, void *restrict tz)
 {
   if (__glibc_unlikely (tz != 0))
-    memset (tz, 0, sizeof *tz);
+    memset (tz, 0, sizeof (struct timezone));
 
   struct timespec ts;
   if (__clock_gettime (CLOCK_REALTIME, &ts))
diff --git a/time/sys/time.h b/time/sys/time.h
index f8c946f94e..0473dae339 100644
--- a/time/sys/time.h
+++ b/time/sys/time.h
@@ -54,23 +54,24 @@ struct timezone
     int tz_minuteswest;		/* Minutes west of GMT.  */
     int tz_dsttime;		/* Nonzero if DST is ever in effect.  */
   };
-
-typedef struct timezone *__restrict __timezone_ptr_t;
-#else
-typedef void *__restrict __timezone_ptr_t;
 #endif
 
-/* Get the current time of day and timezone information,
-   putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.
-   Returns 0 on success, -1 on errors.
-   NOTE: This form of timezone information is obsolete.
-   Use the functions and variables declared in <time.h> instead.  */
+/* Get the current time of day, putting it into *TV.
+   If TZ is not null, *TZ must be a struct timezone, and both fields
+   will be set to zero.
+   Calling this function with a non-null TZ is obsolete;
+   use localtime etc. instead.
+   This function itself is semi-obsolete;
+   most callers should use time or clock_gettime instead. */
 extern int gettimeofday (struct timeval *__restrict __tv,
-			 __timezone_ptr_t __tz) __THROW __nonnull ((1));
+			 void *__restrict __tz) __THROW __nonnull ((1));
 
 #ifdef __USE_MISC
 /* Set the current time of day and timezone information.
-   This call is restricted to the super-user.  */
+   This call is restricted to the super-user.
+   Setting the timezone in this way is obsolete, but we don't yet
+   warn about it because it still has some uses for which there is
+   no alternative.  */
 extern int settimeofday (const struct timeval *__tv,
 			 const struct timezone *__tz)
      __THROW;
-- 
2.17.1

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls.
  2019-10-25 12:08 ` [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls Adhemerval Zanella
@ 2019-10-25 13:05   ` Lukasz Majewski
  2019-10-28 18:10     ` Adhemerval Zanella
  2019-10-26  1:08   ` Alistair Francis
  1 sibling, 1 reply; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-25 13:05 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Zack Weinberg

[-- Attachment #1: Type: text/plain, Size: 43113 bytes --]

Hi Adhemerval,

Thanks for re-sending those patches to ML. Please find some comments
below.

> From: Zack Weinberg <zackw@panix.com>
> 
> Changes from previous version:
> 
>   - Add check usage32 check on __wait4_tv32.
> 
>   - Change capitalized functions to lowercase.
> 
> --
> 
> Linux/Alpha has two versions of several system call wrappers that take
> or return data of type "struct timeval" (possibly nested inside a
> larger structure).  The GLIBC_2.0 version is a compat symbol that
> calls __NR_osf_foo or __NR_old_foo and uses a struct timeval with a
> 32-bit tv_sec field.  The GLIBC_2.1 version is used for current code,
> calls __NR_foo, and uses a struct timeval with a 64-bit tv_sec field.
> 
> This patch changes all of the compat symbols of this type to be
> wrappers around their GLIBC_2.1 counterparts; the compatibility system
> calls will no longer be used.  It serves as a proposal for part of how
> we do the transition to 64-bit time_t on systems that currently use
> 32-bit time_t:
> 
>  * The patched glibc will NOT use system calls that involve 32-bit
>    time_t to implement its compatibility symbols.  This will make both
>    our lives and the kernel maintainers' lives easier.  The primary
>    argument I've seen against it is that the kernel could warn about
>    uses of the old system calls, helping people find old binaries that
>    need to be recompiled.  I think there are several other ways we
>    could accomplish this, e.g. scripts to scan the filesystem for
>    binaries with references to the old symbol versions, or issuing
>    diagnostics ourselves.
> 
>  * The compat symbols do NOT report failure after the Y2038 deadline.
>    An earlier revision of this patch had them return -1 and set errno
>    to EOVERFLOW, but Adhemerval pointed out that many of them have
>    already performed side effects at the point where we discover the
>    overflow, so that would break more than it fixes.  Also, we don't
>    want people to be _checking_ for EOVERFLOW from these functions; we
>    want them to recompile with 64-bit time_t.  So it's not actually
>    useful for them to report failure to the calling code.
> 
>  * What they do do, when they encounter overflow, is saturate the
>    overflowed "struct timeval"(s): tv_sec is set to INT32_MAX and
>    tv_nsec is set to 999999.  That means time stops advancing for
>    programs with 32-bit time_t when they reach the deadline.  That's
>    obviously going to break stuff, but I think wrapping around is
>    probably going to break _more_ stuff.  I'd be interested to hear
>    arguments against, if anyone has one.
> 
> The new header file tv32-compat.h is currently Alpha-specific but I
> mean for it to be reused to aid in writing wrappers for all affected
> architectures.  I only put it in sysdeps/unix/sysv/linux/alpha for now
> because I haven't checked whether the various "foo32" structures it
> defines agree with the ABI for ports other than Linux/Alpha.
> 
> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
>  sysdeps/unix/sysv/linux/Makefile              |   2 +-
>  sysdeps/unix/sysv/linux/adjtime.c             |  40 ++---
>  sysdeps/unix/sysv/linux/adjtimex.c            |  40 +++++
>  sysdeps/unix/sysv/linux/alpha/Makefile        |   2 +-
>  sysdeps/unix/sysv/linux/alpha/adjtime.c       |  82 +---------
>  sysdeps/unix/sysv/linux/alpha/adjtimex.c      |  22 +++
>  sysdeps/unix/sysv/linux/alpha/osf_adjtime.c   | 130 ++++++++++++++++
>  sysdeps/unix/sysv/linux/alpha/osf_getitimer.c |  41 +++++
>  sysdeps/unix/sysv/linux/alpha/osf_getrusage.c |  39 +++++
>  .../unix/sysv/linux/alpha/osf_gettimeofday.c  |  43 ++++++
>  sysdeps/unix/sysv/linux/alpha/osf_setitimer.c |  49 ++++++
>  .../unix/sysv/linux/alpha/osf_settimeofday.c  |  41 +++++
>  sysdeps/unix/sysv/linux/alpha/osf_utimes.c    |  37 +++++
>  sysdeps/unix/sysv/linux/alpha/osf_wait4.c     |  41 +++++
>  sysdeps/unix/sysv/linux/alpha/syscalls.list   |  27 ++--
>  sysdeps/unix/sysv/linux/alpha/tv32-compat.h   | 146
> ++++++++++++++++++ sysdeps/unix/sysv/linux/gettimeofday.c        |
> 14 +- sysdeps/unix/sysv/linux/syscalls.list         |   1 -
>  18 files changed, 666 insertions(+), 131 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/adjtimex.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/adjtimex.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_utimes.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_wait4.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/tv32-compat.h
> 
> diff --git a/sysdeps/unix/sysv/linux/Makefile
> b/sysdeps/unix/sysv/linux/Makefile index bbab8f8cc3..a7623fb390 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -14,7 +14,7 @@ endif
>  ifeq ($(subdir),misc)
>  include $(firstword $(wildcard $(sysdirs:=/sysctl.mk)))
>  
> -sysdep_routines += clone umount umount2 readahead \
> +sysdep_routines += adjtimex clone umount umount2 readahead \
>  		   setfsuid setfsgid epoll_pwait signalfd \
>  		   eventfd eventfd_read eventfd_write prlimit \
>  		   personality epoll_wait tee vmsplice splice \
> diff --git a/sysdeps/unix/sysv/linux/adjtime.c
> b/sysdeps/unix/sysv/linux/adjtime.c index 6d1e129ccc..6b8021caa3
> 100644 --- a/sysdeps/unix/sysv/linux/adjtime.c
> +++ b/sysdeps/unix/sysv/linux/adjtime.c
> @@ -23,39 +23,14 @@
>  #define MAX_SEC	(INT_MAX / 1000000L - 2)
>  #define MIN_SEC	(INT_MIN / 1000000L + 2)
>  
> -#ifndef MOD_OFFSET
> -#define modes mode
> -#endif
> -
> -#ifndef TIMEVAL
> -#define TIMEVAL timeval
> -#endif
> -
> -#ifndef TIMEX
> -#define TIMEX timex
> -#endif
> -
> -#ifndef ADJTIME
> -#define ADJTIME __adjtime
> -#endif
> -
> -#ifndef ADJTIMEX
> -#define NO_LOCAL_ADJTIME
> -#define ADJTIMEX(x) __adjtimex (x)
> -#endif
> -
> -#ifndef LINKAGE
> -#define LINKAGE
> -#endif
> -
> -LINKAGE int
> -ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
> +int
> +__adjtime (const struct timeval *itv, struct timeval *otv)
>  {
> -  struct TIMEX tntx;
> +  struct timex tntx;
>  
>    if (itv)
>      {
> -      struct TIMEVAL tmp;
> +      struct timeval tmp;
>  
>        /* We will do some check here. */
>        tmp.tv_sec = itv->tv_sec + itv->tv_usec / 1000000L;
> @@ -68,7 +43,7 @@ ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL
> *otv) else
>      tntx.modes = ADJ_OFFSET_SS_READ;
>  
> -  if (__glibc_unlikely (ADJTIMEX (&tntx) < 0))
> +  if (__glibc_unlikely (__adjtimex (&tntx) < 0))
>      return -1;
>  
>    if (otv)
> @@ -87,6 +62,9 @@ ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL
> *otv) return 0;
>  }
>  
> -#ifdef NO_LOCAL_ADJTIME
> +#ifdef VERSION_adjtime
> +weak_alias (__adjtime, __wadjtime);
> +default_symbol_version (__wadjtime, adjtime, VERSION_adjtime);
> +#else
>  weak_alias (__adjtime, adjtime)
>  #endif
> diff --git a/sysdeps/unix/sysv/linux/adjtimex.c
> b/sysdeps/unix/sysv/linux/adjtimex.c new file mode 100644
> index 0000000000..6d62c72a17
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/adjtimex.c
> @@ -0,0 +1,40 @@
> +/* Tune kernel clock.  Linux specific syscall.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <sys/timex.h>
> +#include <sysdep.h>
> +
> +int
> +___adjtimex (struct timex *buf)
> +{
> +  return INLINE_SYSCALL_CALL (adjtimex, buf);
> +}
> +
> +#ifdef VERSION_adjtimex
> +weak_alias (___adjtimex, __wadjtimex);
> +weak_alias (___adjtimex, __wnadjtime);
> +default_symbol_version (___adjtimex,  __adjtimex, VERSION_adjtimex);
> +default_symbol_version (__wadjtimex,    adjtimex, VERSION_adjtimex);
> +default_symbol_version (__wnadjtime, ntp_adjtime, VERSION_adjtimex);
> +libc_hidden_ver (___adjtimex, __adjtimex);
> +#else
> +strong_alias (___adjtimex, __adjtimex)
> +weak_alias (___adjtimex, adjtimex)
> +weak_alias (___adjtimex, ntp_adjtime)
> +libc_hidden_def (__adjtimex)
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile
> b/sysdeps/unix/sysv/linux/alpha/Makefile index fdd089af71..2e132e474b
> 100644 --- a/sysdeps/unix/sysv/linux/alpha/Makefile
> +++ b/sysdeps/unix/sysv/linux/alpha/Makefile
> @@ -9,7 +9,7 @@ sysdep_routines += ieee_get_fp_control
> ieee_set_fp_control \ ioperm
>  
>  # Support old timeval32 entry points
> -sysdep_routines += osf_gettimeofday osf_settimeofday \
> +sysdep_routines += osf_adjtime osf_gettimeofday osf_settimeofday \
>  		   osf_getitimer osf_setitimer osf_utimes \
>  		   osf_getrusage osf_wait4
>  
> diff --git a/sysdeps/unix/sysv/linux/alpha/adjtime.c
> b/sysdeps/unix/sysv/linux/alpha/adjtime.c index
> 4aede1cc40..9cb058ee55 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/adjtime.c +++
> b/sysdeps/unix/sysv/linux/alpha/adjtime.c @@ -1,4 +1,5 @@
> -/* Copyright (C) 1998-2019 Free Software Foundation, Inc.
> +/* adjtime -- Adjust the current time of day.  Linux/Alpha/tv64
> version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>  
>     The GNU C Library is free software; you can redistribute it and/or
> @@ -15,80 +16,7 @@
>     License along with the GNU C Library.  If not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#include <shlib-compat.h>
> -#include <sysdep.h>
> -#include <sys/time.h>
> -
> -
> -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> -struct timeval32
> -{
> -    int tv_sec, tv_usec;
> -};
> -
> -struct timex32 {
> -	unsigned int modes;	/* mode selector */
> -	long offset;		/* time offset (usec) */
> -	long freq;		/* frequency offset (scaled ppm) */
> -	long maxerror;		/* maximum error (usec) */
> -	long esterror;		/* estimated error (usec) */
> -	int status;		/* clock command/status */
> -	long constant;		/* pll time constant */
> -	long precision;		/* clock precision (usec)
> (read only) */
> -	long tolerance;		/* clock frequency tolerance
> (ppm)
> -				 * (read only)
> -				 */
> -	struct timeval32 time;	/* (read only) */
> -	long tick;		/* (modified) usecs between clock
> ticks */ -
> -	long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
> -	long jitter;            /* pps jitter (us) (ro) */
> -	int shift;              /* interval duration (s) (shift)
> (ro) */
> -	long stabil;            /* pps stability (scaled ppm) (ro) */
> -	long jitcnt;            /* jitter limit exceeded (ro) */
> -	long calcnt;            /* calibration intervals (ro) */
> -	long errcnt;            /* calibration errors (ro) */
> -	long stbcnt;            /* stability limit exceeded (ro) */
> -
> -	int  :32; int  :32; int  :32; int  :32;
> -	int  :32; int  :32; int  :32; int  :32;
> -	int  :32; int  :32; int  :32; int  :32;
> -};
> -
> -#define TIMEVAL		timeval32
> -#define TIMEX		timex32
> -#define ADJTIME		attribute_compat_text_section
> __adjtime_tv32 -#define ADJTIMEX(x)	INLINE_SYSCALL
> (old_adjtimex, 1, x) -#define ADJTIMEX32(x)	INLINE_SYSCALL
> (old_adjtimex, 1, x) -
> +/* We can use the generic Linux implementation, but we have to
> override its
> +   default symbol version.  */
> +#define VERSION_adjtime GLIBC_2.1
>  #include <sysdeps/unix/sysv/linux/adjtime.c>
> -
> -int attribute_compat_text_section
> -__adjtimex_tv32 (struct timex32 *tx) { return ADJTIMEX (tx); }
> -
> -strong_alias (__adjtimex_tv32, __adjtimex_tv32_1);
> -strong_alias (__adjtimex_tv32, __adjtimex_tv32_2);
> -compat_symbol (libc, __adjtimex_tv32_1, __adjtimex, GLIBC_2_0);
> -compat_symbol (libc, __adjtimex_tv32_2, adjtimex, GLIBC_2_0);
> -compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0);
> -#endif /* SHLIB_COMPAT */
> -
> -#undef TIMEVAL
> -#undef TIMEX
> -#undef ADJTIME
> -#undef ADJTIMEX
> -#define TIMEVAL		timeval
> -#define TIMEX		timex
> -#define ADJTIMEX(x)	INLINE_SYSCALL (adjtimex, 1, x)
> -
> -#include <sysdeps/unix/sysv/linux/adjtime.c>
> -
> -int
> -__adjtimex_tv64 (struct timex *tx) { return ADJTIMEX (tx); }
> -
> -libc_hidden_ver (__adjtimex_tv64, __adjtimex)
> -strong_alias (__adjtimex_tv64, __adjtimex_tv64p);
> -weak_alias (__adjtimex_tv64, ntp_adjtime);
> -versioned_symbol (libc, __adjtimex_tv64, __adjtimex, GLIBC_2_1);
> -versioned_symbol (libc, __adjtimex_tv64p, adjtimex, GLIBC_2_1);
> -versioned_symbol (libc, __adjtime, adjtime, GLIBC_2_1);
> diff --git a/sysdeps/unix/sysv/linux/alpha/adjtimex.c
> b/sysdeps/unix/sysv/linux/alpha/adjtimex.c new file mode 100644
> index 0000000000..1a8e0a9529
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/adjtimex.c
> @@ -0,0 +1,22 @@
> +/* adjtimex -- Adjust the current time of day.  Linux/Alpha/tv64
> version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* We can use the generic Linux implementation, but we have to
> override its
> +   default symbol version.  */
> +#define VERSION_adjtimex GLIBC_2.1
> +#include <sysdeps/unix/sysv/linux/adjtimex.c>
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
> b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c new file mode 100644
> index 0000000000..c948ac2dda
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
> @@ -0,0 +1,130 @@
> +/* adjtime -- adjust the system clock.  Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <sys/timex.h>
> +#include <tv32-compat.h>
> +
> +struct timex32 {
> +	unsigned int modes;	/* mode selector */
> +	long offset;		/* time offset (usec) */
> +	long freq;		/* frequency offset (scaled ppm) */
> +	long maxerror;		/* maximum error (usec) */
> +	long esterror;		/* estimated error (usec) */
> +	int status;		/* clock command/status */
> +	long constant;		/* pll time constant */
> +	long precision;		/* clock precision (usec)
> (read only) */
> +	long tolerance;		/* clock frequency tolerance
> (ppm)
> +				 * (read only)
> +				 */
> +	struct timeval32 time;	/* (read only) */
> +	long tick;		/* (modified) usecs between clock
> ticks */ +
> +	long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
> +	long jitter;            /* pps jitter (us) (ro) */
> +	int shift;              /* interval duration (s) (shift)
> (ro) */
> +	long stabil;            /* pps stability (scaled ppm) (ro) */
> +	long jitcnt;            /* jitter limit exceeded (ro) */
> +	long calcnt;            /* calibration intervals (ro) */
> +	long errcnt;            /* calibration errors (ro) */
> +	long stbcnt;            /* stability limit exceeded (ro) */
> +
> +	int  :32; int  :32; int  :32; int  :32;
> +	int  :32; int  :32; int  :32; int  :32;
> +	int  :32; int  :32; int  :32; int  :32;
> +};
> +
> +int
> +attribute_compat_text_section
> +__adjtime_tv32 (const struct timeval32 *itv, struct timeval32 *otv)
> +{
> +  struct timeval itv64, otv64;
> +  tv32_to_tv64 (&itv64, itv);
> +
> +  if (__adjtime (&itv64, &otv64) == -1)
> +    return -1;
> +
> +  tv64_to_tv32 (otv, &itv64);
> +  return 0;
> +}
> +
> +int
> +attribute_compat_text_section
> +__adjtimex_tv32 (struct timex32 *tx)
> +{
> +  struct timex tx64;
> +  memset (&tx64, 0, sizeof tx64);
> +  tx64.modes     = tx->modes;
> +  tx64.offset    = tx->offset;
> +  tx64.freq      = tx->freq;
> +  tx64.maxerror  = tx->maxerror;
> +  tx64.esterror  = tx->esterror;
> +  tx64.status    = tx->status;
> +  tx64.constant  = tx->constant;
> +  tx64.precision = tx->precision;
> +  tx64.tolerance = tx->tolerance;
> +  tx64.tick      = tx->tick;
> +  tx64.ppsfreq   = tx->ppsfreq;
> +  tx64.jitter    = tx->jitter;
> +  tx64.shift     = tx->shift;
> +  tx64.stabil    = tx->stabil;
> +  tx64.jitcnt    = tx->jitcnt;
> +  tx64.calcnt    = tx->calcnt;
> +  tx64.errcnt    = tx->errcnt;
> +  tx64.stbcnt    = tx->stbcnt;
> +  tv32_to_tv64 (&tx64.time, &tx->time);
> +
> +  int status = __adjtimex (&tx64);
> +  if (status < 0)
> +    return status;
> +
> +  memset (tx, 0, sizeof *tx);
> +  tx->modes     = tx64.modes;
> +  tx->offset    = tx64.offset;
> +  tx->freq      = tx64.freq;
> +  tx->maxerror  = tx64.maxerror;
> +  tx->esterror  = tx64.esterror;
> +  tx->status    = tx64.status;
> +  tx->constant  = tx64.constant;
> +  tx->precision = tx64.precision;
> +  tx->tolerance = tx64.tolerance;
> +  tx->tick      = tx64.tick;
> +  tx->ppsfreq   = tx64.ppsfreq;
> +  tx->jitter    = tx64.jitter;
> +  tx->shift     = tx64.shift;
> +  tx->stabil    = tx64.stabil;
> +  tx->jitcnt    = tx64.jitcnt;
> +  tx->calcnt    = tx64.calcnt;
> +  tx->errcnt    = tx64.errcnt;
> +  tx->stbcnt    = tx64.stbcnt;
> +  tv64_to_tv32 (&tx->time, &tx64.time);
> +
> +  return status;
> +}
> +
> +strong_alias (__adjtimex_tv32, __adjtimex_tv32_1);
> +strong_alias (__adjtimex_tv32, __adjtimex_tv32_2);
> +compat_symbol (libc, __adjtimex_tv32_1, __adjtimex, GLIBC_2_0);
> +compat_symbol (libc, __adjtimex_tv32_2, adjtimex, GLIBC_2_0);
> +compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0);
> +
> +#endif /* SHLIB_COMPAT */
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
> b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c new file mode 100644
> index 0000000000..f290954783
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
> @@ -0,0 +1,41 @@
> +/* getitimer -- Get the state of an interval timer.
> Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <tv32-compat.h>
> +
> +int
> +attribute_compat_text_section
> +__getitimer_tv32 (int which, struct itimerval32 *curr_value)
> +{
> +  struct itimerval curr_value_64;
> +  if (__getitimer (which, &curr_value_64) == -1)
> +    return -1;
> +
> +  /* Write all fields of 'curr_value' regardless of overflow.  */
> +  tv64_to_tv32 (&curr_value->it_interval,
> &curr_value_64.it_interval);
> +  tv64_to_tv32 (&curr_value->it_value, &curr_value_64.it_value);
> +  return 0;
> +}
> +
> +compat_symbol (libc, __getitimer_tv32, getitimer, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
> b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c new file mode 100644
> index 0000000000..918e8445d4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
> @@ -0,0 +1,39 @@
> +/* utimes -- change file timestamps.  Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <sys/resource.h>
> +#include <tv32-compat.h>
> +
> +int
> +__getrusage_tv32 (int who, struct rusage32 *usage32)
> +{
> +  struct rusage usage64;
> +  if (__getrusage (who, &usage64) == -1)
> +    return -1;
> +
> +  rusage64_to_rusage32 (usage32, &usage64);
> +  return 0;
> +}
> +
> +compat_symbol (libc, __getrusage_tv32, getrusage, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
> b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c new file mode
> 100644 index 0000000000..e6cc522dd1
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
> @@ -0,0 +1,43 @@
> +/* gettimeofday -- Get the current time of day.  Linux/Alpha/tv32
> version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <tv32-compat.h>
> +
> +/* Get the current time of day and timezone information putting it
> +   into *TV and *TZ.  */
> +
> +int
> +attribute_compat_text_section
> +__gettimeofday_tv32 (struct timeval32 *restrict tv32, void *restrict
> tz) +{
> +  struct timeval tv;
> +  __gettimeofday (&tv, tz);
> +
> +  tv64_to_tv32 (tv32, &tv);
> +  return 0;
> +}
> +
> +compat_symbol (libc, __gettimeofday_tv32, __gettimeofday, GLIBC_2_0);
> +strong_alias (__gettimeofday_tv32, __gettimeofday_tv32_1);
> +compat_symbol (libc, __gettimeofday_tv32_1, gettimeofday, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
> b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c new file mode 100644
> index 0000000000..d6bbcee60a
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
> @@ -0,0 +1,49 @@
> +/* getitimer -- Get the state of an interval timer.
> Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <tv32-compat.h>
> +
> +int
> +attribute_compat_text_section
> +__setitimer_tv32 (int which, const struct itimerval32 *restrict
> new_value,
> +		  struct itimerval32 *restrict old_value)
> +{
> +  struct itimerval new_value_64;
> +  tv32_to_tv64 (&new_value_64.it_interval, &new_value->it_interval);
> +  tv32_to_tv64 (&new_value_64.it_value, &new_value->it_value);
> +
> +  if (old_value == NULL)
> +    return __setitimer (which, &new_value_64, NULL);
> +
> +  struct itimerval old_value_64;
> +  if (__setitimer (which, &new_value_64, &old_value_64) == -1)
> +    return -1;
> +
> +  /* Write all fields of 'old_value' regardless of overflow.  */
> +  tv64_to_tv32 (&old_value->it_interval, &old_value_64.it_interval);
> +  tv64_to_tv32 (&old_value->it_value, &old_value_64.it_value);
> +  return 0;
> +}
> +
> +compat_symbol (libc, __setitimer_tv32, setitimer, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
> b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c new file mode
> 100644 index 0000000000..fb2a36df19
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
> @@ -0,0 +1,41 @@
> +/* settimeofday -- Set the current time of day.  Linux/Alpha/tv32
> version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <time.h>
> +#include <errno.h>
> +#include <tv32-compat.h>
> +
> +/* Set the current time of day and timezone information.
> +   This call is restricted to the super-user.  */
> +int
> +attribute_compat_text_section
> +__settimeofday_tv32 (const struct timeval32 *tv32,
> +                     const struct timezone *tz)
> +{
> +  struct timeval tv;
> +  tv32_to_tv64 (&tv, tv32);
> +  return __settimeofday (&tv, tz);
> +}
> +
> +compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
> b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c new file mode 100644
> index 0000000000..788fb7cd44
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
> @@ -0,0 +1,37 @@
> +/* utimes -- change file timestamps.  Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <tv32-compat.h>
> +
> +int
> +attribute_compat_text_section
> +__utimes_tv32 (const char *filename, const struct timeval32
> times32[2]) +{
> +  struct timeval times[2];
> +  tv32_to_tv64 (&times[0], &times32[0]);
> +  tv32_to_tv64 (&times[1], &times32[1]);
> +  return __utimes (filename, times);
> +}
> +
> +compat_symbol (libc, __utimes_tv32, utimes, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
> b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c new file mode 100644
> index 0000000000..e8db554660
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
> @@ -0,0 +1,41 @@
> +/* wait4 -- wait for process to change state.  Linux/Alpha/tv32
> version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <sys/resource.h>
> +#include <sys/wait.h>
> +#include <tv32-compat.h>
> +
> +pid_t
> +attribute_compat_text_section
> +__wait4_tv32 (pid_t pid, int *status, int options, struct rusage32
> *usage32) +{
> +  struct rusage usage64;
> +  pid_t child = __wait4 (pid, status, options, &usage64);
> +
> +  if (child >= 0 && usage32 != NULL)
> +    rusage64_to_rusage32 (usage32, &usage64);
> +  return child;
> +}
> +
> +compat_symbol (libc, __wait4_tv32, wait4, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list
> b/sysdeps/unix/sysv/linux/alpha/syscalls.list index
> 12cd021b60..c786aa751e 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/syscalls.list +++
> b/sysdeps/unix/sysv/linux/alpha/syscalls.list @@ -1,4 +1,4 @@
> -# File name	Caller	Syscall name	# args
> Strong name	Weak names +# File name	Caller
> Syscall name	Args	Strong name	Weak names 
>  sigstack	-	sigstack	2	sigstack
>  
> @@ -22,23 +22,14 @@ pciconfig_read	EXTRA
> pciconfig_read	5	pciconfig_read pciconfig_write
> EXTRA	pciconfig_write	5	pciconfig_write
> pciconfig_iobase EXTRA	pciconfig_iobase 3
> __pciconfig_iobase pciconfig_iobase -# support old timeval32 entry
> points -osf_gettimeofday -	osf_gettimeofday 2
> __gettimeofday_tv32  __gettimeofday@GLIBC_2.0 gettimeofday@GLIBC_2.0
> -osf_settimeofday -	osf_settimeofday 2
> __settimeofday_tv32  settimeofday@GLIBC_2.0 -osf_getitimer
> -	osf_getitimer	2	__getitimer_tv32
> getitimer@GLIBC_2.0 -osf_setitimer	-
> osf_setitimer	3	__setitimer_tv32  setitimer@GLIBC_2.0
> -osf_utimes	-	osf_utimes	2	__utimes_tv32
> utimes@GLIBC_2.0 -osf_getrusage	-	osf_getrusage
> 2	__getrusage_tv32  getrusage@GLIBC_2.0 -osf_wait4
> -	osf_wait4	4	__wait4_tv32  wait4@GLIBC_2.0 - -#
> support new timeval64 entry points -gettimeofday	-
> gettimeofday	2	__GI___gettimeofday
> gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
> -settimeofday	-	settimeofday	2
> __settimeofday settimeofday@@GLIBC_2.1 -getitimer	-
> getitimer	2	__getitimer getitimer@@GLIBC_2.1
> -setitimer	-	setitimer	3	__setitimer
> setitimer@@GLIBC_2.1 -utimes		-	utimes
> 	2	__utimes utimes@@GLIBC_2.1 -getrusage
> -	getrusage	2	__getrusage getrusage@@GLIBC_2.1
> -wait4		-	wait4		4	__wait4
> wait4@@GLIBC_2.1 +# timeval64 entry points (see osf_*.c for GLIBC_2.0
> timeval32 equivalents) +gettimeofday	-
> gettimeofday	i:pP	__GI___gettimeofday
> gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
> +settimeofday	-	settimeofday	i:PP
> __settimeofday	settimeofday@@GLIBC_2.1 +getitimer
> -	getitimer	i:ip	__getitimer
> getitimer@@GLIBC_2.1 +setitimer	-	setitimer
> i:ipP	__setitimer	setitimer@@GLIBC_2.1 +utimes
> 	-	utimes		i:sp	__utimes
> utimes@@GLIBC_2.1 +getrusage	-	getrusage
> i:ip	__getrusage	getrusage@@GLIBC_2.1 +wait4
> 	-	wait4		i:iWiP	__wait4
> 	wait4@@GLIBC_2.1 # avoid 64-bit aliases on 32-bit statfs
> syscalls fstatfs		-	fstatfs
> i:ip	__fstatfs	fstatfs diff --git
> a/sysdeps/unix/sysv/linux/alpha/tv32-compat.h
> b/sysdeps/unix/sysv/linux/alpha/tv32-compat.h new file mode 100644
> index 0000000000..e1edb7453a --- /dev/null +++
> b/sysdeps/unix/sysv/linux/alpha/tv32-compat.h @@ -0,0 +1,146 @@ +/*
> Compatibility definitions for `struct timeval' with 32-bit time_t.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _TV32_COMPAT_H
> +#define _TV32_COMPAT_H 1
> +
> +#include <features.h>
> +
> +#include <bits/types.h>
> +#include <bits/types/time_t.h>
> +#include <bits/types/struct_timeval.h>
> +#include <bits/types/struct_timespec.h>
> +#include <bits/types/struct_rusage.h>
> +
> +#include <stdint.h> // for INT32_MAX
> +#include <string.h> // for memset
> +
> +#define TV_USEC_MAX 999999 // 10**6 - 1
> +
> +/* A version of 'struct timeval' with 32-bit time_t.  */
> +struct timeval32
> +{
> +  int32_t tv_sec;
> +  int32_t tv_usec;
> +};
> +
> +/* Structures containing 'struct timeval' with 32-bit time_t.  */
> +struct itimerval32
> +{
> +  struct timeval32 it_interval;
> +  struct timeval32 it_value;
> +};
> +
> +struct rusage32
> +{
> +  struct timeval32 ru_utime;	/* user time used */
> +  struct timeval32 ru_stime;	/* system time used */
> +  long ru_maxrss;		/* maximum resident set size */
> +  long ru_ixrss;		/* integral shared memory size */
> +  long ru_idrss;		/* integral unshared data size */
> +  long ru_isrss;		/* integral unshared stack size */
> +  long ru_minflt;		/* page reclaims */
> +  long ru_majflt;		/* page faults */
> +  long ru_nswap;		/* swaps */
> +  long ru_inblock;		/* block input operations */
> +  long ru_oublock;		/* block output operations */
> +  long ru_msgsnd;		/* messages sent */
> +  long ru_msgrcv;		/* messages received */
> +  long ru_nsignals;		/* signals received */
> +  long ru_nvcsw;		/* voluntary context switches */
> +  long ru_nivcsw;		/* involuntary " */
> +};
> +
> +/* Conversion functions.  If the seconds field of a timeval32 would
> +   overflow, they write { INT32_MAX, TV_USEC_MAX } to the output.  */
> +
> +static inline void
> +tv32_to_tv64 (struct timeval *restrict tv64,
> +              const struct timeval32 *restrict tv32)
> +{
> +  tv64->tv_sec = tv32->tv_sec;
> +  tv64->tv_usec = tv32->tv_usec;
> +}
> +
> +static inline void
> +tv32_to_ts64 (struct timespec *restrict ts64,
> +              const struct timeval32 *restrict tv32)
> +{
> +  ts64->tv_sec = tv32->tv_sec;
> +  ts64->tv_nsec = tv32->tv_usec * 1000;
> +}

The ./include/time.h already provides such helper conversion function -
valid_timeval_to_timespec64 ();

There are also defined:
valid_timespec_to_timespec64 ();
valid_timespec64_to_timespec ();
valid_timespec64_to_timeval ();

There is also a different approach (as suggested some time ago by Paul)
- those helper functions now return the converted structure and accept
  value (not pointer) to convert.

> +
> +static inline void
> +tv64_to_tv32 (struct timeval32 *restrict tv32,
> +              const struct timeval *restrict tv64)
> +{
> +  if (__glibc_unlikely (tv64->tv_sec > (time_t) INT32_MAX))
> +    {
> +      tv32->tv_sec = INT32_MAX;
> +      tv32->tv_usec = TV_USEC_MAX;
> +    }
> +  else
> +    {
> +      tv32->tv_sec = tv64->tv_sec;
> +      tv32->tv_usec = tv64->tv_usec;
> +    }
> +}
> +
> +static inline void
> +ts64_to_tv32 (struct timeval32 *restrict tv32,
> +              const struct timespec *restrict ts64)
> +{
> +  if (__glibc_unlikely (ts64->tv_sec > (time_t) INT32_MAX))
> +    {
> +      tv32->tv_sec = INT32_MAX;
> +      tv32->tv_usec = TV_USEC_MAX;
> +    }
> +  else
> +    {
> +      tv32->tv_sec = ts64->tv_sec;
> +      tv32->tv_usec = ts64->tv_nsec / 1000;
> +    }
> +}
> +
> +static inline void
> +rusage64_to_rusage32 (struct rusage32 *restrict r32,
> +                      const struct rusage *restrict r64)
> +{
> +  /* Make sure the entire output structure is cleared, including
> +     padding and reserved fields.  */
> +  memset (r32, 0, sizeof *r32);
> +
> +  tv64_to_tv32 (&r32->ru_utime, &r64->ru_utime);
> +  tv64_to_tv32 (&r32->ru_stime, &r64->ru_stime);
> +  r32->ru_maxrss   = r64->ru_maxrss;
> +  r32->ru_ixrss    = r64->ru_ixrss;
> +  r32->ru_idrss    = r64->ru_idrss;
> +  r32->ru_isrss    = r64->ru_isrss;
> +  r32->ru_minflt   = r64->ru_minflt;
> +  r32->ru_majflt   = r64->ru_majflt;
> +  r32->ru_nswap    = r64->ru_nswap;
> +  r32->ru_inblock  = r64->ru_inblock;
> +  r32->ru_oublock  = r64->ru_oublock;
> +  r32->ru_msgsnd   = r64->ru_msgsnd;
> +  r32->ru_msgrcv   = r64->ru_msgrcv;
> +  r32->ru_nsignals = r64->ru_nsignals;
> +  r32->ru_nvcsw    = r64->ru_nvcsw;
> +  r32->ru_nivcsw   = r64->ru_nivcsw;
> +}
> +
> +#endif /* tv32-compat.h */
> diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c
> b/sysdeps/unix/sysv/linux/gettimeofday.c index d69d4eaa96..c9597d6405
> 100644 --- a/sysdeps/unix/sysv/linux/gettimeofday.c
> +++ b/sysdeps/unix/sysv/linux/gettimeofday.c
> @@ -30,10 +30,20 @@
>     putting it into *tv and *tz.  If tz is null, *tz is not filled.
>     Returns 0 on success, -1 on errors.  */
>  int
> -__gettimeofday (struct timeval *tv, struct timezone *tz)
> +___gettimeofday (struct timeval *tv, struct timezone *tz)
>  {
>    return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
>  }
> +
> +#ifdef VERSION_gettimeofday
> +weak_alias (___gettimeofday, __wgettimeofday);
> +default_symbol_version (___gettimeofday, __gettimeofday,
> VERSION_gettimeofday); +default_symbol_version (__wgettimeofday,
> gettimeofday, VERSION_gettimeofday); +libc_hidden_ver
> (___gettimeofday, __gettimeofday); +libc_hidden_ver (___gettimeofday,
> gettimeofday); +#else
> +strong_alias (___gettimeofday, __gettimeofday)
> +weak_alias (___gettimeofday, gettimeofday)
>  libc_hidden_def (__gettimeofday)
> -weak_alias (__gettimeofday, gettimeofday)
>  libc_hidden_weak (gettimeofday)
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/syscalls.list
> b/sysdeps/unix/sysv/linux/syscalls.list index e374f97b5f..cdcf6c127b
> 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/syscalls.list
> @@ -1,6 +1,5 @@
>  # File name	Caller	Syscall name	Args
> Strong name	Weak names 
> -adjtimex	adjtime	adjtimex	i:p
> __adjtimex	adjtimex ntp_adjtime alarm		-
> alarm		i:i	alarm bdflush
> EXTRA	bdflush		i:ii
> __compat_bdflush	bdflush@GLIBC_2.0:GLIBC_2.23 capget
> 	EXTRA	capget		i:pp	capget




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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 02/11] Change most internal uses of __gettimeofday to __clock_gettime.
  2019-10-25 12:09 ` [PATCH v2 02/11] Change most internal uses of __gettimeofday to __clock_gettime Adhemerval Zanella
@ 2019-10-25 13:26   ` Lukasz Majewski
  0 siblings, 0 replies; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-25 13:26 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Zack Weinberg

[-- Attachment #1: Type: text/plain, Size: 32453 bytes --]

On Fri, 25 Oct 2019 09:08:23 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> From: Zack Weinberg <zackw@panix.com>
> 
> Changes from previous version:
> 
>   - Fixed some indentation and style issues.
> 
>   - Use external clock_gettime on memusage.h.
> 
>   - Fixed some conformant issues on Hurd.
> 
> --
> 
> Since gettimeofday will shortly be implemented in terms of
> clock_gettime on all platforms, internal code should use clock_gettime
> directly; in addition to removing a layer of indirection, this will
> allow us to remove the PLT-bypass gunk for gettimeofday.  (We can't
> quite do that yet, but it'll be coming later in this patch series.)
> In many cases, the changed code does fewer conversions.
> 
> The changed code always assumes __clock_gettime (CLOCK_REALTIME)
> cannot fail.  Most of the call sites were assuming gettimeofday could
> not fail, but a few places were checking for errors.  POSIX says
> clock_gettime can only fail if the clock constant is invalid or
> unsupported, and CLOCK_REALTIME is the one and only clock constant
> that's required to be supported.  For consistency I grepped the entire
> source tree for any other places that checked for errors from
> __clock_gettime (CLOCK_REALTIME), found one, and changed it too.
> 
> (For the record, POSIX also says gettimeofday can never fail.)
> 
> (It would be nice if we could declare that GNU systems will always
> support CLOCK_MONOTONIC as well as CLOCK_REALTIME; there are several
> places where we are using CLOCK_REALTIME where _MONOTONIC would be
> more appropriate, and/or trying to use _MONOTONIC and then falling
> back to _REALTIME.  But the Hurd doesn't support CLOCK_MONOTONIC yet,
> and it looks like adding it would involve substantial changes to
> gnumach's internals and API.  Oh well.)
> 
> A few Hurd-specific files were changed to use __host_get_time instead
> of __clock_gettime, as this seemed tidier.  We also assume this cannot
> fail.  Skimming the code in gnumach leads me to believe the only way
> it could fail is if __mach_host_self also failed, and our
> Hurd-specific code consistently assumes that can't happen, so I'm
> going with that.
> 
> With the exception of support/support_test_main.c, test cases are not
> modified, mainly because I didn't want to have to figure out which
> test cases were testing gettimeofday specifically.
> 
> The definition of GETTIME in sysdeps/generic/memusage.h had a typo and
> was not reading tv_sec at all.  I fixed this.  It appears nobody has
> been generating malloc traces on a machine that doesn't have a
> superseding definition.
> 
> There are a whole bunch of places where the code could be simplified
> by factoring out timespec subtraction and/or comparison logic, but I
> want to keep this patch as mechanical as possible.
> 
> Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
> powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.
> 
> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
>  inet/deadline.c                |  8 +-------
>  login/logout.c                 |  9 +++++----
>  login/logwtmp.c                |  7 +++----
>  nis/nis_call.c                 |  4 +++-
>  nptl/pthread_join_common.c     |  7 +++----
>  nptl/pthread_mutex_timedlock.c |  7 +++----
>  nscd/nscd_helper.c             | 24 +++++++++++------------
>  resolv/gai_misc.c              |  6 +++---
>  resolv/gai_suspend.c           |  6 +++---
>  resolv/res_send.c              |  7 +------
>  sunrpc/auth_des.c              | 19 ++++++++++--------
>  sunrpc/auth_unix.c             |  9 +++++----
>  sunrpc/create_xid.c            |  6 +++---
>  sunrpc/svcauth_des.c           |  7 ++++++-
>  support/support_test_main.c    | 23 +++++++++++-----------
>  sysdeps/generic/memusage.h     | 16 +++++++--------
>  sysdeps/mach/hurd/getitimer.c  | 11 ++++++++---
>  sysdeps/mach/hurd/setitimer.c  | 13 ++++++------
>  sysdeps/mach/hurd/times.c      |  7 +++----
>  sysdeps/mach/nanosleep.c       | 36
> ++++++++++++++++++++++------------ sysdeps/mach/usleep.c          |
> 5 ----- sysdeps/posix/tempname.c       |  9 ++++-----
>  sysdeps/posix/timespec_get.c   | 14 ++++---------
>  sysdeps/pthread/aio_misc.c     |  6 +++---
>  sysdeps/pthread/aio_suspend.c  |  6 +++---
>  sysdeps/unix/make-syscalls.sh  |  2 +-
>  26 files changed, 137 insertions(+), 137 deletions(-)
> 
> diff --git a/inet/deadline.c b/inet/deadline.c
> index 6051f1fe0c..541c16bd9a 100644
> --- a/inet/deadline.c
> +++ b/inet/deadline.c
> @@ -29,13 +29,7 @@ __deadline_current_time (void)
>  {
>    struct deadline_current_time result;
>    if (__clock_gettime (CLOCK_MONOTONIC, &result.current) != 0)
> -    {
> -      struct timeval current_tv;
> -      if (__gettimeofday (&current_tv, NULL) == 0)
> -        __libc_fatal ("Fatal error: gettimeofday system call
> failed\n");
> -      result.current.tv_sec = current_tv.tv_sec;
> -      result.current.tv_nsec = current_tv.tv_usec * 1000;
> -    }
> +    __clock_gettime (CLOCK_REALTIME, &result.current);
>    assert (result.current.tv_sec >= 0);
>    return result;
>  }
> diff --git a/login/logout.c b/login/logout.c
> index d0d421cbf7..b8b38df19d 100644
> --- a/login/logout.c
> +++ b/login/logout.c
> @@ -19,6 +19,7 @@
>  #include <errno.h>
>  #include <string.h>
>  #include <utmp.h>
> +#include <time.h>
>  #include <sys/time.h>
>  
>  int
> @@ -45,10 +46,10 @@ logout (const char *line)
>        /* Clear information about who & from where.  */
>        memset (ut->ut_name, '\0', sizeof ut->ut_name);
>        memset (ut->ut_host, '\0', sizeof ut->ut_host);
> -      struct timeval tv;
> -      __gettimeofday (&tv, NULL);
> -      ut->ut_tv.tv_sec = tv.tv_sec;
> -      ut->ut_tv.tv_usec = tv.tv_usec;
> +
> +      struct timespec ts;
> +      __clock_gettime (CLOCK_REALTIME, &ts);
> +      TIMESPEC_TO_TIMEVAL (&ut->ut_tv, &ts);
>        ut->ut_type = DEAD_PROCESS;
>  
>        if (pututline (ut) != NULL)
> diff --git a/login/logwtmp.c b/login/logwtmp.c
> index 654f412ecb..eddba96f35 100644
> --- a/login/logwtmp.c
> +++ b/login/logwtmp.c
> @@ -36,10 +36,9 @@ logwtmp (const char *line, const char *name, const
> char *host) strncpy (ut.ut_name, name, sizeof ut.ut_name);
>    strncpy (ut.ut_host, host, sizeof ut.ut_host);
>  
> -  struct timeval tv;
> -  __gettimeofday (&tv, NULL);
> -  ut.ut_tv.tv_sec = tv.tv_sec;
> -  ut.ut_tv.tv_usec = tv.tv_usec;
> +  struct timespec ts;
> +  __clock_gettime (CLOCK_REALTIME, &ts);
> +  TIMESPEC_TO_TIMEVAL (&ut.ut_tv, &ts);
>  
>    updwtmp (_PATH_WTMP, &ut);
>  }
> diff --git a/nis/nis_call.c b/nis/nis_call.c
> index 1684de1c6d..5097e614ea 100644
> --- a/nis/nis_call.c
> +++ b/nis/nis_call.c
> @@ -709,6 +709,7 @@ __nisfind_server (const_nis_name name, int
> search_parent, nis_error status;
>    directory_obj *obj;
>    struct timeval now;
> +  struct timespec ts;
>    unsigned int server_used = ~0;
>    unsigned int current_ep = ~0;
>  
> @@ -718,7 +719,8 @@ __nisfind_server (const_nis_name name, int
> search_parent, if (*dir != NULL)
>      return NIS_SUCCESS;
>  
> -  (void) gettimeofday (&now, NULL);
> +  __clock_gettime (CLOCK_REALTIME, &ts);
> +  TIMESPEC_TO_TIMEVAL (&now, &ts);
>  
>    if ((flags & NO_CACHE) == 0)
>      *dir = nis_server_cache_search (name, search_parent,
> &server_used, diff --git a/nptl/pthread_join_common.c
> b/nptl/pthread_join_common.c index 9545ae4bd3..ad3073e32d 100644
> --- a/nptl/pthread_join_common.c
> +++ b/nptl/pthread_join_common.c
> @@ -46,15 +46,14 @@ timedwait_tid (pid_t *tidp, const struct timespec
> *abstime) /* Repeat until thread terminated.  */
>    while ((tid = *tidp) != 0)
>      {
> -      struct timeval tv;
>        struct timespec rt;
>  
>        /* Get the current time.  */
> -      __gettimeofday (&tv, NULL);
> +      __clock_gettime (CLOCK_REALTIME, &rt);
>  
>        /* Compute relative timeout.  */
> -      rt.tv_sec = abstime->tv_sec - tv.tv_sec;
> -      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
> +      rt.tv_sec = abstime->tv_sec - rt.tv_sec;
> +      rt.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
>        if (rt.tv_nsec < 0)
>          {
>            rt.tv_nsec += 1000000000;
> diff --git a/nptl/pthread_mutex_timedlock.c
> b/nptl/pthread_mutex_timedlock.c index a0ce044dd4..7a5be6b997 100644
> --- a/nptl/pthread_mutex_timedlock.c
> +++ b/nptl/pthread_mutex_timedlock.c
> @@ -567,15 +567,14 @@ __pthread_mutex_clocklock_common
> (pthread_mutex_t *mutex, goto failpp;
>  		      }
>  
> -		    struct timeval tv;
>  		    struct timespec rt;
>  
>  		    /* Get the current time.  */
> -		    (void) __gettimeofday (&tv, NULL);
> +		    __clock_gettime (CLOCK_REALTIME, &rt);
>  
>  		    /* Compute relative timeout.  */
> -		    rt.tv_sec = abstime->tv_sec - tv.tv_sec;
> -		    rt.tv_nsec = abstime->tv_nsec - tv.tv_usec *
> 1000;
> +		    rt.tv_sec = abstime->tv_sec - rt.tv_sec;
> +		    rt.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
>  		    if (rt.tv_nsec < 0)
>  		      {
>  			rt.tv_nsec += 1000000000;
> diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
> index d326a380ee..7361fe2e0a 100644
> --- a/nscd/nscd_helper.c
> +++ b/nscd/nscd_helper.c
> @@ -59,9 +59,10 @@ wait_on_socket (int sock, long int usectmo)
>        /* Handle the case where the poll() call is interrupted by a
>  	 signal.  We cannot just use TEMP_FAILURE_RETRY since it
> might lead to infinite loops.  */
> -      struct timeval now;
> -      (void) __gettimeofday (&now, NULL);
> -      long int end = now.tv_sec * 1000 + usectmo + (now.tv_usec +
> 500) / 1000;
> +      struct timespec now;
> +      __clock_gettime (CLOCK_REALTIME, &now);
> +      long int end = (now.tv_sec * 1000 + usectmo
> +                      + (now.tv_nsec + 500000) / 1000000);
>        long int timeout = usectmo;
>        while (1)
>  	{
> @@ -70,8 +71,9 @@ wait_on_socket (int sock, long int usectmo)
>  	    break;
>  
>  	  /* Recompute the timeout time.  */
> -	  (void) __gettimeofday (&now, NULL);
> -	  timeout = end - (now.tv_sec * 1000 + (now.tv_usec + 500) /
> 1000);
> +          __clock_gettime (CLOCK_REALTIME, &now);
> +	  timeout = end - ((now.tv_sec * 1000
> +                            + (now.tv_nsec + 500000) / 1000000));
>  	}
>      }
>  
> @@ -191,9 +193,7 @@ open_socket (request_type type, const char *key,
> size_t keylen) memcpy (reqdata->key, key, keylen);
>  
>    bool first_try = true;
> -  struct timeval tvend;
> -  /* Fake initializing tvend.  */
> -  asm ("" : "=m" (tvend));
> +  struct timespec tvend = { 0, 0 };
>    while (1)
>      {
>  #ifndef MSG_NOSIGNAL
> @@ -212,18 +212,18 @@ open_socket (request_type type, const char
> *key, size_t keylen) 
>        /* The daemon is busy wait for it.  */
>        int to;
> -      struct timeval now;
> -      (void) __gettimeofday (&now, NULL);
> +      struct timespec now;
> +      __clock_gettime (CLOCK_REALTIME, &now);
>        if (first_try)
>  	{
> -	  tvend.tv_usec = now.tv_usec;
> +	  tvend.tv_nsec = now.tv_nsec;
>  	  tvend.tv_sec = now.tv_sec + 5;
>  	  to = 5 * 1000;
>  	  first_try = false;
>  	}
>        else
>  	to = ((tvend.tv_sec - now.tv_sec) * 1000
> -	      + (tvend.tv_usec - now.tv_usec) / 1000);
> +	      + (tvend.tv_nsec - now.tv_nsec) / 1000000);
>  
>        struct pollfd fds[1];
>        fds[0].fd = sock;
> diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c
> index 8738359d81..760c33ac29 100644
> --- a/resolv/gai_misc.c
> +++ b/resolv/gai_misc.c
> @@ -357,13 +357,13 @@ handle_requests (void *arg)
>  	 something to arrive in it. */
>        if (runp == NULL && optim.gai_idle_time >= 0)
>  	{
> -	  struct timeval now;
> +	  struct timespec now;
>  	  struct timespec wakeup_time;
>  
>  	  ++idle_thread_count;
> -	  gettimeofday (&now, NULL);
> +          __clock_gettime (CLOCK_REALTIME, &now);
>  	  wakeup_time.tv_sec = now.tv_sec + optim.gai_idle_time;
> -	  wakeup_time.tv_nsec = now.tv_usec * 1000;
> +	  wakeup_time.tv_nsec = now.tv_nsec;
>  	  if (wakeup_time.tv_nsec >= 1000000000)
>  	    {
>  	      wakeup_time.tv_nsec -= 1000000000;
> diff --git a/resolv/gai_suspend.c b/resolv/gai_suspend.c
> index 16d6998980..b8c642bddc 100644
> --- a/resolv/gai_suspend.c
> +++ b/resolv/gai_suspend.c
> @@ -91,11 +91,11 @@ gai_suspend (const struct gaicb *const list[],
> int ent, {
>  	  /* We have to convert the relative timeout value into an
>  	     absolute time value with pthread_cond_timedwait
> expects.  */
> -	  struct timeval now;
> +	  struct timespec now;
>  	  struct timespec abstime;
>  
> -	  __gettimeofday (&now, NULL);
> -	  abstime.tv_nsec = timeout->tv_nsec + now.tv_usec * 1000;
> +          __clock_gettime (CLOCK_REALTIME, &now);
> +	  abstime.tv_nsec = timeout->tv_nsec + now.tv_nsec;
>  	  abstime.tv_sec = timeout->tv_sec + now.tv_sec;
>  	  if (abstime.tv_nsec >= 1000000000)
>  	    {
> diff --git a/resolv/res_send.c b/resolv/res_send.c
> index 6b9c73f820..47bfba6747 100644
> --- a/resolv/res_send.c
> +++ b/resolv/res_send.c
> @@ -172,12 +172,7 @@ evCmpTime(struct timespec a, struct timespec b) {
>  
>  static void
>  evNowTime(struct timespec *res) {
> -	struct timeval now;
> -
> -	if (gettimeofday(&now, NULL) < 0)
> -		evConsTime(res, 0, 0);
> -	else
> -		TIMEVAL_TO_TIMESPEC (&now, res);
> +	__clock_gettime(CLOCK_REALTIME, res);
>  }
>  
>  
> diff --git a/sunrpc/auth_des.c b/sunrpc/auth_des.c
> index 5b6f985bc2..d26820a701 100644
> --- a/sunrpc/auth_des.c
> +++ b/sunrpc/auth_des.c
> @@ -41,6 +41,7 @@
>  #include <rpc/xdr.h>
>  #include <netinet/in.h>		/* XXX: just to get htonl()
> and ntohl() */ #include <sys/socket.h>
> +#include <time.h>
>  #include <shlib-compat.h>
>  
>  #define MILLION		1000000L
> @@ -246,15 +247,15 @@ authdes_marshal (AUTH *auth, XDR *xdrs)
>    int status;
>    int len;
>    register int32_t *ixdr;
> -  struct timeval tval;
> +  struct timespec now;
>  
>    /*
>     * Figure out the "time", accounting for any time difference
>     * with the server if necessary.
>     */
> -  __gettimeofday (&tval, (struct timezone *) NULL);
> -  ad->ad_timestamp.tv_sec = tval.tv_sec + ad->ad_timediff.tv_sec;
> -  ad->ad_timestamp.tv_usec = tval.tv_usec + ad->ad_timediff.tv_usec;
> +  __clock_gettime (CLOCK_REALTIME, &now);
> +  ad->ad_timestamp.tv_sec = now.tv_sec + ad->ad_timediff.tv_sec;
> +  ad->ad_timestamp.tv_usec = (now.tv_nsec / 1000) +
> ad->ad_timediff.tv_usec; if (ad->ad_timestamp.tv_usec >= MILLION)
>      {
>        ad->ad_timestamp.tv_usec -= MILLION;
> @@ -445,21 +446,23 @@ authdes_destroy (AUTH *auth)
>  static bool_t
>  synchronize (struct sockaddr *syncaddr, struct rpc_timeval *timep)
>  {
> -  struct timeval mytime;
> +  struct timespec mytime;
>    struct rpc_timeval timeout;
> +  long int myusec;
>  
>    timeout.tv_sec = RTIME_TIMEOUT;
>    timeout.tv_usec = 0;
>    if (rtime ((struct sockaddr_in *) syncaddr, timep, &timeout) < 0)
>      return FALSE;
>  
> -  __gettimeofday (&mytime, (struct timezone *) NULL);
> +  __clock_gettime (CLOCK_REALTIME, &mytime);
>    timep->tv_sec -= mytime.tv_sec;
> -  if (mytime.tv_usec > timep->tv_usec)
> +  myusec = mytime.tv_nsec / 1000;
> +  if (myusec > timep->tv_usec)
>      {
>        timep->tv_sec -= 1;
>        timep->tv_usec += MILLION;
>      }
> -  timep->tv_usec -= mytime.tv_usec;
> +  timep->tv_usec -= myusec;
>    return TRUE;
>  }
> diff --git a/sunrpc/auth_unix.c b/sunrpc/auth_unix.c
> index b035fdd870..ff0d2eb933 100644
> --- a/sunrpc/auth_unix.c
> +++ b/sunrpc/auth_unix.c
> @@ -43,6 +43,7 @@
>  #include <stdio.h>
>  #include <string.h>
>  #include <unistd.h>
> +#include <time.h>
>  #include <libintl.h>
>  #include <sys/param.h>
>  #include <wchar.h>
> @@ -96,7 +97,7 @@ authunix_create (char *machname, uid_t uid, gid_t
> gid, int len, {
>    struct authunix_parms aup;
>    char mymem[MAX_AUTH_BYTES];
> -  struct timeval now;
> +  struct timespec now;
>    XDR xdrs;
>    AUTH *auth;
>    struct audata *au;
> @@ -122,7 +123,7 @@ no_memory:
>    /*
>     * fill in param struct from the given params
>     */
> -  (void) __gettimeofday (&now, (struct timezone *) 0);
> +  __clock_gettime (CLOCK_REALTIME, &now);
>    aup.aup_time = now.tv_sec;
>    aup.aup_machname = machname;
>    aup.aup_uid = uid;
> @@ -276,7 +277,7 @@ authunix_refresh (AUTH *auth)
>  {
>    struct audata *au = AUTH_PRIVATE (auth);
>    struct authunix_parms aup;
> -  struct timeval now;
> +  struct timespec now;
>    XDR xdrs;
>    int stat;
>  
> @@ -297,7 +298,7 @@ authunix_refresh (AUTH *auth)
>      goto done;
>  
>    /* update the time and serialize in place */
> -  (void) __gettimeofday (&now, (struct timezone *) 0);
> +  __clock_gettime (CLOCK_REALTIME, &now);
>    aup.aup_time = now.tv_sec;
>    xdrs.x_op = XDR_ENCODE;
>    XDR_SETPOS (&xdrs, 0);
> diff --git a/sunrpc/create_xid.c b/sunrpc/create_xid.c
> index 1339615a1b..c692c1eb92 100644
> --- a/sunrpc/create_xid.c
> +++ b/sunrpc/create_xid.c
> @@ -39,10 +39,10 @@ _create_xid (void)
>    pid_t pid = getpid ();
>    if (is_initialized != pid)
>      {
> -      struct timeval now;
> +      struct timespec now;
>  
> -      __gettimeofday (&now, (struct timezone *) 0);
> -      __srand48_r (now.tv_sec ^ now.tv_usec ^ pid,
> +      __clock_gettime (CLOCK_REALTIME, &now);
> +      __srand48_r (now.tv_sec ^ now.tv_nsec ^ pid,
>  		   &__rpc_lrand48_data);
>        is_initialized = pid;
>      }
> diff --git a/sunrpc/svcauth_des.c b/sunrpc/svcauth_des.c
> index c5a512d6f8..7607abc818 100644
> --- a/sunrpc/svcauth_des.c
> +++ b/sunrpc/svcauth_des.c
> @@ -44,6 +44,7 @@
>  #include <limits.h>
>  #include <string.h>
>  #include <stdint.h>
> +#include <time.h>
>  #include <sys/param.h>
>  #include <netinet/in.h>
>  #include <rpc/rpc.h>
> @@ -295,7 +296,11 @@ _svcauth_des (register struct svc_req *rqst,
> register struct rpc_msg *msg) debug ("timestamp before last seen");
>  	return AUTH_REJECTEDVERF;	/* replay */
>        }
> -    __gettimeofday (&current, (struct timezone *) NULL);
> +    {
> +      struct timespec now;
> +      __clock_gettime (CLOCK_REALTIME, &now);
> +      TIMESPEC_TO_TIMEVAL (&current, &now);
> +    }
>      current.tv_sec -= window;	/* allow for expiration */
>      if (!BEFORE (&current, &timestamp))
>        {
> diff --git a/support/support_test_main.c b/support/support_test_main.c
> index 05ad92e688..d6b3a8d45f 100644
> --- a/support/support_test_main.c
> +++ b/support/support_test_main.c
> @@ -88,16 +88,18 @@ static pid_t test_pid;
>  static void (*cleanup_function) (void);
>  
>  static void
> -print_timestamp (const char *what, struct timeval tv)
> +print_timestamp (const char *what, struct timespec tv)
>  {
>    struct tm tm;
> +  /* Casts of tv.tv_nsec below are necessary because the type of
> +     tv_nsec is not literally long int on all supported platforms.
> */ if (gmtime_r (&tv.tv_sec, &tm) == NULL)
> -    printf ("%s: %lld.%06d\n",
> -            what, (long long int) tv.tv_sec, (int) tv.tv_usec);
> +    printf ("%s: %lld.%09ld\n",
> +            what, (long long int) tv.tv_sec, (long int) tv.tv_nsec);
>    else
> -    printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%06d\n",
> +    printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%09ld\n",
>              what, 1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
> -            tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec);
> +            tm.tm_hour, tm.tm_min, tm.tm_sec, (long int) tv.tv_nsec);
>  }
>  
>  /* Timeout handler.  We kill the child and exit with an error.  */
> @@ -110,8 +112,8 @@ signal_handler (int sig)
>  
>    /* Do this first to avoid further interference from the
>       subprocess.  */
> -  struct timeval now;
> -  bool now_available = gettimeofday (&now, NULL) == 0;
> +  struct timespec now;
> +  clock_gettime (CLOCK_REALTIME, &now);
>    struct stat64 st;
>    bool st_available = fstat64 (STDOUT_FILENO, &st) == 0 &&
> st.st_mtime != 0; 
> @@ -165,12 +167,9 @@ signal_handler (int sig)
>      printf ("Timed out: killed the child process but it exited %d\n",
>              WEXITSTATUS (status));
>  
> -  if (now_available)
> -    print_timestamp ("Termination time", now);
> +  print_timestamp ("Termination time", now);
>    if (st_available)
> -    print_timestamp ("Last write to standard output",
> -                     (struct timeval) { st.st_mtim.tv_sec,
> -                         st.st_mtim.tv_nsec / 1000 });
> +    print_timestamp ("Last write to standard output", st.st_mtim);
>  
>    /* Exit with an error.  */
>    exit (1);
> diff --git a/sysdeps/generic/memusage.h b/sysdeps/generic/memusage.h
> index 400fe23f29..88b291e3fa 100644
> --- a/sysdeps/generic/memusage.h
> +++ b/sysdeps/generic/memusage.h
> @@ -26,14 +26,14 @@
>  #endif
>  
>  #ifndef GETTIME
> -# define GETTIME(low,high) \
> -  {
> 	      \
> -    struct timeval tval;
> 	      \
> -    uint64_t usecs;
> 	      \
> -    gettimeofday (&tval, NULL);
> 		      \
> -    usecs = (uint64_t) tval.tv_usec + (uint64_t) tval.tv_usec *
> 1000000;      \
> -    low = usecs & 0xffffffff;
> 	      \
> -    high = usecs >> 32;
> 		      \ +# define GETTIME(low,high)
> 				   \
> +  {
> 	   \
> +    struct timespec now;
> 	   \
> +    uint64_t usecs;
> 	   \
> +    clock_gettime (CLOCK_REALTIME, &now);
> 	   \
> +    usecs = (uint64_t)now.tv_nsec / 1000 + (uint64_t)now.tv_sec *
> 1000000; \
> +    low = usecs & 0xffffffff;
> 	   \
> +    high = usecs >> 32;
> 		   \ }
>  #endif
>  
> diff --git a/sysdeps/mach/hurd/getitimer.c
> b/sysdeps/mach/hurd/getitimer.c index f332f0e681..0982357815 100644
> --- a/sysdeps/mach/hurd/getitimer.c
> +++ b/sysdeps/mach/hurd/getitimer.c
> @@ -19,8 +19,9 @@
>  #include <errno.h>
>  #include <sys/time.h>
>  #include <hurd.h>
> +#include <mach.h>
>  
> -/* XXX Temporary cheezoid implementation; see __setitmr.c.  */
> +/* XXX Temporary cheezoid implementation; see setitimer.c.  */
>  
>  /* These are defined in __setitmr.c.  */
>  extern spin_lock_t _hurd_itimer_lock;
> @@ -61,8 +62,12 @@ __getitimer (enum __itimer_which which, struct
> itimerval *value) }
>  
>    /* Get the time now.  */
> -  if (__gettimeofday (&elapsed, NULL) < 0)
> -    return -1;
> +  {
> +     time_value_t tv;
> +     __host_get_time (__mach_host_self (), &tv);
> +     elapsed.tv_sec = tv.seconds;
> +     elapsed.tv_usec = tv.microseconds;
> +  }
>  
>    /* Extract the current timer setting; and the time it was set, so
> we can calculate the time elapsed so far.  */
> diff --git a/sysdeps/mach/hurd/setitimer.c
> b/sysdeps/mach/hurd/setitimer.c index 34b433914c..2aab365c31 100644
> --- a/sysdeps/mach/hurd/setitimer.c
> +++ b/sysdeps/mach/hurd/setitimer.c
> @@ -23,6 +23,7 @@
>  #include <hurd/signal.h>
>  #include <hurd/sigpreempt.h>
>  #include <hurd/msg_request.h>
> +#include <mach.h>
>  #include <mach/message.h>
>  
>  /* XXX Temporary cheezoid implementation of ITIMER_REAL/SIGALRM.  */
> @@ -243,12 +244,12 @@ setitimer_locked (const struct itimerval *new,
> struct itimerval *old, if ((newval.it_value.tv_sec |
> newval.it_value.tv_usec) != 0 || old != NULL) {
>        /* Calculate how much time is remaining for the pending alarm.
>  */
> -      if (__gettimeofday (&now, NULL) < 0)
> -	{
> -	  __spin_unlock (&_hurd_itimer_lock);
> -	  _hurd_critical_section_unlock (crit);
> -	  return -1;
> -	}
> +      {
> +	time_value_t tv;
> +	__host_get_time (__mach_host_self (), &tv);
> +	now.tv_sec = tv.seconds;
> +	now.tv_usec = tv.microseconds;
> +      }
>        elapsed = now;
>        subtract_timeval (&elapsed, &_hurd_itimer_started);
>        remaining = _hurd_itimerval.it_value;
> diff --git a/sysdeps/mach/hurd/times.c b/sysdeps/mach/hurd/times.c
> index 3aac803c51..56a0062cd5 100644
> --- a/sysdeps/mach/hurd/times.c
> +++ b/sysdeps/mach/hurd/times.c
> @@ -42,7 +42,7 @@ __times (struct tms *tms)
>    struct task_basic_info bi;
>    struct task_thread_times_info tti;
>    mach_msg_type_number_t count;
> -  union { time_value_t tvt; struct timeval tv; } now;
> +  time_value_t now;
>    error_t err;
>  
>    count = TASK_BASIC_INFO_COUNT;
> @@ -65,10 +65,9 @@ __times (struct tms *tms)
>    /* XXX This can't be implemented until getrusage(RUSAGE_CHILDREN)
> can be.  */ tms->tms_cutime = tms->tms_cstime = 0;
>  
> -  if (__gettimeofday (&now.tv, NULL) < 0)
> -    return -1;
> +  __host_get_time (__mach_host_self (), &now);
>  
> -  return (clock_from_time_value (&now.tvt)
> +  return (clock_from_time_value (&now)
>  	  - clock_from_time_value (&bi.creation_time));
>  }
>  weak_alias (__times, times)
> diff --git a/sysdeps/mach/nanosleep.c b/sysdeps/mach/nanosleep.c
> index 67caa3ea8a..36fb14598e 100644
> --- a/sysdeps/mach/nanosleep.c
> +++ b/sysdeps/mach/nanosleep.c
> @@ -18,16 +18,26 @@
>  
>  #include <errno.h>
>  #include <mach.h>
> -#include <sys/time.h>
>  #include <time.h>
>  #include <unistd.h>
>  
> +# define timespec_sub(a, b, result)
> 	      \
> +  do {
> 		      \
> +    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;
> 	      \
> +    (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec;
> 	      \
> +    if ((result)->tv_nsec < 0) {
> 	      \
> +      --(result)->tv_sec;
> 	      \
> +      (result)->tv_nsec += 1000000000;
> 		      \
> +    }
> 	      \
> +  } while (0)
> +
>  int
>  __libc_nanosleep (const struct timespec *requested_time,
> -	     struct timespec *remaining)
> +                  struct timespec *remaining)
>  {
>    mach_port_t recv;
> -  struct timeval before, after;
> +  struct timespec before;
> +  error_t err;
>  
>    if (requested_time->tv_sec < 0
>        || requested_time->tv_nsec < 0
> @@ -43,20 +53,20 @@ __libc_nanosleep (const struct timespec
> *requested_time, 
>    recv = __mach_reply_port ();
>  
> -  if (remaining && __gettimeofday (&before, NULL) < 0)
> -    return -1;
> -  error_t err = __mach_msg (NULL,
> MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
> -			    0, 0, recv, ms, MACH_PORT_NULL);
> +  if (remaining != 0)
> +    __clock_gettime (CLOCK_REALTIME, &before);
> +
> +  err = __mach_msg (NULL,
> MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
> +                    0, 0, recv, ms, MACH_PORT_NULL);
>    __mach_port_destroy (mach_task_self (), recv);
>    if (err == EMACH_RCV_INTERRUPTED)
>      {
> -      if (remaining && __gettimeofday (&after, NULL) >= 0)
> +      if (remaining != 0)
>  	{
> -	  struct timeval req_time, elapsed, rem;
> -	  TIMESPEC_TO_TIMEVAL (&req_time, requested_time);
> -	  timersub (&after, &before, &elapsed);
> -	  timersub (&req_time, &elapsed, &rem);
> -	  TIMEVAL_TO_TIMESPEC (&rem, remaining);
> +	  struct timespec after, elapsed;
> +	  __clock_gettime (CLOCK_REALTIME, &after);
> +	  timespec_sub (&after, &before, &elapsed);
> +	  timespec_sub (requested_time, &elapsed, remaining);
>  	}
>  
>        errno = EINTR;
> diff --git a/sysdeps/mach/usleep.c b/sysdeps/mach/usleep.c
> index 3b79857c5d..578540d065 100644
> --- a/sysdeps/mach/usleep.c
> +++ b/sysdeps/mach/usleep.c
> @@ -25,17 +25,12 @@ int
>  usleep (useconds_t useconds)
>  {
>    mach_port_t recv;
> -  struct timeval before, after;
>  
>    recv = __mach_reply_port ();
>  
> -  if (__gettimeofday (&before, NULL) < 0)
> -    return -1;
>    (void) __mach_msg (NULL,
> MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT, 0, 0, recv,
> (useconds + 999) / 1000, MACH_PORT_NULL); __mach_port_destroy
> (mach_task_self (), recv);
> -  if (__gettimeofday (&after, NULL) < 0)
> -    return -1;
>  
>    return 0;
>  }
> diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
> index a248472540..692c336452 100644
> --- a/sysdeps/posix/tempname.c
> +++ b/sysdeps/posix/tempname.c
> @@ -50,7 +50,7 @@
>  #include <string.h>
>  
>  #include <fcntl.h>
> -#include <sys/time.h>
> +#include <time.h>
>  #include <stdint.h>
>  #include <unistd.h>
>  
> @@ -63,7 +63,6 @@
>  # define struct_stat64 struct stat
>  # define __gen_tempname gen_tempname
>  # define __getpid getpid
> -# define __gettimeofday gettimeofday
>  # define __mkdir mkdir
>  # define __open open
>  # define __lxstat64(version, file, buf) lstat (file, buf)
> @@ -76,9 +75,9 @@
>  # else
>  # define RANDOM_BITS(Var) \
>      {
>          \
> -      struct timeval tv;
>          \
> -      __gettimeofday (&tv, NULL);
>          \
> -      (Var) = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
>          \
> +      struct timespec ts;
>          \
> +      clock_gettime (CLOCK_REALTIME, &ts);
>          \
> +      (Var) = ((uint64_t) tv.tv_nsec << 16) ^ tv.tv_sec;
>          \ }
>  #endif
>  
> diff --git a/sysdeps/posix/timespec_get.c
> b/sysdeps/posix/timespec_get.c index 1fc18ac648..e3146da2d3 100644
> --- a/sysdeps/posix/timespec_get.c
> +++ b/sysdeps/posix/timespec_get.c
> @@ -23,16 +23,10 @@
>  int
>  timespec_get (struct timespec *ts, int base)
>  {
> -  switch (base)
> +  if (base == TIME_UTC)
>      {
> -    case TIME_UTC:
> -      if (__clock_gettime (CLOCK_REALTIME, ts) < 0)
> -        return 0;
> -      break;
> -
> -    default:
> -      return 0;
> +      __clock_gettime (CLOCK_REALTIME, ts);
> +      return base;
>      }
> -
> -  return base;
> +  return 0;
>  }
> diff --git a/sysdeps/pthread/aio_misc.c b/sysdeps/pthread/aio_misc.c
> index 6ff0132ecb..65b4b1ade8 100644
> --- a/sysdeps/pthread/aio_misc.c
> +++ b/sysdeps/pthread/aio_misc.c
> @@ -614,13 +614,13 @@ handle_fildes_io (void *arg)
>  	 something to arrive in it. */
>        if (runp == NULL && optim.aio_idle_time >= 0)
>  	{
> -	  struct timeval now;
> +	  struct timespec now;
>  	  struct timespec wakeup_time;
>  
>  	  ++idle_thread_count;
> -	  __gettimeofday (&now, NULL);
> +	  __clock_gettime (CLOCK_REALTIME, &now);
>  	  wakeup_time.tv_sec = now.tv_sec + optim.aio_idle_time;
> -	  wakeup_time.tv_nsec = now.tv_usec * 1000;
> +	  wakeup_time.tv_nsec = now.tv_nsec;
>  	  if (wakeup_time.tv_nsec >= 1000000000)
>  	    {
>  	      wakeup_time.tv_nsec -= 1000000000;
> diff --git a/sysdeps/pthread/aio_suspend.c
> b/sysdeps/pthread/aio_suspend.c index ad654e1d08..bb324a5fe6 100644
> --- a/sysdeps/pthread/aio_suspend.c
> +++ b/sysdeps/pthread/aio_suspend.c
> @@ -183,11 +183,11 @@ aio_suspend (const struct aiocb *const list[],
> int nent, {
>  	  /* We have to convert the relative timeout value into an
>  	     absolute time value with pthread_cond_timedwait
> expects.  */
> -	  struct timeval now;
> +	  struct timespec now;
>  	  struct timespec abstime;
>  
> -	  __gettimeofday (&now, NULL);
> -	  abstime.tv_nsec = timeout->tv_nsec + now.tv_usec * 1000;
> +	  __clock_gettime (CLOCK_REALTIME, &now);
> +	  abstime.tv_nsec = timeout->tv_nsec + now.tv_nsec;
>  	  abstime.tv_sec = timeout->tv_sec + now.tv_sec;
>  	  if (abstime.tv_nsec >= 1000000000)
>  	    {
> diff --git a/sysdeps/unix/make-syscalls.sh
> b/sysdeps/unix/make-syscalls.sh index b49e6b6305..fe24bbc78f 100644
> --- a/sysdeps/unix/make-syscalls.sh
> +++ b/sysdeps/unix/make-syscalls.sh
> @@ -27,7 +27,7 @@
>  # n: scalar buffer length (e.g., 3rd arg to read)
>  # N: pointer to value/return scalar buffer length (e.g., 6th arg to
> recvfrom) # p: non-NULL pointer to typed object (e.g., any non-void*
> arg) -# P: optionally-NULL pointer to typed object (e.g., 2nd
> argument to gettimeofday) +# P: optionally-NULL pointer to typed
> object (e.g., 3rd argument to sigaction) # s: non-NULL string (e.g.,
> 1st arg to open) # S: optionally-NULL string (e.g., 1st arg to acct)
>  # v: vararg scalar (e.g., optional 3rd arg to open)

Reviewed-by: Lukasz Majewski <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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 03/11] Use clock_settime to implement stime; withdraw stime.
  2019-10-25 12:08 ` [PATCH v2 03/11] Use clock_settime to implement stime; withdraw stime Adhemerval Zanella
@ 2019-10-25 13:59   ` Lukasz Majewski
  0 siblings, 0 replies; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-25 13:59 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Zack Weinberg

[-- Attachment #1: Type: text/plain, Size: 5627 bytes --]

On Fri, 25 Oct 2019 09:08:24 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> From: Zack Weinberg <zackw@panix.com>
> 
> Use clock_settime to implement stime; withdraw stime.
> 
> Changes from previous version:
> 
>   - Added a NEWS entry.
> 
> --
> 
> Unconditionally, on all ports, use clock_settime to implement stime,
> not settimeofday or a direct syscall.  Then convert stime into a
> compatibility symbol and remove its prototype from time.h.
> 
> Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
> powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.
> 
> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
>  NEWS                                  |  4 +++
>  sysdeps/unix/stime.c                  | 39
> --------------------------- sysdeps/unix/sysv/linux/syscalls.list |
> 1 - time/stime.c                          | 25 ++++++++---------
>  time/time.h                           |  6 -----
>  5 files changed, 17 insertions(+), 58 deletions(-)
>  delete mode 100644 sysdeps/unix/stime.c
> 
> diff --git a/NEWS b/NEWS
> index d7286841c9..8727b5e7f0 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -30,6 +30,10 @@ Deprecated and removed features, and other changes
> affecting compatibility: Request 25 to TS 18661-1, as applied for
> C2X.  Existing binaries that pass floating-point arguments directly
> will continue to work. 
> +* The obsolete function stime is no longer available to newly linked
> +  binaries and it has been removed from <time.h> header.  This
> function
> +  has been deprecated in favor of clock_settime.
> +
>  Changes to build and runtime requirements:
>  
>    [Add changes to build and runtime requirements here]
> diff --git a/sysdeps/unix/stime.c b/sysdeps/unix/stime.c
> deleted file mode 100644
> index b40c33454a..0000000000
> --- a/sysdeps/unix/stime.c
> +++ /dev/null
> @@ -1,39 +0,0 @@
> -/* Copyright (C) 1992-2019 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be
> useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <stddef.h>		/* For NULL.  */
> -#include <sys/time.h>
> -#include <time.h>
> -
> -/* Set the system clock to *WHEN.  */
> -
> -int
> -stime (const time_t *when)
> -{
> -  struct timeval tv;
> -
> -  if (when == NULL)
> -    {
> -      __set_errno (EINVAL);
> -      return -1;
> -    }
> -
> -  tv.tv_sec = *when;
> -  tv.tv_usec = 0;
> -  return __settimeofday (&tv, (struct timezone *) 0);
> -}
> diff --git a/sysdeps/unix/sysv/linux/syscalls.list
> b/sysdeps/unix/sysv/linux/syscalls.list index cdcf6c127b..70b110979b
> 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/syscalls.list
> @@ -61,7 +61,6 @@ setfsgid	EXTRA	setfsgid
> i:i	setfsgid setfsuid	EXTRA	setfsuid
> i:i	setfsuid setpgid		-	setpgid
> 	i:ii	__setpgid	setpgid sigaltstack
> -	sigaltstack	i:PP	__sigaltstack
> sigaltstack -stime		-	stime
> i:p	stime sysinfo		EXTRA	sysinfo
> 	i:p	__sysinfo	sysinfo swapon
> -	swapon		i:si	__swapon	swapon
> swapoff		-	swapoff		i:s
> __swapoff	swapoff diff --git a/time/stime.c b/time/stime.c
> index a53c0e86ae..6ea3b6dcc1 100644 --- a/time/stime.c +++
> b/time/stime.c @@ -15,23 +15,24 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#include <errno.h>
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_31)
> +
>  #include <time.h>
> -#include <stddef.h>
>  
>  /* Set the system clock to *WHEN.  */
>  
>  int
> -stime (const time_t *when)
> +attribute_compat_text_section
> +__stime (const time_t *when)
>  {
> -  if (when == NULL)
> -    {
> -      __set_errno (EINVAL);
> -      return -1;
> -    }
> -
> -  __set_errno (ENOSYS);
> -  return -1;
> +  struct timespec ts;
> +  ts.tv_sec = *when;
> +  ts.tv_nsec = 0;
> +
> +  return __clock_settime (CLOCK_REALTIME, &ts);
>  }
>  
> -stub_warning (stime)
> +compat_symbol (libc, __stime, stime, GLIBC_2_0);
> +#endif
> diff --git a/time/time.h b/time/time.h
> index 72a1078d2c..7daaacce16 100644
> --- a/time/time.h
> +++ b/time/time.h
> @@ -175,12 +175,6 @@ extern int daylight;
>  extern long int timezone;
>  #endif
>  
> -#ifdef __USE_MISC
> -/* Set the system time to *WHEN.
> -   This call is restricted to the superuser.  */
> -extern int stime (const time_t *__when) __THROW;
> -#endif
> -
>  
>  /* Nonzero if YEAR is a leap year (every 4 years,
>     except every 100th isn't, and every 400th is).  */

Reviewed-by: Lukasz Majewski <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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 04/11] Use clock_settime to implement settimeofday.
  2019-10-25 12:09 ` [PATCH v2 04/11] Use clock_settime to implement settimeofday Adhemerval Zanella
@ 2019-10-25 15:28   ` Lukasz Majewski
  2019-10-28 18:28     ` Adhemerval Zanella
  2019-10-25 20:42   ` Alistair Francis
  2019-10-25 23:34   ` Rafal Luzynski
  2 siblings, 1 reply; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-25 15:28 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Zack Weinberg

[-- Attachment #1: Type: text/plain, Size: 17861 bytes --]

On Fri, 25 Oct 2019 09:08:25 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> From: Zack Weinberg <zackw@panix.com>
> 
> Use clock_settime to implement settimeofday.
> 
> Changes from previous version:
> 
>   - Added a NEWS entry.
> 
> --
> 
> Unconditionally, on all ports, use clock_settime to implement
> settimeofday.  Remove sysdeps/unix/clock_settime.c, which implemented
> clock_settime by calling settimeofday; new OS ports must henceforth
> provide a real implementation of clock_settime.
> 
> Hurd had a real implementation of settimeofday but not of
> clock_settime; this patch converts it into an implementation of
> clock_settime.  It only supports CLOCK_REALTIME and microsecond
> resolution; Hurd/Mach does not appear to have any support for
> finer-resolution clocks.
> 
> The vestigial "set time zone" feature of settimeofday complicates the
> generic settimeofday implementation a little.  The only remaining uses
> of this feature that aren't just bugs, are using it to inform the
> Linux kernel of the offset between the hardware clock and UTC, on
> systems where the hardware clock doesn't run in UTC (usually because
> of dual-booting with Windows).  There currently isn't any other way to
> do this.  However, the callers that do this call settimeofday with
> _only_ the timezone argument non-NULL.  Therefore, glibc's new
> behavior is: callers of settimeofday must supply one and only one of
> the two arguments.  If both arguments are non-NULL, or both arguments
> are NULL, the call fails and sets errno to EINVAL.
> 
> When only the timeval argument is supplied, settimeofday calls
> __clock_settime(CLOCK_REALTIME), same as stime.
> 
> When only the timezone argument is supplied, settimeofday calls a new
> internal function called __settimezone.  On Linux, only, this function
> will pass the timezone structure to the settimeofday system call.  On
> all other operating systems, and on Linux architectures that don't
> define __NR_settimeofday, __settimezone is a stub that always sets
> errno to ENOSYS and returns -1.
> 
> The settimeoday syscall is enabled on Linux by the flag
> COMPAT_32BIT_TIME, which is an option to either 32-bits ABIs or COMPAT
> builds (defined usually by 64-bit kernels that want to support 32-bit
>  ABIs, such as x86).  The idea to future 64-bit time_t only ABIs
> is to not provide settimeofday syscall.
> 
> The same semantics are implemented for Linux/Alpha's GLIBC_2.0 compat
> symbol for settimeofday.
> 
> There are no longer any internal callers of __settimeofday, so the
> internal prototype is removed.
> 
> Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
> powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.
> 
> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
>  NEWS                                          | 24 +++++++++
>  include/sys/time.h                            |  3 +-
>  sysdeps/{unix => mach/hurd}/clock_settime.c   | 51
> ++++++++----------- sysdeps/unix/syscalls.list                    |
> 1 - .../unix/sysv/linux/alpha/osf_settimeofday.c  | 16 ++++--
>  sysdeps/unix/sysv/linux/alpha/settimeofday.c  | 22 ++++++++
>  sysdeps/unix/sysv/linux/alpha/syscalls.list   |  1 -
>  sysdeps/unix/sysv/linux/settimezone.c         | 36 +++++++++++++
>  time/Makefile                                 |  8 +--
>  time/settimeofday.c                           | 24 +++++++--
>  .../hurd/settimeofday.c => time/settimezone.c | 34 ++-----------
>  11 files changed, 147 insertions(+), 73 deletions(-)
>  rename sysdeps/{unix => mach/hurd}/clock_settime.c (65%)
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/settimeofday.c
>  create mode 100644 sysdeps/unix/sysv/linux/settimezone.c
>  rename sysdeps/mach/hurd/settimeofday.c => time/settimezone.c (52%)
> 
> diff --git a/NEWS b/NEWS
> index 8727b5e7f0..0b1476e745 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -34,6 +34,30 @@ Deprecated and removed features, and other changes
> affecting compatibility: binaries and it has been removed from
> <time.h> header.  This function has been deprecated in favor of
> clock_settime. 
> +* The settimeofday function can still be used to set a system-wide
> time
> +  zone when the operating system supports it.  This is because the
> Linux
> +  kernel reused the API, on some architectures, to describe a
> system-wide
> +  time-zone-like offset between the software clock maintained by the
> kernel,
> +  and the “RTC” clock that keeps time when the system is shut down.
> +
> +  However, to reduce the odds of this offset being set by accident,
> +  settimeofday can no longer be used to set the time and the offset
> +  simultaneously.  If both of its two arguments are non-null, the
> call
> +  will fail (setting errno to EINVAL).
> +
> +  Callers attempting to set this offset should also be prepared for
> the call
> +  to fail and set errno to ENOSYS; this already happens on the Hurd
> and on
> +  some Linux architectures.  The Linux kernel maintainers are
> discussing a
> +  more principled replacement for the reused API.  After a
> replacement
> +  becomes available, we will change settimeofday to fail with ENOSYS
> on all
> +  platforms when its ‘tzp’ argument is not a null pointer.
> +
> +  Note that settimeofday itself is obsolescent according to POSIX.
> +  Programs that set the system time should use clock_settime and/or
> +  the adjtime family of functions instead.  We may also cease to make
> +  settimeofday available to newly linked binaries after there is a
> +  replacement for Linux’s time-zone-like offset API.
> +
>  Changes to build and runtime requirements:
>  
>    [Add changes to build and runtime requirements here]
> diff --git a/include/sys/time.h b/include/sys/time.h
> index 57208afa82..c0e30e70fb 100644
> --- a/include/sys/time.h
> +++ b/include/sys/time.h
> @@ -24,8 +24,7 @@ extern int __gettimeofday (struct timeval *__tv,
>  			   struct timezone *__tz);
>  libc_hidden_proto (__gettimeofday)
>  libc_hidden_proto (gettimeofday)
> -extern int __settimeofday (const struct timeval *__tv,
> -			   const struct timezone *__tz)
> +extern int __settimezone (const struct timezone *__tz)
>  	attribute_hidden;
>  extern int __adjtime (const struct timeval *__delta,
>  		      struct timeval *__olddelta);
> diff --git a/sysdeps/unix/clock_settime.c
> b/sysdeps/mach/hurd/clock_settime.c similarity index 65%
> rename from sysdeps/unix/clock_settime.c
> rename to sysdeps/mach/hurd/clock_settime.c
> index 18d7c99864..02239c097a 100644
> --- a/sysdeps/unix/clock_settime.c
> +++ b/sysdeps/mach/hurd/clock_settime.c
> @@ -1,4 +1,4 @@
> -/* Copyright (C) 1999-2019 Free Software Foundation, Inc.
> +/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>  
>     The GNU C Library is free software; you can redistribute it and/or
> @@ -17,38 +17,31 @@
>  
>  #include <errno.h>
>  #include <time.h>
> -#include <sys/time.h>
> +#include <hurd.h>
> +#include <hurd/port.h>
>  #include <shlib-compat.h>
>  
> -/* Set CLOCK to value TP.  */
> +/* Set the current time of day.
> +   This call is restricted to the super-user.  */
>  int
> -__clock_settime (clockid_t clock_id, const struct timespec *tp)
> +__clock_settime (clockid_t clock_id, const struct timespec *ts)
>  {
> -  int retval = -1;
> -
> -  /* Make sure the time cvalue is OK.  */
> -  if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000)
> -    {
> -      __set_errno (EINVAL);
> -      return -1;
> -    }
> -
> -  switch (clock_id)
> -    {
> -    case CLOCK_REALTIME:
> -      {
> -	struct timeval tv;
> -	TIMESPEC_TO_TIMEVAL (&tv, tp);
> -	retval = __settimeofday (&tv, NULL);
> -      }
> -      break;
> -
> -    default:
> -      __set_errno (EINVAL);
> -      break;
> -    }
> -
> -  return retval;
> +  error_t err;
> +  mach_port_t hostpriv;
> +  time_value_t tv;
> +
> +  if (clock_id != CLOCK_REALTIME)
> +    return __hurd_fail (EINVAL);
> +
> +  err = __get_privileged_ports (&hostpriv, NULL);
> +  if (err)
> +    return __hurd_fail (EPERM);
> +
> +  TIMESPEC_TO_TIME_VALUE (&tv, ts);
> +  err = __host_set_time (hostpriv, tv);
> +  __mach_port_deallocate (__mach_task_self (), hostpriv);
> +
> +  return __hurd_fail (err);
>  }
>  libc_hidden_def (__clock_settime)
>  
> diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list
> index 61e5360b4d..5fedd5733d 100644
> --- a/sysdeps/unix/syscalls.list
> +++ b/sysdeps/unix/syscalls.list
> @@ -76,7 +76,6 @@ setreuid	-	setreuid
> i:ii	__setreuid	setreuid setrlimit	-
> setrlimit	i:ip	__setrlimit setrlimit setsid
> 	-	setsid		i:	__setsid
> setsid setsockopt	-	setsockopt	i:iiibn
> setsockopt	__setsockopt -settimeofday	-
> settimeofday	i:PP	__settimeofday	settimeofday
> setuid		-	setuid		i:i
> __setuid	setuid shutdown	-	shutdown
> i:ii	shutdown sigaction	-	sigaction
> i:ipp	__sigaction	sigaction diff --git
> a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
> b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c index
> fb2a36df19..914f5ac57b 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c +++
> b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c @@ -32,9 +32,19 @@
> attribute_compat_text_section __settimeofday_tv32 (const struct
> timeval32 *tv32, const struct timezone *tz) {
> -  struct timeval tv;
> -  tv32_to_tv64 (&tv, tv32);
> -  return __settimeofday (&tv, tz);
> +  if (__glibc_unlikely (tz != 0))
> +    {
> +      if (tv32 != 0)
> +	{
> +	  __set_errno (EINVAL);
> +	  return -1;
> +	}
> +      return __settimezone (tz);
> +    }
> +
> +  struct timespec ts;
> +  tv32_to_ts64 (&ts, tv32);

This can be replaced with valid_timeval_to_timespec64() from
include/time.h

> +  return __clock_settime (CLOCK_REALTIME, &ts);
>  }
>  
>  compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0);
> diff --git a/sysdeps/unix/sysv/linux/alpha/settimeofday.c
> b/sysdeps/unix/sysv/linux/alpha/settimeofday.c new file mode 100644
> index 0000000000..36a6901e4e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/settimeofday.c
> @@ -0,0 +1,22 @@
> +/* settimeofday -- Set the current time of day.  Linux/Alpha/tv64
> version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* We can use the generic implementation, but we have to override its
> +   default symbol version.  */
> +#define VERSION_settimeofday GLIBC_2.1
> +#include <time/settimeofday.c>
> diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list
> b/sysdeps/unix/sysv/linux/alpha/syscalls.list index
> c786aa751e..95a27e18e8 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/syscalls.list +++
> b/sysdeps/unix/sysv/linux/alpha/syscalls.list @@ -24,7 +24,6 @@
> pciconfig_iobase EXTRA	pciconfig_iobase 3
> __pciconfig_iobase pciconfig_iobase # timeval64 entry points (see
> osf_*.c for GLIBC_2.0 timeval32 equivalents) gettimeofday
> -	gettimeofday	i:pP	__GI___gettimeofday
> gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
> -settimeofday	-	settimeofday	i:PP
> __settimeofday	settimeofday@@GLIBC_2.1 getitimer
> -	getitimer	i:ip	__getitimer
> getitimer@@GLIBC_2.1 setitimer	-	setitimer
> i:ipP	__setitimer	setitimer@@GLIBC_2.1 utimes
> 	-	utimes		i:sp	__utimes
> utimes@@GLIBC_2.1 diff --git a/sysdeps/unix/sysv/linux/settimezone.c
> b/sysdeps/unix/sysv/linux/settimezone.c new file mode 100644 index
> 0000000000..90b38307c6 --- /dev/null +++
> b/sysdeps/unix/sysv/linux/settimezone.c @@ -0,0 +1,36 @@ +/* Obsolete
> set system time.  Linux version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +#include <sys/time.h>
> +#include <sysdep.h>
> +
> +/* Set the system-wide timezone.
> +   This call is restricted to the super-user.
> +   This operation is considered obsolete, kernel support may not be
> +   available on all architectures.  */
> +int
> +__settimezone (const struct timezone *tz)
> +{
> +#ifdef __NR_settimeofday
> +  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
> +#else
> +  __set_errno (ENOSYS);
> +  return -1
> +#endif
> +}
> diff --git a/time/Makefile b/time/Makefile
> index ad8844ea34..6de4e418d9 100644
> --- a/time/Makefile
> +++ b/time/Makefile
> @@ -31,13 +31,13 @@ headers := time.h sys/time.h sys/timeb.h
> bits/time.h			\ 
>  routines := offtime asctime clock ctime ctime_r difftime \
>  	    gmtime localtime mktime time		 \
> -	    gettimeofday settimeofday adjtime tzset	 \
> -	    tzfile getitimer setitimer			 \
> +	    gettimeofday settimeofday settimezone	 \
> +	    adjtime tzset tzfile getitimer setitimer	 \
>  	    stime dysize timegm ftime			 \
>  	    getdate strptime strptime_l			 \
>  	    strftime wcsftime strftime_l wcsftime_l	 \
> -	    timespec_get 	 			 \
> -	    clock_getcpuclockid clock_getres 		 \
> +	    timespec_get				 \
> +	    clock_getcpuclockid clock_getres		 \
>  	    clock_gettime clock_settime clock_nanosleep
>  
>  aux :=	    era alt_digit lc-time-cleanup
> diff --git a/time/settimeofday.c b/time/settimeofday.c
> index 6aa4832d65..ad57ad41a1 100644
> --- a/time/settimeofday.c
> +++ b/time/settimeofday.c
> @@ -16,6 +16,7 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #include <errno.h>
> +#include <time.h>
>  #include <sys/time.h>
>  
>  /* Set the current time of day and timezone information.
> @@ -23,9 +24,24 @@
>  int
>  __settimeofday (const struct timeval *tv, const struct timezone *tz)
>  {
> -  __set_errno (ENOSYS);
> -  return -1;
> +  if (__glibc_unlikely (tz != 0))
> +    {
> +      if (tv != 0)
> +	{
> +	  __set_errno (EINVAL);
> +	  return -1;
> +	}
> +      return __settimezone (tz);
> +    }
> +
> +  struct timespec ts;
> +  TIMEVAL_TO_TIMESPEC (tv, &ts);
> +  return __clock_settime (CLOCK_REALTIME, &ts);
>  }
> -stub_warning (settimeofday)
>  
> -weak_alias (__settimeofday, settimeofday)
> +#ifdef VERSION_settimeofday
> +weak_alias (__settimeofday, __settimeofday_w);
> +default_symbol_version (__settimeofday_w, settimeofday,
> VERSION_settimeofday); +#else
> +weak_alias (__settimeofday, settimeofday);
> +#endif
> diff --git a/sysdeps/mach/hurd/settimeofday.c b/time/settimezone.c
> similarity index 52%
> rename from sysdeps/mach/hurd/settimeofday.c
> rename to time/settimezone.c
> index 31bffcad9d..b9969c9dd5 100644
> --- a/sysdeps/mach/hurd/settimeofday.c
> +++ b/time/settimezone.c
> @@ -1,4 +1,4 @@
> -/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
> +/* Copyright (C) 2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>  
>     The GNU C Library is free software; you can redistribute it and/or
> @@ -17,36 +17,12 @@
>  
>  #include <errno.h>
>  #include <sys/time.h>
> -#include <hurd.h>
> -#include <hurd/port.h>
>  
> -/* Set the current time of day and timezone information.
> +/* Set the system-wide timezone.
>     This call is restricted to the super-user.  */
>  int
> -__settimeofday (const struct timeval *tv, const struct timezone *tz)
> +__settimezone (const struct timezone *tz)
>  {
> -  error_t err;
> -  mach_port_t hostpriv;
> -
> -  if (tz != NULL)
> -    {
> -      errno = ENOSYS;
> -      return -1;
> -    }
> -
> -  err = __get_privileged_ports (&hostpriv, NULL);
> -  if (err)
> -    return __hurd_fail (EPERM);
> -
> -  /* `time_value_t' and `struct timeval' are in fact identical with
> the
> -     names changed.  */
> -  err = __host_set_time (hostpriv, *(time_value_t *) tv);
> -  __mach_port_deallocate (__mach_task_self (), hostpriv);
> -
> -  if (err)
> -    return __hurd_fail (err);
> -
> -  return 0;
> +  __set_errno (ENOSYS);
> +  return -1;
>  }
> -
> -weak_alias (__settimeofday, settimeofday)

Reviewed-by: Lukasz Majewski <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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 04/11] Use clock_settime to implement settimeofday.
  2019-10-25 12:09 ` [PATCH v2 04/11] Use clock_settime to implement settimeofday Adhemerval Zanella
  2019-10-25 15:28   ` Lukasz Majewski
@ 2019-10-25 20:42   ` Alistair Francis
  2019-10-28 18:29     ` Adhemerval Zanella
  2019-10-25 23:34   ` Rafal Luzynski
  2 siblings, 1 reply; 34+ messages in thread
From: Alistair Francis @ 2019-10-25 20:42 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library, Lukasz Majewski, Zack Weinberg

On Fri, Oct 25, 2019 at 5:09 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> From: Zack Weinberg <zackw@panix.com>
>
> Use clock_settime to implement settimeofday.
>
> Changes from previous version:
>
>   - Added a NEWS entry.
>
> --
>
> Unconditionally, on all ports, use clock_settime to implement
> settimeofday.  Remove sysdeps/unix/clock_settime.c, which implemented
> clock_settime by calling settimeofday; new OS ports must henceforth
> provide a real implementation of clock_settime.
>
> Hurd had a real implementation of settimeofday but not of
> clock_settime; this patch converts it into an implementation of
> clock_settime.  It only supports CLOCK_REALTIME and microsecond
> resolution; Hurd/Mach does not appear to have any support for
> finer-resolution clocks.
>
> The vestigial "set time zone" feature of settimeofday complicates the
> generic settimeofday implementation a little.  The only remaining uses
> of this feature that aren't just bugs, are using it to inform the
> Linux kernel of the offset between the hardware clock and UTC, on
> systems where the hardware clock doesn't run in UTC (usually because
> of dual-booting with Windows).  There currently isn't any other way to
> do this.  However, the callers that do this call settimeofday with
> _only_ the timezone argument non-NULL.  Therefore, glibc's new
> behavior is: callers of settimeofday must supply one and only one of
> the two arguments.  If both arguments are non-NULL, or both arguments
> are NULL, the call fails and sets errno to EINVAL.
>
> When only the timeval argument is supplied, settimeofday calls
> __clock_settime(CLOCK_REALTIME), same as stime.
>
> When only the timezone argument is supplied, settimeofday calls a new
> internal function called __settimezone.  On Linux, only, this function
> will pass the timezone structure to the settimeofday system call.  On
> all other operating systems, and on Linux architectures that don't
> define __NR_settimeofday, __settimezone is a stub that always sets
> errno to ENOSYS and returns -1.
>
> The settimeoday syscall is enabled on Linux by the flag
> COMPAT_32BIT_TIME, which is an option to either 32-bits ABIs or COMPAT
> builds (defined usually by 64-bit kernels that want to support 32-bit
>  ABIs, such as x86).  The idea to future 64-bit time_t only ABIs
> is to not provide settimeofday syscall.
>
> The same semantics are implemented for Linux/Alpha's GLIBC_2.0 compat
> symbol for settimeofday.
>
> There are no longer any internal callers of __settimeofday, so the
> internal prototype is removed.
>
> Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
> powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.
>
> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
>  NEWS                                          | 24 +++++++++
>  include/sys/time.h                            |  3 +-
>  sysdeps/{unix => mach/hurd}/clock_settime.c   | 51 ++++++++-----------
>  sysdeps/unix/syscalls.list                    |  1 -
>  .../unix/sysv/linux/alpha/osf_settimeofday.c  | 16 ++++--
>  sysdeps/unix/sysv/linux/alpha/settimeofday.c  | 22 ++++++++
>  sysdeps/unix/sysv/linux/alpha/syscalls.list   |  1 -
>  sysdeps/unix/sysv/linux/settimezone.c         | 36 +++++++++++++
>  time/Makefile                                 |  8 +--
>  time/settimeofday.c                           | 24 +++++++--
>  .../hurd/settimeofday.c => time/settimezone.c | 34 ++-----------
>  11 files changed, 147 insertions(+), 73 deletions(-)
>  rename sysdeps/{unix => mach/hurd}/clock_settime.c (65%)
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/settimeofday.c
>  create mode 100644 sysdeps/unix/sysv/linux/settimezone.c
>  rename sysdeps/mach/hurd/settimeofday.c => time/settimezone.c (52%)
>
> diff --git a/NEWS b/NEWS
> index 8727b5e7f0..0b1476e745 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -34,6 +34,30 @@ Deprecated and removed features, and other changes affecting compatibility:
>    binaries and it has been removed from <time.h> header.  This function
>    has been deprecated in favor of clock_settime.
>
> +* The settimeofday function can still be used to set a system-wide time
> +  zone when the operating system supports it.  This is because the Linux
> +  kernel reused the API, on some architectures, to describe a system-wide
> +  time-zone-like offset between the software clock maintained by the kernel,
> +  and the “RTC” clock that keeps time when the system is shut down.
> +
> +  However, to reduce the odds of this offset being set by accident,
> +  settimeofday can no longer be used to set the time and the offset
> +  simultaneously.  If both of its two arguments are non-null, the call
> +  will fail (setting errno to EINVAL).
> +
> +  Callers attempting to set this offset should also be prepared for the call
> +  to fail and set errno to ENOSYS; this already happens on the Hurd and on
> +  some Linux architectures.  The Linux kernel maintainers are discussing a
> +  more principled replacement for the reused API.  After a replacement
> +  becomes available, we will change settimeofday to fail with ENOSYS on all
> +  platforms when its ‘tzp’ argument is not a null pointer.
> +
> +  Note that settimeofday itself is obsolescent according to POSIX.
> +  Programs that set the system time should use clock_settime and/or
> +  the adjtime family of functions instead.  We may also cease to make
> +  settimeofday available to newly linked binaries after there is a
> +  replacement for Linux’s time-zone-like offset API.
> +
>  Changes to build and runtime requirements:
>
>    [Add changes to build and runtime requirements here]
> diff --git a/include/sys/time.h b/include/sys/time.h
> index 57208afa82..c0e30e70fb 100644
> --- a/include/sys/time.h
> +++ b/include/sys/time.h
> @@ -24,8 +24,7 @@ extern int __gettimeofday (struct timeval *__tv,
>                            struct timezone *__tz);
>  libc_hidden_proto (__gettimeofday)
>  libc_hidden_proto (gettimeofday)
> -extern int __settimeofday (const struct timeval *__tv,
> -                          const struct timezone *__tz)
> +extern int __settimezone (const struct timezone *__tz)
>         attribute_hidden;
>  extern int __adjtime (const struct timeval *__delta,
>                       struct timeval *__olddelta);
> diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/mach/hurd/clock_settime.c
> similarity index 65%
> rename from sysdeps/unix/clock_settime.c
> rename to sysdeps/mach/hurd/clock_settime.c
> index 18d7c99864..02239c097a 100644
> --- a/sysdeps/unix/clock_settime.c
> +++ b/sysdeps/mach/hurd/clock_settime.c
> @@ -1,4 +1,4 @@
> -/* Copyright (C) 1999-2019 Free Software Foundation, Inc.
> +/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>
>     The GNU C Library is free software; you can redistribute it and/or
> @@ -17,38 +17,31 @@
>
>  #include <errno.h>
>  #include <time.h>
> -#include <sys/time.h>
> +#include <hurd.h>
> +#include <hurd/port.h>
>  #include <shlib-compat.h>
>
> -/* Set CLOCK to value TP.  */
> +/* Set the current time of day.
> +   This call is restricted to the super-user.  */
>  int
> -__clock_settime (clockid_t clock_id, const struct timespec *tp)
> +__clock_settime (clockid_t clock_id, const struct timespec *ts)
>  {
> -  int retval = -1;
> -
> -  /* Make sure the time cvalue is OK.  */
> -  if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000)
> -    {
> -      __set_errno (EINVAL);
> -      return -1;
> -    }
> -
> -  switch (clock_id)
> -    {
> -    case CLOCK_REALTIME:
> -      {
> -       struct timeval tv;
> -       TIMESPEC_TO_TIMEVAL (&tv, tp);
> -       retval = __settimeofday (&tv, NULL);
> -      }
> -      break;
> -
> -    default:
> -      __set_errno (EINVAL);
> -      break;
> -    }
> -
> -  return retval;
> +  error_t err;
> +  mach_port_t hostpriv;
> +  time_value_t tv;
> +
> +  if (clock_id != CLOCK_REALTIME)
> +    return __hurd_fail (EINVAL);
> +
> +  err = __get_privileged_ports (&hostpriv, NULL);
> +  if (err)
> +    return __hurd_fail (EPERM);
> +
> +  TIMESPEC_TO_TIME_VALUE (&tv, ts);
> +  err = __host_set_time (hostpriv, tv);
> +  __mach_port_deallocate (__mach_task_self (), hostpriv);
> +
> +  return __hurd_fail (err);
>  }
>  libc_hidden_def (__clock_settime)
>
> diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list
> index 61e5360b4d..5fedd5733d 100644
> --- a/sysdeps/unix/syscalls.list
> +++ b/sysdeps/unix/syscalls.list
> @@ -76,7 +76,6 @@ setreuid      -       setreuid        i:ii    __setreuid      setreuid
>  setrlimit      -       setrlimit       i:ip    __setrlimit setrlimit
>  setsid         -       setsid          i:      __setsid        setsid
>  setsockopt     -       setsockopt      i:iiibn setsockopt      __setsockopt
> -settimeofday   -       settimeofday    i:PP    __settimeofday  settimeofday
>  setuid         -       setuid          i:i     __setuid        setuid
>  shutdown       -       shutdown        i:ii    shutdown
>  sigaction      -       sigaction       i:ipp   __sigaction     sigaction
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
> index fb2a36df19..914f5ac57b 100644
> --- a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
> @@ -32,9 +32,19 @@ attribute_compat_text_section
>  __settimeofday_tv32 (const struct timeval32 *tv32,
>                       const struct timezone *tz)
>  {
> -  struct timeval tv;
> -  tv32_to_tv64 (&tv, tv32);
> -  return __settimeofday (&tv, tz);
> +  if (__glibc_unlikely (tz != 0))
> +    {
> +      if (tv32 != 0)
> +       {
> +         __set_errno (EINVAL);
> +         return -1;
> +       }
> +      return __settimezone (tz);
> +    }
> +
> +  struct timespec ts;
> +  tv32_to_ts64 (&ts, tv32);
> +  return __clock_settime (CLOCK_REALTIME, &ts);
>  }
>
>  compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0);
> diff --git a/sysdeps/unix/sysv/linux/alpha/settimeofday.c b/sysdeps/unix/sysv/linux/alpha/settimeofday.c
> new file mode 100644
> index 0000000000..36a6901e4e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/settimeofday.c
> @@ -0,0 +1,22 @@
> +/* settimeofday -- Set the current time of day.  Linux/Alpha/tv64 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* We can use the generic implementation, but we have to override its
> +   default symbol version.  */
> +#define VERSION_settimeofday GLIBC_2.1
> +#include <time/settimeofday.c>
> diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list
> index c786aa751e..95a27e18e8 100644
> --- a/sysdeps/unix/sysv/linux/alpha/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list
> @@ -24,7 +24,6 @@ pciconfig_iobase EXTRA        pciconfig_iobase 3      __pciconfig_iobase pciconfig_iobase
>
>  # timeval64 entry points (see osf_*.c for GLIBC_2.0 timeval32 equivalents)
>  gettimeofday   -       gettimeofday    i:pP    __GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
> -settimeofday   -       settimeofday    i:PP    __settimeofday  settimeofday@@GLIBC_2.1
>  getitimer      -       getitimer       i:ip    __getitimer     getitimer@@GLIBC_2.1
>  setitimer      -       setitimer       i:ipP   __setitimer     setitimer@@GLIBC_2.1
>  utimes         -       utimes          i:sp    __utimes        utimes@@GLIBC_2.1
> diff --git a/sysdeps/unix/sysv/linux/settimezone.c b/sysdeps/unix/sysv/linux/settimezone.c
> new file mode 100644
> index 0000000000..90b38307c6
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/settimezone.c
> @@ -0,0 +1,36 @@
> +/* Obsolete set system time.  Linux version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +#include <sys/time.h>
> +#include <sysdep.h>
> +
> +/* Set the system-wide timezone.
> +   This call is restricted to the super-user.
> +   This operation is considered obsolete, kernel support may not be
> +   available on all architectures.  */
> +int
> +__settimezone (const struct timezone *tz)
> +{
> +#ifdef __NR_settimeofday
> +  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
> +#else
> +  __set_errno (ENOSYS);
> +  return -1

You are missing a semi-colon here.

Alistair

> +#endif
> +}
> diff --git a/time/Makefile b/time/Makefile
> index ad8844ea34..6de4e418d9 100644
> --- a/time/Makefile
> +++ b/time/Makefile
> @@ -31,13 +31,13 @@ headers := time.h sys/time.h sys/timeb.h bits/time.h                        \
>
>  routines := offtime asctime clock ctime ctime_r difftime \
>             gmtime localtime mktime time                 \
> -           gettimeofday settimeofday adjtime tzset      \
> -           tzfile getitimer setitimer                   \
> +           gettimeofday settimeofday settimezone        \
> +           adjtime tzset tzfile getitimer setitimer     \
>             stime dysize timegm ftime                    \
>             getdate strptime strptime_l                  \
>             strftime wcsftime strftime_l wcsftime_l      \
> -           timespec_get                                 \
> -           clock_getcpuclockid clock_getres             \
> +           timespec_get                                 \
> +           clock_getcpuclockid clock_getres             \
>             clock_gettime clock_settime clock_nanosleep
>
>  aux :=     era alt_digit lc-time-cleanup
> diff --git a/time/settimeofday.c b/time/settimeofday.c
> index 6aa4832d65..ad57ad41a1 100644
> --- a/time/settimeofday.c
> +++ b/time/settimeofday.c
> @@ -16,6 +16,7 @@
>     <https://www.gnu.org/licenses/>.  */
>
>  #include <errno.h>
> +#include <time.h>
>  #include <sys/time.h>
>
>  /* Set the current time of day and timezone information.
> @@ -23,9 +24,24 @@
>  int
>  __settimeofday (const struct timeval *tv, const struct timezone *tz)
>  {
> -  __set_errno (ENOSYS);
> -  return -1;
> +  if (__glibc_unlikely (tz != 0))
> +    {
> +      if (tv != 0)
> +       {
> +         __set_errno (EINVAL);
> +         return -1;
> +       }
> +      return __settimezone (tz);
> +    }
> +
> +  struct timespec ts;
> +  TIMEVAL_TO_TIMESPEC (tv, &ts);
> +  return __clock_settime (CLOCK_REALTIME, &ts);
>  }
> -stub_warning (settimeofday)
>
> -weak_alias (__settimeofday, settimeofday)
> +#ifdef VERSION_settimeofday
> +weak_alias (__settimeofday, __settimeofday_w);
> +default_symbol_version (__settimeofday_w, settimeofday, VERSION_settimeofday);
> +#else
> +weak_alias (__settimeofday, settimeofday);
> +#endif
> diff --git a/sysdeps/mach/hurd/settimeofday.c b/time/settimezone.c
> similarity index 52%
> rename from sysdeps/mach/hurd/settimeofday.c
> rename to time/settimezone.c
> index 31bffcad9d..b9969c9dd5 100644
> --- a/sysdeps/mach/hurd/settimeofday.c
> +++ b/time/settimezone.c
> @@ -1,4 +1,4 @@
> -/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
> +/* Copyright (C) 2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>
>     The GNU C Library is free software; you can redistribute it and/or
> @@ -17,36 +17,12 @@
>
>  #include <errno.h>
>  #include <sys/time.h>
> -#include <hurd.h>
> -#include <hurd/port.h>
>
> -/* Set the current time of day and timezone information.
> +/* Set the system-wide timezone.
>     This call is restricted to the super-user.  */
>  int
> -__settimeofday (const struct timeval *tv, const struct timezone *tz)
> +__settimezone (const struct timezone *tz)
>  {
> -  error_t err;
> -  mach_port_t hostpriv;
> -
> -  if (tz != NULL)
> -    {
> -      errno = ENOSYS;
> -      return -1;
> -    }
> -
> -  err = __get_privileged_ports (&hostpriv, NULL);
> -  if (err)
> -    return __hurd_fail (EPERM);
> -
> -  /* `time_value_t' and `struct timeval' are in fact identical with the
> -     names changed.  */
> -  err = __host_set_time (hostpriv, *(time_value_t *) tv);
> -  __mach_port_deallocate (__mach_task_self (), hostpriv);
> -
> -  if (err)
> -    return __hurd_fail (err);
> -
> -  return 0;
> +  __set_errno (ENOSYS);
> +  return -1;
>  }
> -
> -weak_alias (__settimeofday, settimeofday)
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 05/11] Use clock_gettime to implement time.
  2019-10-25 12:09 ` [PATCH v2 05/11] Use clock_gettime to implement time Adhemerval Zanella
@ 2019-10-25 20:59   ` Lukasz Majewski
  0 siblings, 0 replies; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-25 20:59 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 5773 bytes --]

On Fri, 25 Oct 2019 09:08:26 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> Use clock_gettime to implement time.
> 
> Changes from previous version:
> 
>   - Do not remove Linux arch-specific implementations.
> 
>   - Use CLOCK_REALTIME_COARSE for Linux.
> 
> --
> 
> Change the default implementation of time to call clock_gettime,
> to align with new Linux ports that are expected to only implement
> __NR_clock_gettime.  Arch-specific implementation that either call
> the time vDSO or route to gettimeofday vDSO are not removed.
> 
> Also for Linux, CLOCK_REALTIME_COARSE is used instead of generic
> CLOCK_REALTIME clockid.  This takes less CPU time and its behavior
> better matches what the current glibc does.
> 
> Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
> powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.
> 
> Co-authored-by: Zack Weinberg <zackw@panix.com>
> ---
>  sysdeps/unix/sysv/linux/powerpc/time.c        |  2 +-
>  .../sysv/linux/{time.c => time-internal.h}    | 31
> ++++--------------- sysdeps/posix/time.c => time/time-internal.h  |
> 28 +++-------------- time/time.c                                   |
> 13 ++++---- 4 files changed, 17 insertions(+), 57 deletions(-)
>  rename sysdeps/unix/sysv/linux/{time.c => time-internal.h} (64%)
>  rename sysdeps/posix/time.c => time/time-internal.h (57%)
> 
> diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c
> b/sysdeps/unix/sysv/linux/powerpc/time.c index c35b80fad1..e957b81751
> 100644 --- a/sysdeps/unix/sysv/linux/powerpc/time.c
> +++ b/sysdeps/unix/sysv/linux/powerpc/time.c
> @@ -78,6 +78,6 @@ libc_hidden_def (time)
>  
>  #else
>  
> -#include <sysdeps/posix/time.c>
> +#include <time/time.c>
>  
>  #endif /* !SHARED */
> diff --git a/sysdeps/unix/sysv/linux/time.c
> b/sysdeps/unix/sysv/linux/time-internal.h similarity index 64%
> rename from sysdeps/unix/sysv/linux/time.c
> rename to sysdeps/unix/sysv/linux/time-internal.h
> index f461733678..c4c5f6b643 100644
> --- a/sysdeps/unix/sysv/linux/time.c
> +++ b/sysdeps/unix/sysv/linux/time-internal.h
> @@ -1,4 +1,5 @@
> -/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
> +/* Internals of time and related functions.  Linux version.
> +   Copyright 2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>  
>     The GNU C Library is free software; you can redistribute it and/or
> @@ -15,27 +16,7 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#include <stddef.h>
> -#include <time.h>
> -
> -#include <sysdep.h>
> -
> -#ifdef __NR_time
> -
> -time_t
> -time (time_t *t)
> -{
> -  INTERNAL_SYSCALL_DECL (err);
> -  time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
> -  /* There cannot be any error.  */
> -  if (t != NULL)
> -    *t = res;
> -  return res;
> -}
> -libc_hidden_def (time)
> -
> -#else
> -
> -# include <sysdeps/posix/time.c>
> -
> -#endif
> +/* Timer used on clock_gettime for time implementation.  For Linux
> +   it uses the coarse version which returns the time at the last tick
> +   and mimic what time as syscall should return.  */
> +#define TIME_CLOCK_GETTIME_CLOCKID CLOCK_REALTIME_COARSE
> diff --git a/sysdeps/posix/time.c b/time/time-internal.h
> similarity index 57%
> rename from sysdeps/posix/time.c
> rename to time/time-internal.h
> index 0ab31bd7b6..f448f64191 100644
> --- a/sysdeps/posix/time.c
> +++ b/time/time-internal.h
> @@ -1,4 +1,5 @@
> -/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
> +/* Internals of time and related functions.
> +   Copyright 2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>  
>     The GNU C Library is free software; you can redistribute it and/or
> @@ -15,26 +16,5 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#include <stddef.h>		/* For NULL.  */
> -#include <time.h>
> -#include <sys/time.h>
> -
> -
> -/* Return the current time as a `time_t' and also put it in *T if T
> is
> -   not NULL.  Time is represented as seconds from Jan 1 00:00:00
> 1970.  */ -time_t
> -time (time_t *t)
> -{
> -  struct timeval tv;
> -  time_t result;
> -
> -  if (__gettimeofday (&tv, (struct timezone *) NULL))
> -    result = (time_t) -1;
> -  else
> -    result = (time_t) tv.tv_sec;
> -
> -  if (t != NULL)
> -    *t = result;
> -  return result;
> -}
> -libc_hidden_def (time)
> +/* Timer used on clock_gettime for time implementation.  */
> +#define TIME_CLOCK_GETTIME_CLOCKID CLOCK_REALTIME
> diff --git a/time/time.c b/time/time.c
> index b53a06e29c..09a2b4fc88 100644
> --- a/time/time.c
> +++ b/time/time.c
> @@ -15,19 +15,18 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#include <errno.h>
>  #include <time.h>
> +#include <time-internal.h>
>  
>  /* Return the time now, and store it in *TIMER if not NULL.  */
>  time_t
>  time (time_t *timer)
>  {
> -  __set_errno (ENOSYS);
> +  struct timespec ts;
> +  __clock_gettime (TIME_CLOCK_GETTIME_CLOCKID, &ts);
>  
> -  if (timer != NULL)
> -    *timer = (time_t) -1;
> -  return (time_t) -1;
> +  if (timer)
> +    *timer = ts.tv_sec;
> +  return ts.tv_sec;
>  }
>  libc_hidden_def (time)
> -
> -stub_warning (time)

Reviewed-by: Lukasz Majewski <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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 06/11] Change most internal uses of time to __clock_gettime.
  2019-10-25 12:09 ` [PATCH v2 06/11] Change most internal uses of time " Adhemerval Zanella
@ 2019-10-25 21:22   ` Lukasz Majewski
  0 siblings, 0 replies; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-25 21:22 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 14028 bytes --]

Hi Adhemerval,

> As for gettimeofday, time will be implemented based on clock_gettime
> on all platforms and internal code should use clock_gettime
> directly.  In addition to removing a layer of indirection, this will
> allow us to remove the PLT-bypass gunk for gettimeofday.
> 
> The changed code always assumes __clock_gettime (CLOCK_REALTIME)
> or __clock_gettime (CLOCK_REALTIME_COURSE) (for Linux case) cannot
				     ^^^^^^ - coarse ?

> fail, using the same rationale for gettimeofday change.  And internal
> helper was added (time_now).
> 
> Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
> powerpc64-linux-gnu, and powerpc-linux-gnu.
> ---
>  include/time.h                         | 11 +++-
>  misc/syslog.c                          |  2 +-
>  nscd/nscd_gethst_r.c                   |  2 +-
>  nscd/nscd_helper.c                     |  4 +-
>  string/strfry.c                        |  4 +-
>  sysdeps/unix/sysv/linux/check_native.c |  2 +-
>  sysdeps/unix/sysv/linux/check_pf.c     |  2 +-
>  sysdeps/unix/sysv/linux/getsysstats.c  |  2 +-
>  sysdeps/unix/sysv/linux/i386/time.c    | 34 ------------
>  sysdeps/unix/sysv/linux/ifaddrs.c      |  2 +-
>  sysdeps/unix/sysv/linux/powerpc/time.c | 71
> ++++++++------------------ sysdeps/unix/sysv/linux/x86/time.c     |
> 34 ++++-------- time/getdate.c                         |  2 +-
>  time/time.c                            |  1 -
>  14 files changed, 52 insertions(+), 121 deletions(-)
>  delete mode 100644 sysdeps/unix/sysv/linux/i386/time.c
> 
> diff --git a/include/time.h b/include/time.h
> index d93b16a781..3eac3dcb8d 100644
> --- a/include/time.h
> +++ b/include/time.h
> @@ -7,12 +7,12 @@
>  # include <stdbool.h>
>  # include <time/mktime-internal.h>
>  # include <endian.h>
> +# include <time-internal.h>
>  
>  extern __typeof (strftime_l) __strftime_l;
>  libc_hidden_proto (__strftime_l)
>  extern __typeof (strptime_l) __strptime_l;
>  
> -libc_hidden_proto (time)
>  libc_hidden_proto (asctime)
>  libc_hidden_proto (mktime)
>  libc_hidden_proto (timelocal)
> @@ -236,5 +236,14 @@ valid_timespec64_to_timeval (const struct
> __timespec64 ts64) 
>    return tv;
>  }
> +
> +/* Helper function to get time in seconds, similar to time.  */
> +static inline time_t
> +time_now (void)
> +{
> +  struct timespec ts;
> +  __clock_gettime (TIME_CLOCK_GETTIME_CLOCKID, &ts);
> +  return ts.tv_sec;
> +}
>  #endif
>  #endif
> diff --git a/misc/syslog.c b/misc/syslog.c
> index cf2deef533..fd6537edf6 100644
> --- a/misc/syslog.c
> +++ b/misc/syslog.c
> @@ -205,7 +205,7 @@ __vsyslog_internal(int pri, const char *fmt,
> va_list ap, {
>  	    __fsetlocking (f, FSETLOCKING_BYCALLER);
>  	    fprintf (f, "<%d>", pri);
> -	    now = time (NULL);
> +	    now = time_now ();
>  	    f->_IO_write_ptr += __strftime_l (f->_IO_write_ptr,
>  					      f->_IO_write_end
>  					      - f->_IO_write_ptr,
> diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c
> index 18c6be0d48..8eca90fd52 100644
> --- a/nscd/nscd_gethst_r.c
> +++ b/nscd/nscd_gethst_r.c
> @@ -113,7 +113,7 @@ __nscd_get_nl_timestamp (void)
>    if (map == NULL
>        || (map != NO_MAPPING
>  	  && map->head->nscd_certainly_running == 0
> -	  && map->head->timestamp + MAPPING_TIMEOUT < time (NULL)))
> +	  && map->head->timestamp + MAPPING_TIMEOUT < time_now ()))
>      map = __nscd_get_mapping (GETFDHST, "hosts",
> &__hst_map_handle.mapped); 
>    if (map == NO_MAPPING)
> diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
> index 7361fe2e0a..d50615e13e 100644
> --- a/nscd/nscd_helper.c
> +++ b/nscd/nscd_helper.c
> @@ -348,7 +348,7 @@ __nscd_get_mapping (request_type type, const char
> *key, thread got stuck.  */
>  	  || __builtin_expect (! head->nscd_certainly_running
>  			       && (head->timestamp + MAPPING_TIMEOUT
> -				   < time (NULL)), 0))
> +				   < time_now ()), 0))
>  	{
>  	out_unmap:
>  	  __munmap (mapping, mapsize);
> @@ -414,7 +414,7 @@ __nscd_get_map_ref (request_type type, const char
> *name, /* If not mapped or timestamp not updated, request new map.  */
>        if (cur == NULL
>  	  || (cur->head->nscd_certainly_running == 0
> -	      && cur->head->timestamp + MAPPING_TIMEOUT < time
> (NULL))
> +	      && cur->head->timestamp + MAPPING_TIMEOUT < time_now
> ()) || cur->head->data_size > cur->datasize)
>  	cur = __nscd_get_mapping (type, name,
>  				  (struct mapped_database **)
> &mapptr->mapped); diff --git a/string/strfry.c b/string/strfry.c
> index 6306f06ae4..8b293af185 100644
> --- a/string/strfry.c
> +++ b/string/strfry.c
> @@ -17,7 +17,7 @@
>  
>  #include <string.h>
>  #include <stdlib.h>
> -#include <time.h>
> +#include <random-bits.h>
>  #include <unistd.h>
>  
>  char *
> @@ -30,7 +30,7 @@ strfry (char *string)
>      {
>        static char state[32];
>        rdata.state = NULL;
> -      __initstate_r (time (NULL) ^ getpid (),
> +      __initstate_r (random_bits (),
>  		     state, sizeof (state), &rdata);
>        init = 1;
>      }
> diff --git a/sysdeps/unix/sysv/linux/check_native.c
> b/sysdeps/unix/sysv/linux/check_native.c index 3e57629d8c..82e2a0d83f
> 100644 --- a/sysdeps/unix/sysv/linux/check_native.c
> +++ b/sysdeps/unix/sysv/linux/check_native.c
> @@ -69,7 +69,7 @@ __check_native (uint32_t a1_index, int *a1_native,
>    req.nlh.nlmsg_type = RTM_GETLINK;
>    req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
>    req.nlh.nlmsg_pid = 0;
> -  req.nlh.nlmsg_seq = time (NULL);
> +  req.nlh.nlmsg_seq = time_now ();
>    req.g.rtgen_family = AF_UNSPEC;
>  
>    assert (sizeof (req) - offsetof (struct req, pad) == 3);
> diff --git a/sysdeps/unix/sysv/linux/check_pf.c
> b/sysdeps/unix/sysv/linux/check_pf.c index 97a30f63fc..bcb9c602aa
> 100644 --- a/sysdeps/unix/sysv/linux/check_pf.c
> +++ b/sysdeps/unix/sysv/linux/check_pf.c
> @@ -126,7 +126,7 @@ make_request (int fd, pid_t pid)
>    req.nlh.nlmsg_type = RTM_GETADDR;
>    req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
>    req.nlh.nlmsg_pid = 0;
> -  req.nlh.nlmsg_seq = time (NULL);
> +  req.nlh.nlmsg_seq = time_now ();
>    req.g.rtgen_family = AF_UNSPEC;
>  
>    assert (sizeof (req) - offsetof (struct req, pad) == 3);
> diff --git a/sysdeps/unix/sysv/linux/getsysstats.c
> b/sysdeps/unix/sysv/linux/getsysstats.c index 41ceb9a320..6457193227
> 100644 --- a/sysdeps/unix/sysv/linux/getsysstats.c
> +++ b/sysdeps/unix/sysv/linux/getsysstats.c
> @@ -128,7 +128,7 @@ __get_nprocs (void)
>    static int cached_result = -1;
>    static time_t timestamp;
>  
> -  time_t now = time (NULL);
> +  time_t now = time_now ();
>    time_t prev = timestamp;
>    atomic_read_barrier ();
>    if (now == prev && cached_result > -1)
> diff --git a/sysdeps/unix/sysv/linux/i386/time.c
> b/sysdeps/unix/sysv/linux/i386/time.c deleted file mode 100644
> index 1bbe079f65..0000000000
> --- a/sysdeps/unix/sysv/linux/i386/time.c
> +++ /dev/null
> @@ -1,34 +0,0 @@
> -/* time -- Get number of seconds since Epoch.  Linux/i386 version.
> -   Copyright (C) 2015-2019 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be
> useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#ifdef SHARED
> -# define time __redirect_time
> -#endif
> -
> -#include <time.h>
> -
> -#ifdef SHARED
> -# undef time
> -# define time_type __redirect_time
> -
> -# undef libc_hidden_def
> -# define libc_hidden_def(name)  \
> -  __hidden_ver1 (__time_syscall, __GI_time, __time_syscall);
> -#endif
> -
> -#include <sysdeps/unix/sysv/linux/x86/time.c>
> diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c
> b/sysdeps/unix/sysv/linux/ifaddrs.c index 0c36001660..2b89c7a3af
> 100644 --- a/sysdeps/unix/sysv/linux/ifaddrs.c
> +++ b/sysdeps/unix/sysv/linux/ifaddrs.c
> @@ -102,7 +102,7 @@ __netlink_sendreq (struct netlink_handle *h, int
> type) struct sockaddr_nl nladdr;
>  
>    if (h->seq == 0)
> -    h->seq = time (NULL);
> +    h->seq = time_now ();
>  
>    req.nlh.nlmsg_len = sizeof (req);
>    req.nlh.nlmsg_type = type;
> diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c
> b/sysdeps/unix/sysv/linux/powerpc/time.c index e957b81751..80a4c73416
> 100644 --- a/sysdeps/unix/sysv/linux/powerpc/time.c
> +++ b/sysdeps/unix/sysv/linux/powerpc/time.c
> @@ -16,68 +16,37 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#ifdef SHARED
> -# ifndef __powerpc64__
> -#  define time __redirect_time
> -# else
> -#  define __redirect_time time
> -# endif
> -
> -# include <time.h>
> -# include <sysdep.h>
> -# include <dl-vdso.h>
> -# include <libc-vdso.h>
> -# include <dl-machine.h>
> +#include <time.h>
> +#include <sysdep.h>
>  
> -# ifndef __powerpc64__
> -#  undef time
> +#ifdef HAVE_TIME_VSYSCALL
> +# define HAVE_VSYSCALL
> +#endif
> +#include <sysdep-vdso.h>
>  
> -time_t
> -__time_vsyscall (time_t *t)
> +static time_t
> +time_vsyscall (time_t *t)
>  {
>    return INLINE_VSYSCALL (time, 1, t);
>  }
>  
> -/* __GI_time is defined as hidden and for ppc32 it enables the
> -   compiler make a local call (symbol@local) for internal GLIBC
> usage. It
> -   means the PLT won't be used and the ifunc resolver will be called
> directly.
> -   For ppc64 a call to a function in another translation unit might
> use a
> -   different toc pointer thus disallowing direct branchess and
> making internal
> -   ifuncs calls safe.  */
> -#  undef libc_hidden_def
> -#  define libc_hidden_def(name)
> 	\
> -  __hidden_ver1 (__time_vsyscall, __GI_time, __time_vsyscall);
> -
> -# endif /* !__powerpc64__  */
> -
> -static time_t
> -time_syscall (time_t *t)
> -{
> -  struct timeval tv;
> -  time_t result;
> -
> -  if (INLINE_VSYSCALL (gettimeofday, 2, &tv, NULL) < 0)
> -    result = (time_t) -1;
> -  else
> -    result = (time_t) tv.tv_sec;
> -
> -  if (t != NULL)
> -    *t = result;
> -  return result;
> -}
> +#ifdef SHARED
> +# include <dl-vdso.h>
> +# include <libc-vdso.h>
>  
>  # define INIT_ARCH() \
>    void *vdso_time = get_vdso_symbol (HAVE_TIME_VSYSCALL);
>  
>  /* If the vDSO is not available we fall back to the syscall.  */
> -libc_ifunc_hidden (__redirect_time, time,
> -		   vdso_time
> -		   ? VDSO_IFUNC_RET (vdso_time)
> -		   : (void *) time_syscall);
> -libc_hidden_def (time)
> +libc_ifunc (time,
> +	    vdso_time
> +	    ? VDSO_IFUNC_RET (vdso_time)
> +	    : (void *) time_vsyscall);
>  
>  #else
> -
> -#include <time/time.c>
> -
> +time_t
> +time (time_t *t)
> +{
> +  return time_vsyscall (t);
> +}
>  #endif /* !SHARED */
> diff --git a/sysdeps/unix/sysv/linux/x86/time.c
> b/sysdeps/unix/sysv/linux/x86/time.c index 2e47661be3..4a03c46d21
> 100644 --- a/sysdeps/unix/sysv/linux/x86/time.c
> +++ b/sysdeps/unix/sysv/linux/x86/time.c
> @@ -17,43 +17,31 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #include <time.h>
> +#include <sysdep.h>
>  
> -#ifdef SHARED
> -
> -#include <dl-vdso.h>
> -#include <errno.h>
> +#ifdef HAVE_TIME_VSYSCALL
> +# define HAVE_VSYSCALL
> +#endif
>  #include <sysdep-vdso.h>
>  
>  static time_t
> -__time_syscall (time_t *t)
> +time_vsyscall (time_t *t)
>  {
> -  INTERNAL_SYSCALL_DECL (err);
> -  return INTERNAL_SYSCALL (time, err, 1, t);
> +  return INLINE_VSYSCALL (time, 1, t);
>  }
>  
> -# ifndef time_type
> -/* The i386 time.c includes this file with a defined time_type macro.
> -   For x86_64 we have to define it to time as the internal symbol is
> the
> -   ifunc'ed one.  */
> -#  define time_type time
> -# endif
> +#ifdef SHARED
> +# include <dl-vdso.h>
> +# include <libc-vdso.h>
>  
>  #undef INIT_ARCH
>  #define INIT_ARCH()
>  /* If the vDSO is not available we fall back on the syscall.  */
> -libc_ifunc_hidden (time_type, time,
> -		   (get_vdso_symbol ("__vdso_time") ?:
> __time_syscall)) -libc_hidden_def (time)
> -
> +libc_ifunc (time, (get_vdso_symbol ("__vdso_time") ?: time_vsyscall))
>  #else
> -
> -# include <sysdep.h>
> -
>  time_t
>  time (time_t *t)
>  {
> -  INTERNAL_SYSCALL_DECL (err);
> -  return INTERNAL_SYSCALL (time, err, 1, t);
> +  return time_vsyscall (t);
>  }
> -
>  #endif
> diff --git a/time/getdate.c b/time/getdate.c
> index 305e7d9dc4..8e15af9f15 100644
> --- a/time/getdate.c
> +++ b/time/getdate.c
> @@ -219,7 +219,7 @@ __getdate_r (const char *string, struct tm *tp)
>      return 7;
>  
>    /* Get current time.  */
> -  timer = time (NULL);
> +  timer = time_now ();
>    __localtime_r (&timer, &tm);
>  
>    /* If only the weekday is given, today is assumed if the given day
> diff --git a/time/time.c b/time/time.c
> index 09a2b4fc88..cfa92cbbb8 100644
> --- a/time/time.c
> +++ b/time/time.c
> @@ -29,4 +29,3 @@ time (time_t *timer)
>      *timer = ts.tv_sec;
>    return ts.tv_sec;
>  }
> -libc_hidden_def (time)


Reviewed-by: Lukasz Majewski <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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 04/11] Use clock_settime to implement settimeofday.
  2019-10-25 12:09 ` [PATCH v2 04/11] Use clock_settime to implement settimeofday Adhemerval Zanella
  2019-10-25 15:28   ` Lukasz Majewski
  2019-10-25 20:42   ` Alistair Francis
@ 2019-10-25 23:34   ` Rafal Luzynski
  2019-10-28 18:46     ` Adhemerval Zanella
  2 siblings, 1 reply; 34+ messages in thread
From: Rafal Luzynski @ 2019-10-25 23:34 UTC (permalink / raw)
  To: Adhemerval Zanella, libc-alpha; +Cc: Lukasz Majewski, Zack Weinberg

25.10.2019 14:08 Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:
> 
> 
> From: Zack Weinberg <zackw@panix.com>
> 
> Use clock_settime to implement settimeofday.
> 
> Changes from previous version:
> 
>   - Added a NEWS entry.
> 
> --
> 
> [...]
> diff --git a/NEWS b/NEWS
> index 8727b5e7f0..0b1476e745 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -34,6 +34,30 @@ Deprecated and removed features, and other changes
> affecting compatibility:
>    binaries and it has been removed from <time.h> header.  This function
>    has been deprecated in favor of clock_settime.
>  
> +* The settimeofday function can still be used to set a system-wide time
> +  zone when the operating system supports it.  This is because the Linux
> +  kernel reused the API, on some architectures, to describe a system-wide
> +  time-zone-like offset between the software clock maintained by the
> kernel,
> +  and the “RTC” clock that keeps time when the system is shut down.

That's little off-topic and little nit-picky but are you sure you want to
use the Unicode quotes like “” instead of plain ASCII "" ?  No problem if
this is what you really want but I suspect your editor converted this.

> +  However, to reduce the odds of this offset being set by accident,
> +  settimeofday can no longer be used to set the time and the offset
> +  simultaneously.  If both of its two arguments are non-null, the call
> +  will fail (setting errno to EINVAL).
> +
> +  Callers attempting to set this offset should also be prepared for the
> call
> +  to fail and set errno to ENOSYS; this already happens on the Hurd and
> on
> +  some Linux architectures.  The Linux kernel maintainers are discussing
> a
> +  more principled replacement for the reused API.  After a replacement
> +  becomes available, we will change settimeofday to fail with ENOSYS on
> all
> +  platforms when its ‘tzp’ argument is not a null pointer.

Same here, the Unicode ‘’ instead of plain ASCII '' .

> +  Note that settimeofday itself is obsolescent according to POSIX.
> +  Programs that set the system time should use clock_settime and/or
> +  the adjtime family of functions instead.  We may also cease to make
> +  settimeofday available to newly linked binaries after there is a
> +  replacement for Linux’s time-zone-like offset API.

Again the Unicode apostrophe ’ instead of plain ASCII ' .

Regards,

Rafal

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls.
  2019-10-25 12:08 ` [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls Adhemerval Zanella
  2019-10-25 13:05   ` Lukasz Majewski
@ 2019-10-26  1:08   ` Alistair Francis
  2019-10-28 18:13     ` Adhemerval Zanella
  1 sibling, 1 reply; 34+ messages in thread
From: Alistair Francis @ 2019-10-26  1:08 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library, Lukasz Majewski, Zack Weinberg

On Fri, Oct 25, 2019 at 5:09 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> From: Zack Weinberg <zackw@panix.com>
>
> Changes from previous version:
>
>   - Add check usage32 check on __wait4_tv32.
>
>   - Change capitalized functions to lowercase.
>
> --
>
> Linux/Alpha has two versions of several system call wrappers that take
> or return data of type "struct timeval" (possibly nested inside a
> larger structure).  The GLIBC_2.0 version is a compat symbol that
> calls __NR_osf_foo or __NR_old_foo and uses a struct timeval with a
> 32-bit tv_sec field.  The GLIBC_2.1 version is used for current code,
> calls __NR_foo, and uses a struct timeval with a 64-bit tv_sec field.
>
> This patch changes all of the compat symbols of this type to be
> wrappers around their GLIBC_2.1 counterparts; the compatibility system
> calls will no longer be used.  It serves as a proposal for part of how
> we do the transition to 64-bit time_t on systems that currently use
> 32-bit time_t:
>
>  * The patched glibc will NOT use system calls that involve 32-bit
>    time_t to implement its compatibility symbols.  This will make both
>    our lives and the kernel maintainers' lives easier.  The primary
>    argument I've seen against it is that the kernel could warn about
>    uses of the old system calls, helping people find old binaries that
>    need to be recompiled.  I think there are several other ways we
>    could accomplish this, e.g. scripts to scan the filesystem for
>    binaries with references to the old symbol versions, or issuing
>    diagnostics ourselves.
>
>  * The compat symbols do NOT report failure after the Y2038 deadline.
>    An earlier revision of this patch had them return -1 and set errno
>    to EOVERFLOW, but Adhemerval pointed out that many of them have
>    already performed side effects at the point where we discover the
>    overflow, so that would break more than it fixes.  Also, we don't
>    want people to be _checking_ for EOVERFLOW from these functions; we
>    want them to recompile with 64-bit time_t.  So it's not actually
>    useful for them to report failure to the calling code.
>
>  * What they do do, when they encounter overflow, is saturate the
>    overflowed "struct timeval"(s): tv_sec is set to INT32_MAX and
>    tv_nsec is set to 999999.  That means time stops advancing for
>    programs with 32-bit time_t when they reach the deadline.  That's
>    obviously going to break stuff, but I think wrapping around is
>    probably going to break _more_ stuff.  I'd be interested to hear
>    arguments against, if anyone has one.
>
> The new header file tv32-compat.h is currently Alpha-specific but I
> mean for it to be reused to aid in writing wrappers for all affected
> architectures.  I only put it in sysdeps/unix/sysv/linux/alpha for now
> because I haven't checked whether the various "foo32" structures it
> defines agree with the ABI for ports other than Linux/Alpha.
>
> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
>  sysdeps/unix/sysv/linux/Makefile              |   2 +-
>  sysdeps/unix/sysv/linux/adjtime.c             |  40 ++---
>  sysdeps/unix/sysv/linux/adjtimex.c            |  40 +++++
>  sysdeps/unix/sysv/linux/alpha/Makefile        |   2 +-
>  sysdeps/unix/sysv/linux/alpha/adjtime.c       |  82 +---------
>  sysdeps/unix/sysv/linux/alpha/adjtimex.c      |  22 +++
>  sysdeps/unix/sysv/linux/alpha/osf_adjtime.c   | 130 ++++++++++++++++
>  sysdeps/unix/sysv/linux/alpha/osf_getitimer.c |  41 +++++
>  sysdeps/unix/sysv/linux/alpha/osf_getrusage.c |  39 +++++
>  .../unix/sysv/linux/alpha/osf_gettimeofday.c  |  43 ++++++
>  sysdeps/unix/sysv/linux/alpha/osf_setitimer.c |  49 ++++++
>  .../unix/sysv/linux/alpha/osf_settimeofday.c  |  41 +++++
>  sysdeps/unix/sysv/linux/alpha/osf_utimes.c    |  37 +++++
>  sysdeps/unix/sysv/linux/alpha/osf_wait4.c     |  41 +++++
>  sysdeps/unix/sysv/linux/alpha/syscalls.list   |  27 ++--
>  sysdeps/unix/sysv/linux/alpha/tv32-compat.h   | 146 ++++++++++++++++++
>  sysdeps/unix/sysv/linux/gettimeofday.c        |  14 +-
>  sysdeps/unix/sysv/linux/syscalls.list         |   1 -
>  18 files changed, 666 insertions(+), 131 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/adjtimex.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/adjtimex.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_utimes.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_wait4.c
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/tv32-compat.h
>
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index bbab8f8cc3..a7623fb390 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -14,7 +14,7 @@ endif
>  ifeq ($(subdir),misc)
>  include $(firstword $(wildcard $(sysdirs:=/sysctl.mk)))
>
> -sysdep_routines += clone umount umount2 readahead \
> +sysdep_routines += adjtimex clone umount umount2 readahead \
>                    setfsuid setfsgid epoll_pwait signalfd \
>                    eventfd eventfd_read eventfd_write prlimit \
>                    personality epoll_wait tee vmsplice splice \
> diff --git a/sysdeps/unix/sysv/linux/adjtime.c b/sysdeps/unix/sysv/linux/adjtime.c
> index 6d1e129ccc..6b8021caa3 100644
> --- a/sysdeps/unix/sysv/linux/adjtime.c
> +++ b/sysdeps/unix/sysv/linux/adjtime.c
> @@ -23,39 +23,14 @@
>  #define MAX_SEC        (INT_MAX / 1000000L - 2)
>  #define MIN_SEC        (INT_MIN / 1000000L + 2)
>
> -#ifndef MOD_OFFSET
> -#define modes mode
> -#endif
> -
> -#ifndef TIMEVAL
> -#define TIMEVAL timeval
> -#endif
> -
> -#ifndef TIMEX
> -#define TIMEX timex
> -#endif
> -
> -#ifndef ADJTIME
> -#define ADJTIME __adjtime
> -#endif
> -
> -#ifndef ADJTIMEX
> -#define NO_LOCAL_ADJTIME
> -#define ADJTIMEX(x) __adjtimex (x)
> -#endif
> -
> -#ifndef LINKAGE
> -#define LINKAGE
> -#endif
> -
> -LINKAGE int
> -ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
> +int
> +__adjtime (const struct timeval *itv, struct timeval *otv)
>  {
> -  struct TIMEX tntx;
> +  struct timex tntx;
>
>    if (itv)
>      {
> -      struct TIMEVAL tmp;
> +      struct timeval tmp;
>
>        /* We will do some check here. */
>        tmp.tv_sec = itv->tv_sec + itv->tv_usec / 1000000L;
> @@ -68,7 +43,7 @@ ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
>    else
>      tntx.modes = ADJ_OFFSET_SS_READ;
>
> -  if (__glibc_unlikely (ADJTIMEX (&tntx) < 0))
> +  if (__glibc_unlikely (__adjtimex (&tntx) < 0))
>      return -1;
>
>    if (otv)
> @@ -87,6 +62,9 @@ ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv)
>    return 0;
>  }
>
> -#ifdef NO_LOCAL_ADJTIME
> +#ifdef VERSION_adjtime
> +weak_alias (__adjtime, __wadjtime);
> +default_symbol_version (__wadjtime, adjtime, VERSION_adjtime);
> +#else
>  weak_alias (__adjtime, adjtime)
>  #endif
> diff --git a/sysdeps/unix/sysv/linux/adjtimex.c b/sysdeps/unix/sysv/linux/adjtimex.c
> new file mode 100644
> index 0000000000..6d62c72a17
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/adjtimex.c
> @@ -0,0 +1,40 @@
> +/* Tune kernel clock.  Linux specific syscall.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <sys/timex.h>
> +#include <sysdep.h>
> +
> +int
> +___adjtimex (struct timex *buf)
> +{
> +  return INLINE_SYSCALL_CALL (adjtimex, buf);

The y2038 safe platforms don't have the adjtimex syscall, instead they
have the clock_adjtime call. Can this fall back to clock_adjtime if
__NR_adjtimex isn't defined?

Alistair

> +}
> +
> +#ifdef VERSION_adjtimex
> +weak_alias (___adjtimex, __wadjtimex);
> +weak_alias (___adjtimex, __wnadjtime);
> +default_symbol_version (___adjtimex,  __adjtimex, VERSION_adjtimex);
> +default_symbol_version (__wadjtimex,    adjtimex, VERSION_adjtimex);
> +default_symbol_version (__wnadjtime, ntp_adjtime, VERSION_adjtimex);
> +libc_hidden_ver (___adjtimex, __adjtimex);
> +#else
> +strong_alias (___adjtimex, __adjtimex)
> +weak_alias (___adjtimex, adjtimex)
> +weak_alias (___adjtimex, ntp_adjtime)
> +libc_hidden_def (__adjtimex)
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile
> index fdd089af71..2e132e474b 100644
> --- a/sysdeps/unix/sysv/linux/alpha/Makefile
> +++ b/sysdeps/unix/sysv/linux/alpha/Makefile
> @@ -9,7 +9,7 @@ sysdep_routines += ieee_get_fp_control ieee_set_fp_control \
>                    ioperm
>
>  # Support old timeval32 entry points
> -sysdep_routines += osf_gettimeofday osf_settimeofday \
> +sysdep_routines += osf_adjtime osf_gettimeofday osf_settimeofday \
>                    osf_getitimer osf_setitimer osf_utimes \
>                    osf_getrusage osf_wait4
>
> diff --git a/sysdeps/unix/sysv/linux/alpha/adjtime.c b/sysdeps/unix/sysv/linux/alpha/adjtime.c
> index 4aede1cc40..9cb058ee55 100644
> --- a/sysdeps/unix/sysv/linux/alpha/adjtime.c
> +++ b/sysdeps/unix/sysv/linux/alpha/adjtime.c
> @@ -1,4 +1,5 @@
> -/* Copyright (C) 1998-2019 Free Software Foundation, Inc.
> +/* adjtime -- Adjust the current time of day.  Linux/Alpha/tv64 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>
>     The GNU C Library is free software; you can redistribute it and/or
> @@ -15,80 +16,7 @@
>     License along with the GNU C Library.  If not, see
>     <https://www.gnu.org/licenses/>.  */
>
> -#include <shlib-compat.h>
> -#include <sysdep.h>
> -#include <sys/time.h>
> -
> -
> -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> -struct timeval32
> -{
> -    int tv_sec, tv_usec;
> -};
> -
> -struct timex32 {
> -       unsigned int modes;     /* mode selector */
> -       long offset;            /* time offset (usec) */
> -       long freq;              /* frequency offset (scaled ppm) */
> -       long maxerror;          /* maximum error (usec) */
> -       long esterror;          /* estimated error (usec) */
> -       int status;             /* clock command/status */
> -       long constant;          /* pll time constant */
> -       long precision;         /* clock precision (usec) (read only) */
> -       long tolerance;         /* clock frequency tolerance (ppm)
> -                                * (read only)
> -                                */
> -       struct timeval32 time;  /* (read only) */
> -       long tick;              /* (modified) usecs between clock ticks */
> -
> -       long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
> -       long jitter;            /* pps jitter (us) (ro) */
> -       int shift;              /* interval duration (s) (shift) (ro) */
> -       long stabil;            /* pps stability (scaled ppm) (ro) */
> -       long jitcnt;            /* jitter limit exceeded (ro) */
> -       long calcnt;            /* calibration intervals (ro) */
> -       long errcnt;            /* calibration errors (ro) */
> -       long stbcnt;            /* stability limit exceeded (ro) */
> -
> -       int  :32; int  :32; int  :32; int  :32;
> -       int  :32; int  :32; int  :32; int  :32;
> -       int  :32; int  :32; int  :32; int  :32;
> -};
> -
> -#define TIMEVAL                timeval32
> -#define TIMEX          timex32
> -#define ADJTIME                attribute_compat_text_section __adjtime_tv32
> -#define ADJTIMEX(x)    INLINE_SYSCALL (old_adjtimex, 1, x)
> -#define ADJTIMEX32(x)  INLINE_SYSCALL (old_adjtimex, 1, x)
> -
> +/* We can use the generic Linux implementation, but we have to override its
> +   default symbol version.  */
> +#define VERSION_adjtime GLIBC_2.1
>  #include <sysdeps/unix/sysv/linux/adjtime.c>
> -
> -int attribute_compat_text_section
> -__adjtimex_tv32 (struct timex32 *tx) { return ADJTIMEX (tx); }
> -
> -strong_alias (__adjtimex_tv32, __adjtimex_tv32_1);
> -strong_alias (__adjtimex_tv32, __adjtimex_tv32_2);
> -compat_symbol (libc, __adjtimex_tv32_1, __adjtimex, GLIBC_2_0);
> -compat_symbol (libc, __adjtimex_tv32_2, adjtimex, GLIBC_2_0);
> -compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0);
> -#endif /* SHLIB_COMPAT */
> -
> -#undef TIMEVAL
> -#undef TIMEX
> -#undef ADJTIME
> -#undef ADJTIMEX
> -#define TIMEVAL                timeval
> -#define TIMEX          timex
> -#define ADJTIMEX(x)    INLINE_SYSCALL (adjtimex, 1, x)
> -
> -#include <sysdeps/unix/sysv/linux/adjtime.c>
> -
> -int
> -__adjtimex_tv64 (struct timex *tx) { return ADJTIMEX (tx); }
> -
> -libc_hidden_ver (__adjtimex_tv64, __adjtimex)
> -strong_alias (__adjtimex_tv64, __adjtimex_tv64p);
> -weak_alias (__adjtimex_tv64, ntp_adjtime);
> -versioned_symbol (libc, __adjtimex_tv64, __adjtimex, GLIBC_2_1);
> -versioned_symbol (libc, __adjtimex_tv64p, adjtimex, GLIBC_2_1);
> -versioned_symbol (libc, __adjtime, adjtime, GLIBC_2_1);
> diff --git a/sysdeps/unix/sysv/linux/alpha/adjtimex.c b/sysdeps/unix/sysv/linux/alpha/adjtimex.c
> new file mode 100644
> index 0000000000..1a8e0a9529
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/adjtimex.c
> @@ -0,0 +1,22 @@
> +/* adjtimex -- Adjust the current time of day.  Linux/Alpha/tv64 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* We can use the generic Linux implementation, but we have to override its
> +   default symbol version.  */
> +#define VERSION_adjtimex GLIBC_2.1
> +#include <sysdeps/unix/sysv/linux/adjtimex.c>
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
> new file mode 100644
> index 0000000000..c948ac2dda
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
> @@ -0,0 +1,130 @@
> +/* adjtime -- adjust the system clock.  Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <sys/timex.h>
> +#include <tv32-compat.h>
> +
> +struct timex32 {
> +       unsigned int modes;     /* mode selector */
> +       long offset;            /* time offset (usec) */
> +       long freq;              /* frequency offset (scaled ppm) */
> +       long maxerror;          /* maximum error (usec) */
> +       long esterror;          /* estimated error (usec) */
> +       int status;             /* clock command/status */
> +       long constant;          /* pll time constant */
> +       long precision;         /* clock precision (usec) (read only) */
> +       long tolerance;         /* clock frequency tolerance (ppm)
> +                                * (read only)
> +                                */
> +       struct timeval32 time;  /* (read only) */
> +       long tick;              /* (modified) usecs between clock ticks */
> +
> +       long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
> +       long jitter;            /* pps jitter (us) (ro) */
> +       int shift;              /* interval duration (s) (shift) (ro) */
> +       long stabil;            /* pps stability (scaled ppm) (ro) */
> +       long jitcnt;            /* jitter limit exceeded (ro) */
> +       long calcnt;            /* calibration intervals (ro) */
> +       long errcnt;            /* calibration errors (ro) */
> +       long stbcnt;            /* stability limit exceeded (ro) */
> +
> +       int  :32; int  :32; int  :32; int  :32;
> +       int  :32; int  :32; int  :32; int  :32;
> +       int  :32; int  :32; int  :32; int  :32;
> +};
> +
> +int
> +attribute_compat_text_section
> +__adjtime_tv32 (const struct timeval32 *itv, struct timeval32 *otv)
> +{
> +  struct timeval itv64, otv64;
> +  tv32_to_tv64 (&itv64, itv);
> +
> +  if (__adjtime (&itv64, &otv64) == -1)
> +    return -1;
> +
> +  tv64_to_tv32 (otv, &itv64);
> +  return 0;
> +}
> +
> +int
> +attribute_compat_text_section
> +__adjtimex_tv32 (struct timex32 *tx)
> +{
> +  struct timex tx64;
> +  memset (&tx64, 0, sizeof tx64);
> +  tx64.modes     = tx->modes;
> +  tx64.offset    = tx->offset;
> +  tx64.freq      = tx->freq;
> +  tx64.maxerror  = tx->maxerror;
> +  tx64.esterror  = tx->esterror;
> +  tx64.status    = tx->status;
> +  tx64.constant  = tx->constant;
> +  tx64.precision = tx->precision;
> +  tx64.tolerance = tx->tolerance;
> +  tx64.tick      = tx->tick;
> +  tx64.ppsfreq   = tx->ppsfreq;
> +  tx64.jitter    = tx->jitter;
> +  tx64.shift     = tx->shift;
> +  tx64.stabil    = tx->stabil;
> +  tx64.jitcnt    = tx->jitcnt;
> +  tx64.calcnt    = tx->calcnt;
> +  tx64.errcnt    = tx->errcnt;
> +  tx64.stbcnt    = tx->stbcnt;
> +  tv32_to_tv64 (&tx64.time, &tx->time);
> +
> +  int status = __adjtimex (&tx64);
> +  if (status < 0)
> +    return status;
> +
> +  memset (tx, 0, sizeof *tx);
> +  tx->modes     = tx64.modes;
> +  tx->offset    = tx64.offset;
> +  tx->freq      = tx64.freq;
> +  tx->maxerror  = tx64.maxerror;
> +  tx->esterror  = tx64.esterror;
> +  tx->status    = tx64.status;
> +  tx->constant  = tx64.constant;
> +  tx->precision = tx64.precision;
> +  tx->tolerance = tx64.tolerance;
> +  tx->tick      = tx64.tick;
> +  tx->ppsfreq   = tx64.ppsfreq;
> +  tx->jitter    = tx64.jitter;
> +  tx->shift     = tx64.shift;
> +  tx->stabil    = tx64.stabil;
> +  tx->jitcnt    = tx64.jitcnt;
> +  tx->calcnt    = tx64.calcnt;
> +  tx->errcnt    = tx64.errcnt;
> +  tx->stbcnt    = tx64.stbcnt;
> +  tv64_to_tv32 (&tx->time, &tx64.time);
> +
> +  return status;
> +}
> +
> +strong_alias (__adjtimex_tv32, __adjtimex_tv32_1);
> +strong_alias (__adjtimex_tv32, __adjtimex_tv32_2);
> +compat_symbol (libc, __adjtimex_tv32_1, __adjtimex, GLIBC_2_0);
> +compat_symbol (libc, __adjtimex_tv32_2, adjtimex, GLIBC_2_0);
> +compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0);
> +
> +#endif /* SHLIB_COMPAT */
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
> new file mode 100644
> index 0000000000..f290954783
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
> @@ -0,0 +1,41 @@
> +/* getitimer -- Get the state of an interval timer.  Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <tv32-compat.h>
> +
> +int
> +attribute_compat_text_section
> +__getitimer_tv32 (int which, struct itimerval32 *curr_value)
> +{
> +  struct itimerval curr_value_64;
> +  if (__getitimer (which, &curr_value_64) == -1)
> +    return -1;
> +
> +  /* Write all fields of 'curr_value' regardless of overflow.  */
> +  tv64_to_tv32 (&curr_value->it_interval, &curr_value_64.it_interval);
> +  tv64_to_tv32 (&curr_value->it_value, &curr_value_64.it_value);
> +  return 0;
> +}
> +
> +compat_symbol (libc, __getitimer_tv32, getitimer, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
> new file mode 100644
> index 0000000000..918e8445d4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
> @@ -0,0 +1,39 @@
> +/* utimes -- change file timestamps.  Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <sys/resource.h>
> +#include <tv32-compat.h>
> +
> +int
> +__getrusage_tv32 (int who, struct rusage32 *usage32)
> +{
> +  struct rusage usage64;
> +  if (__getrusage (who, &usage64) == -1)
> +    return -1;
> +
> +  rusage64_to_rusage32 (usage32, &usage64);
> +  return 0;
> +}
> +
> +compat_symbol (libc, __getrusage_tv32, getrusage, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
> new file mode 100644
> index 0000000000..e6cc522dd1
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
> @@ -0,0 +1,43 @@
> +/* gettimeofday -- Get the current time of day.  Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <tv32-compat.h>
> +
> +/* Get the current time of day and timezone information putting it
> +   into *TV and *TZ.  */
> +
> +int
> +attribute_compat_text_section
> +__gettimeofday_tv32 (struct timeval32 *restrict tv32, void *restrict tz)
> +{
> +  struct timeval tv;
> +  __gettimeofday (&tv, tz);
> +
> +  tv64_to_tv32 (tv32, &tv);
> +  return 0;
> +}
> +
> +compat_symbol (libc, __gettimeofday_tv32, __gettimeofday, GLIBC_2_0);
> +strong_alias (__gettimeofday_tv32, __gettimeofday_tv32_1);
> +compat_symbol (libc, __gettimeofday_tv32_1, gettimeofday, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
> new file mode 100644
> index 0000000000..d6bbcee60a
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
> @@ -0,0 +1,49 @@
> +/* getitimer -- Get the state of an interval timer.  Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <tv32-compat.h>
> +
> +int
> +attribute_compat_text_section
> +__setitimer_tv32 (int which, const struct itimerval32 *restrict new_value,
> +                 struct itimerval32 *restrict old_value)
> +{
> +  struct itimerval new_value_64;
> +  tv32_to_tv64 (&new_value_64.it_interval, &new_value->it_interval);
> +  tv32_to_tv64 (&new_value_64.it_value, &new_value->it_value);
> +
> +  if (old_value == NULL)
> +    return __setitimer (which, &new_value_64, NULL);
> +
> +  struct itimerval old_value_64;
> +  if (__setitimer (which, &new_value_64, &old_value_64) == -1)
> +    return -1;
> +
> +  /* Write all fields of 'old_value' regardless of overflow.  */
> +  tv64_to_tv32 (&old_value->it_interval, &old_value_64.it_interval);
> +  tv64_to_tv32 (&old_value->it_value, &old_value_64.it_value);
> +  return 0;
> +}
> +
> +compat_symbol (libc, __setitimer_tv32, setitimer, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
> new file mode 100644
> index 0000000000..fb2a36df19
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
> @@ -0,0 +1,41 @@
> +/* settimeofday -- Set the current time of day.  Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <time.h>
> +#include <errno.h>
> +#include <tv32-compat.h>
> +
> +/* Set the current time of day and timezone information.
> +   This call is restricted to the super-user.  */
> +int
> +attribute_compat_text_section
> +__settimeofday_tv32 (const struct timeval32 *tv32,
> +                     const struct timezone *tz)
> +{
> +  struct timeval tv;
> +  tv32_to_tv64 (&tv, tv32);
> +  return __settimeofday (&tv, tz);
> +}
> +
> +compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_utimes.c b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
> new file mode 100644
> index 0000000000..788fb7cd44
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
> @@ -0,0 +1,37 @@
> +/* utimes -- change file timestamps.  Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <tv32-compat.h>
> +
> +int
> +attribute_compat_text_section
> +__utimes_tv32 (const char *filename, const struct timeval32 times32[2])
> +{
> +  struct timeval times[2];
> +  tv32_to_tv64 (&times[0], &times32[0]);
> +  tv32_to_tv64 (&times[1], &times32[1]);
> +  return __utimes (filename, times);
> +}
> +
> +compat_symbol (libc, __utimes_tv32, utimes, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_wait4.c b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
> new file mode 100644
> index 0000000000..e8db554660
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
> @@ -0,0 +1,41 @@
> +/* wait4 -- wait for process to change state.  Linux/Alpha/tv32 version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> +
> +#include <sys/time.h>
> +#include <sys/resource.h>
> +#include <sys/wait.h>
> +#include <tv32-compat.h>
> +
> +pid_t
> +attribute_compat_text_section
> +__wait4_tv32 (pid_t pid, int *status, int options, struct rusage32 *usage32)
> +{
> +  struct rusage usage64;
> +  pid_t child = __wait4 (pid, status, options, &usage64);
> +
> +  if (child >= 0 && usage32 != NULL)
> +    rusage64_to_rusage32 (usage32, &usage64);
> +  return child;
> +}
> +
> +compat_symbol (libc, __wait4_tv32, wait4, GLIBC_2_0);
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list
> index 12cd021b60..c786aa751e 100644
> --- a/sysdeps/unix/sysv/linux/alpha/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list
> @@ -1,4 +1,4 @@
> -# File name    Caller  Syscall name    # args  Strong name     Weak names
> +# File name    Caller  Syscall name    Args    Strong name     Weak names
>
>  sigstack       -       sigstack        2       sigstack
>
> @@ -22,23 +22,14 @@ pciconfig_read      EXTRA   pciconfig_read  5       pciconfig_read
>  pciconfig_write        EXTRA   pciconfig_write 5       pciconfig_write
>  pciconfig_iobase EXTRA pciconfig_iobase 3      __pciconfig_iobase pciconfig_iobase
>
> -# support old timeval32 entry points
> -osf_gettimeofday -     osf_gettimeofday 2      __gettimeofday_tv32  __gettimeofday@GLIBC_2.0 gettimeofday@GLIBC_2.0
> -osf_settimeofday -     osf_settimeofday 2      __settimeofday_tv32  settimeofday@GLIBC_2.0
> -osf_getitimer  -       osf_getitimer   2       __getitimer_tv32  getitimer@GLIBC_2.0
> -osf_setitimer  -       osf_setitimer   3       __setitimer_tv32  setitimer@GLIBC_2.0
> -osf_utimes     -       osf_utimes      2       __utimes_tv32  utimes@GLIBC_2.0
> -osf_getrusage  -       osf_getrusage   2       __getrusage_tv32  getrusage@GLIBC_2.0
> -osf_wait4      -       osf_wait4       4       __wait4_tv32  wait4@GLIBC_2.0
> -
> -# support new timeval64 entry points
> -gettimeofday   -       gettimeofday    2       __GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
> -settimeofday   -       settimeofday    2       __settimeofday settimeofday@@GLIBC_2.1
> -getitimer      -       getitimer       2       __getitimer getitimer@@GLIBC_2.1
> -setitimer      -       setitimer       3       __setitimer setitimer@@GLIBC_2.1
> -utimes         -       utimes          2       __utimes utimes@@GLIBC_2.1
> -getrusage      -       getrusage       2       __getrusage getrusage@@GLIBC_2.1
> -wait4          -       wait4           4       __wait4 wait4@@GLIBC_2.1
> +# timeval64 entry points (see osf_*.c for GLIBC_2.0 timeval32 equivalents)
> +gettimeofday   -       gettimeofday    i:pP    __GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
> +settimeofday   -       settimeofday    i:PP    __settimeofday  settimeofday@@GLIBC_2.1
> +getitimer      -       getitimer       i:ip    __getitimer     getitimer@@GLIBC_2.1
> +setitimer      -       setitimer       i:ipP   __setitimer     setitimer@@GLIBC_2.1
> +utimes         -       utimes          i:sp    __utimes        utimes@@GLIBC_2.1
> +getrusage      -       getrusage       i:ip    __getrusage     getrusage@@GLIBC_2.1
> +wait4          -       wait4           i:iWiP  __wait4         wait4@@GLIBC_2.1
>
>  # avoid 64-bit aliases on 32-bit statfs syscalls
>  fstatfs                -       fstatfs         i:ip    __fstatfs       fstatfs
> diff --git a/sysdeps/unix/sysv/linux/alpha/tv32-compat.h b/sysdeps/unix/sysv/linux/alpha/tv32-compat.h
> new file mode 100644
> index 0000000000..e1edb7453a
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/tv32-compat.h
> @@ -0,0 +1,146 @@
> +/* Compatibility definitions for `struct timeval' with 32-bit time_t.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _TV32_COMPAT_H
> +#define _TV32_COMPAT_H 1
> +
> +#include <features.h>
> +
> +#include <bits/types.h>
> +#include <bits/types/time_t.h>
> +#include <bits/types/struct_timeval.h>
> +#include <bits/types/struct_timespec.h>
> +#include <bits/types/struct_rusage.h>
> +
> +#include <stdint.h> // for INT32_MAX
> +#include <string.h> // for memset
> +
> +#define TV_USEC_MAX 999999 // 10**6 - 1
> +
> +/* A version of 'struct timeval' with 32-bit time_t.  */
> +struct timeval32
> +{
> +  int32_t tv_sec;
> +  int32_t tv_usec;
> +};
> +
> +/* Structures containing 'struct timeval' with 32-bit time_t.  */
> +struct itimerval32
> +{
> +  struct timeval32 it_interval;
> +  struct timeval32 it_value;
> +};
> +
> +struct rusage32
> +{
> +  struct timeval32 ru_utime;   /* user time used */
> +  struct timeval32 ru_stime;   /* system time used */
> +  long ru_maxrss;              /* maximum resident set size */
> +  long ru_ixrss;               /* integral shared memory size */
> +  long ru_idrss;               /* integral unshared data size */
> +  long ru_isrss;               /* integral unshared stack size */
> +  long ru_minflt;              /* page reclaims */
> +  long ru_majflt;              /* page faults */
> +  long ru_nswap;               /* swaps */
> +  long ru_inblock;             /* block input operations */
> +  long ru_oublock;             /* block output operations */
> +  long ru_msgsnd;              /* messages sent */
> +  long ru_msgrcv;              /* messages received */
> +  long ru_nsignals;            /* signals received */
> +  long ru_nvcsw;               /* voluntary context switches */
> +  long ru_nivcsw;              /* involuntary " */
> +};
> +
> +/* Conversion functions.  If the seconds field of a timeval32 would
> +   overflow, they write { INT32_MAX, TV_USEC_MAX } to the output.  */
> +
> +static inline void
> +tv32_to_tv64 (struct timeval *restrict tv64,
> +              const struct timeval32 *restrict tv32)
> +{
> +  tv64->tv_sec = tv32->tv_sec;
> +  tv64->tv_usec = tv32->tv_usec;
> +}
> +
> +static inline void
> +tv32_to_ts64 (struct timespec *restrict ts64,
> +              const struct timeval32 *restrict tv32)
> +{
> +  ts64->tv_sec = tv32->tv_sec;
> +  ts64->tv_nsec = tv32->tv_usec * 1000;
> +}
> +
> +static inline void
> +tv64_to_tv32 (struct timeval32 *restrict tv32,
> +              const struct timeval *restrict tv64)
> +{
> +  if (__glibc_unlikely (tv64->tv_sec > (time_t) INT32_MAX))
> +    {
> +      tv32->tv_sec = INT32_MAX;
> +      tv32->tv_usec = TV_USEC_MAX;
> +    }
> +  else
> +    {
> +      tv32->tv_sec = tv64->tv_sec;
> +      tv32->tv_usec = tv64->tv_usec;
> +    }
> +}
> +
> +static inline void
> +ts64_to_tv32 (struct timeval32 *restrict tv32,
> +              const struct timespec *restrict ts64)
> +{
> +  if (__glibc_unlikely (ts64->tv_sec > (time_t) INT32_MAX))
> +    {
> +      tv32->tv_sec = INT32_MAX;
> +      tv32->tv_usec = TV_USEC_MAX;
> +    }
> +  else
> +    {
> +      tv32->tv_sec = ts64->tv_sec;
> +      tv32->tv_usec = ts64->tv_nsec / 1000;
> +    }
> +}
> +
> +static inline void
> +rusage64_to_rusage32 (struct rusage32 *restrict r32,
> +                      const struct rusage *restrict r64)
> +{
> +  /* Make sure the entire output structure is cleared, including
> +     padding and reserved fields.  */
> +  memset (r32, 0, sizeof *r32);
> +
> +  tv64_to_tv32 (&r32->ru_utime, &r64->ru_utime);
> +  tv64_to_tv32 (&r32->ru_stime, &r64->ru_stime);
> +  r32->ru_maxrss   = r64->ru_maxrss;
> +  r32->ru_ixrss    = r64->ru_ixrss;
> +  r32->ru_idrss    = r64->ru_idrss;
> +  r32->ru_isrss    = r64->ru_isrss;
> +  r32->ru_minflt   = r64->ru_minflt;
> +  r32->ru_majflt   = r64->ru_majflt;
> +  r32->ru_nswap    = r64->ru_nswap;
> +  r32->ru_inblock  = r64->ru_inblock;
> +  r32->ru_oublock  = r64->ru_oublock;
> +  r32->ru_msgsnd   = r64->ru_msgsnd;
> +  r32->ru_msgrcv   = r64->ru_msgrcv;
> +  r32->ru_nsignals = r64->ru_nsignals;
> +  r32->ru_nvcsw    = r64->ru_nvcsw;
> +  r32->ru_nivcsw   = r64->ru_nivcsw;
> +}
> +
> +#endif /* tv32-compat.h */
> diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
> index d69d4eaa96..c9597d6405 100644
> --- a/sysdeps/unix/sysv/linux/gettimeofday.c
> +++ b/sysdeps/unix/sysv/linux/gettimeofday.c
> @@ -30,10 +30,20 @@
>     putting it into *tv and *tz.  If tz is null, *tz is not filled.
>     Returns 0 on success, -1 on errors.  */
>  int
> -__gettimeofday (struct timeval *tv, struct timezone *tz)
> +___gettimeofday (struct timeval *tv, struct timezone *tz)
>  {
>    return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
>  }
> +
> +#ifdef VERSION_gettimeofday
> +weak_alias (___gettimeofday, __wgettimeofday);
> +default_symbol_version (___gettimeofday, __gettimeofday, VERSION_gettimeofday);
> +default_symbol_version (__wgettimeofday,   gettimeofday, VERSION_gettimeofday);
> +libc_hidden_ver (___gettimeofday, __gettimeofday);
> +libc_hidden_ver (___gettimeofday, gettimeofday);
> +#else
> +strong_alias (___gettimeofday, __gettimeofday)
> +weak_alias (___gettimeofday, gettimeofday)
>  libc_hidden_def (__gettimeofday)
> -weak_alias (__gettimeofday, gettimeofday)
>  libc_hidden_weak (gettimeofday)
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
> index e374f97b5f..cdcf6c127b 100644
> --- a/sysdeps/unix/sysv/linux/syscalls.list
> +++ b/sysdeps/unix/sysv/linux/syscalls.list
> @@ -1,6 +1,5 @@
>  # File name    Caller  Syscall name    Args    Strong name     Weak names
>
> -adjtimex       adjtime adjtimex        i:p     __adjtimex      adjtimex ntp_adjtime
>  alarm          -       alarm           i:i     alarm
>  bdflush                EXTRA   bdflush         i:ii    __compat_bdflush        bdflush@GLIBC_2.0:GLIBC_2.23
>  capget         EXTRA   capget          i:pp    capget
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 07/11] Consolidate and deprecate ftime
  2019-10-25 12:09 ` [PATCH v2 07/11] Consolidate and deprecate ftime Adhemerval Zanella
@ 2019-10-28 13:23   ` Lukasz Majewski
  0 siblings, 0 replies; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-28 13:23 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Zack Weinberg

[-- Attachment #1: Type: text/plain, Size: 7306 bytes --]

Hi Adhemerval,

> From: Zack Weinberg <zackw@panix.com>
> 
> Consolidate and deprecate ftime
> 
> Changes from previous version:
> 
>   - Do not remove sys/timeb.h, instead mark ftime as deprecated.  The
>     idea is still to remove it eventually on a future release.
> 
> --
> 
> ftime is an obsolete variation on gettimeofday, offering only
> millisecond time resolution; it was probably a system call in ooold
> versions of BSD Unix.  For historic reasons, we had three
> implementations of it.  These are all consolidated into time/ftime.c,
> and then the function is deprecated.
> 
> For some reason, the implementation of ftime in terms of gettimeofday
> was rounding rather than truncating microseconds to milliseconds.  In
> all the other places where we use a higher-resolution time function to
> implement a lower-resolution one, we truncate.  ftime is changed to
> match, just for tidiness' sake.
> 
> Like gettimeofday, ftime tries to report the time zone, and using that
> information is always a bug.  This patch dummies out the reported
> timezone information; the timezone and dstflag fields of the
> returned "struct timeb" will always be zero.
> 
> Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
> powerpc64-linux-gnu, and powerpc-linux-gnu.
> 
> Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
>  NEWS                            |  3 +++
>  sysdeps/unix/bsd/ftime.c        | 40
> --------------------------------- sysdeps/unix/sysv/linux/ftime.c |
> 3 --- time/ftime.c                    | 26 ++++++++-------------
>  time/sys/timeb.h                |  3 ++-
>  time/tst-ftime.c                |  7 ++++++
>  6 files changed, 21 insertions(+), 61 deletions(-)
>  delete mode 100644 sysdeps/unix/bsd/ftime.c
>  delete mode 100644 sysdeps/unix/sysv/linux/ftime.c
> 
> diff --git a/NEWS b/NEWS
> index 0b1476e745..6d109f84f0 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -58,6 +58,9 @@ Deprecated and removed features, and other changes
> affecting compatibility: settimeofday available to newly linked
> binaries after there is a replacement for Linux’s time-zone-like
> offset API. 
> +* The obsolete functions ftime has been deprecated and will be
> removed from
> +  a future version of glibc.  Application should use clock_gettime
> instead. +
>  Changes to build and runtime requirements:
>  
>    [Add changes to build and runtime requirements here]
> diff --git a/sysdeps/unix/bsd/ftime.c b/sysdeps/unix/bsd/ftime.c
> deleted file mode 100644
> index e1f20bc609..0000000000
> --- a/sysdeps/unix/bsd/ftime.c
> +++ /dev/null
> @@ -1,40 +0,0 @@
> -/* Copyright (C) 1994-2019 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be
> useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#include <sys/timeb.h>
> -#include <sys/time.h>
> -
> -int
> -ftime (struct timeb *timebuf)
> -{
> -  struct timeval tv;
> -  struct timezone tz;
> -
> -  if (__gettimeofday (&tv, &tz) < 0)
> -    return -1;
> -
> -  timebuf->time = tv.tv_sec;
> -  timebuf->millitm = (tv.tv_usec + 500) / 1000;
> -  if (timebuf->millitm == 1000)
> -    {
> -      ++timebuf->time;
> -      timebuf->millitm = 0;
> -    }
> -  timebuf->timezone = tz.tz_minuteswest;
> -  timebuf->dstflag = tz.tz_dsttime;
> -  return 0;
> -}
> diff --git a/sysdeps/unix/sysv/linux/ftime.c
> b/sysdeps/unix/sysv/linux/ftime.c deleted file mode 100644
> index 5a5949f608..0000000000
> --- a/sysdeps/unix/sysv/linux/ftime.c
> +++ /dev/null
> @@ -1,3 +0,0 @@
> -/* Linux defines the ftime system call but doesn't actually implement
> -   it.  Use the BSD implementation.  */
> -#include <sysdeps/unix/bsd/ftime.c>
> diff --git a/time/ftime.c b/time/ftime.c
> index 8bedc0d91e..b4bd58ecef 100644
> --- a/time/ftime.c
> +++ b/time/ftime.c
> @@ -1,4 +1,5 @@
> -/* Copyright (C) 1994-2019 Free Software Foundation, Inc.
> +/* Deprecated return date and time.
> +   Copyright (C) 1994-2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>  
>     The GNU C Library is free software; you can redistribute it and/or
> @@ -15,27 +16,18 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#include <errno.h>
> -#include <time.h>
>  #include <sys/timeb.h>
> +#include <time.h>
>  
>  int
>  ftime (struct timeb *timebuf)
>  {
> -  int save = errno;
> -  struct tm tp;
> -
> -  __set_errno (0);
> -  if (time (&timebuf->time) == (time_t) -1 && errno != 0)
> -    return -1;
> -  timebuf->millitm = 0;
> -
> -  if (__localtime_r (&timebuf->time, &tp) == NULL)
> -    return -1;
> -
> -  timebuf->timezone = tp.tm_gmtoff / 60;
> -  timebuf->dstflag = tp.tm_isdst;
> +  struct timespec ts;
> +  __clock_gettime (CLOCK_REALTIME, &ts);
>  
> -  __set_errno (save);
> +  timebuf->time = ts.tv_sec;
> +  timebuf->millitm = ts.tv_nsec / 1000000;
> +  timebuf->timezone = 0;
> +  timebuf->dstflag = 0;
>    return 0;
>  }
> diff --git a/time/sys/timeb.h b/time/sys/timeb.h
> index b958dc3e4a..5c16f79da2 100644
> --- a/time/sys/timeb.h
> +++ b/time/sys/timeb.h
> @@ -36,7 +36,8 @@ struct timeb
>  
>  /* Fill in TIMEBUF with information about the current time.  */
>  
> -extern int ftime (struct timeb *__timebuf);
> +extern int ftime (struct timeb *__timebuf)
> +  __nonnull ((1)) __attribute_deprecated__;
>  
>  __END_DECLS
>  
> diff --git a/time/tst-ftime.c b/time/tst-ftime.c
> index 4b7e90cc03..39d94a1b26 100644
> --- a/time/tst-ftime.c
> +++ b/time/tst-ftime.c
> @@ -18,6 +18,7 @@
>  
>  #include <sys/timeb.h>
>  #include <stdio.h>
> +#include <libc-diag.h>
>  
>  static int
>  do_test (void)
> @@ -29,12 +30,18 @@ do_test (void)
>      {
>        prev = curr;
>  
> +      /* ftime was deprecated on 2.31.  */
> +      DIAG_PUSH_NEEDS_COMMENT;
> +      DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
> +
>        if (ftime (&curr))
>          {
>            printf ("ftime returned an error\n");
>            return 1;
>          }
>  
> +      DIAG_POP_NEEDS_COMMENT;
> +
>        if (curr.time < prev.time)
>          {
>            printf ("ftime's time flowed backwards\n");

Reviewed-by: Lukasz Majewski <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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 08/11] Use clock_gettime to implement timespec_get.
  2019-10-25 12:09 ` [PATCH v2 08/11] Use clock_gettime to implement timespec_get Adhemerval Zanella
@ 2019-10-28 13:30   ` Lukasz Majewski
  0 siblings, 0 replies; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-28 13:30 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Zack Weinberg

[-- Attachment #1: Type: text/plain, Size: 5564 bytes --]

Hi Adhemerval,

> From: Zack Weinberg <zackw@panix.com>
> 
> Use clock_gettime to implement timespec_get.
> 
> Changes from previous version:
> 
>   - Change commit message remove the rationale to not promote it.
> 
> --
> 
> timespec_get is the same function as clock_gettime, with an obnoxious
> coating of NIH painted on it by the ISO C committee.  In addition to
> the rename, it takes its arguments in a different order, it returns 0
> on *failure* or a positive number on *success*, and it requires that
> all of its TIME_* constants be positive.  This last means we cannot
> directly reuse the existing CLOCK_* constants for it, because
> those have been allocated starting with CLOCK_REALTIME = 0 on all
> existing platforms.
> 
> This patch simply promotes the sysdeps/posix implementation to
> universal, and removes the Linux-specific implementation, whose
> apparent reason for existing was to cut out one function call's worth
> of overhead.
> 
> Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
> powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.
> ---
>  sysdeps/posix/timespec_get.c           | 32 ------------------
>  sysdeps/unix/sysv/linux/timespec_get.c | 46
> -------------------------- time/timespec_get.c                    |
> 14 +++----- 3 files changed, 4 insertions(+), 88 deletions(-)
>  delete mode 100644 sysdeps/posix/timespec_get.c
>  delete mode 100644 sysdeps/unix/sysv/linux/timespec_get.c
> 
> diff --git a/sysdeps/posix/timespec_get.c
> b/sysdeps/posix/timespec_get.c deleted file mode 100644
> index e3146da2d3..0000000000
> --- a/sysdeps/posix/timespec_get.c
> +++ /dev/null
> @@ -1,32 +0,0 @@
> -/* timespec_get -- C11 interface to sample a clock.  Generic POSIX.1
> version.
> -   Copyright (C) 2013-2019 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be
> useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#include <time.h>
> -
> -
> -/* Set TS to calendar time based in time base BASE.  */
> -int
> -timespec_get (struct timespec *ts, int base)
> -{
> -  if (base == TIME_UTC)
> -    {
> -      __clock_gettime (CLOCK_REALTIME, ts);
> -      return base;
> -    }
> -  return 0;
> -}
> diff --git a/sysdeps/unix/sysv/linux/timespec_get.c
> b/sysdeps/unix/sysv/linux/timespec_get.c deleted file mode 100644
> index 629827d0f9..0000000000
> --- a/sysdeps/unix/sysv/linux/timespec_get.c
> +++ /dev/null
> @@ -1,46 +0,0 @@
> -/* Copyright (C) 2011-2019 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License.
> -
> -   The GNU C Library is distributed in the hope that it will be
> useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#include <time.h>
> -#include <sysdep.h>
> -#include <errno.h>
> -
> -#ifdef HAVE_CLOCK_GETTIME_VSYSCALL
> -# define HAVE_VSYSCALL
> -#endif
> -#include <sysdep-vdso.h>
> -
> -/* Set TS to calendar time based in time base BASE.  */
> -int
> -timespec_get (struct timespec *ts, int base)
> -{
> -  switch (base)
> -    {
> -      int res;
> -      INTERNAL_SYSCALL_DECL (err);
> -    case TIME_UTC:
> -      res = INTERNAL_VSYSCALL (clock_gettime, err, 2,
> CLOCK_REALTIME, ts);
> -      if (INTERNAL_SYSCALL_ERROR_P (res, err))
> -	return 0;
> -      break;
> -
> -    default:
> -      return 0;
> -    }
> -
> -  return base;
> -}
> diff --git a/time/timespec_get.c b/time/timespec_get.c
> index cef9a4263c..5124c747c2 100644
> --- a/time/timespec_get.c
> +++ b/time/timespec_get.c
> @@ -22,16 +22,10 @@
>  int
>  timespec_get (struct timespec *ts, int base)
>  {
> -  switch (base)
> +  if (base == TIME_UTC)
>      {
> -    case TIME_UTC:
> -      /* Not supported.  */
> -      return 0;
> -
> -    default:
> -      return 0;
> +      __clock_gettime (CLOCK_REALTIME, ts);
> +      return base;
>      }
> -
> -  return base;
> +  return 0;
>  }
> -stub_warning (timespec_get)

Reviewed-by: Lukasz Majewski <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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 09/11] Use clock_gettime to implement gettimeofday.
  2019-10-25 12:09 ` [PATCH v2 09/11] Use clock_gettime to implement gettimeofday Adhemerval Zanella
@ 2019-10-28 14:16   ` Lukasz Majewski
  2019-10-28 18:01     ` Joseph Myers
  0 siblings, 1 reply; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-28 14:16 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 27125 bytes --]

Hi Adhemerval,

> Use clock_gettime to implement gettimeofday
> 
> Changes from previous version:
> 
>   - Do not remove Linux arch-specific implementations.
> 
> --
> 
> Consolidate generic gettimeofday implementation to use clock_gettime.
> Linux ports that still provide gettimeofday through vDSO are not
> changed.
> 
> Remove sysdeps/unix/clock_gettime.c, which implemented clock_gettime
> using gettimeofday; new OS ports must provide a real implementation of
> clock_gettime.
> 
> Rename sysdeps/mach/gettimeofday.c to sysdeps/mach/clock_gettime.c and
> convert into an implementation of clock_gettime.  It only supports
> CLOCK_REALTIME; Mach does not appear to have any support for monotonic
> clocks.  It uses __host_get_time, which provides at best microsecond
> resolution.  Hurd is currently using sysdeps/posix/clock_getres.c for
> clock_getres; its output for CLOCK_REALTIME is based on
> sysconf (_SC_CLK_TCK), and I do not know whether that gives the
> correct result.
> 
> Unlike settimeofday, there are no known uses of gettimeofday's
> vestigial "get time zone" feature that are not bugs.  (The per-process
> timezone support in localtime and friends is unrelated, and the
> programs that set the kernel's offset between the hardware clock and
> UTC do not need to read it back.)  Therefore, this feature is dummied
> out.  Henceforth, if gettimeofday's "struct timezone" argument is not
> NULL, it will write zeroes to both fields.  Any program that is
> actually looking at this data will thus think it is running in UTC,
> which is probably more correct than whatever it was doing before.
> 
> [__]gettimeofday no longer has any internal callers, so we can now
> remove its internal prototype and PLT bypass aliases.  The
> __gettimeofday@GLIBC_2.0 export remains, in case it is used by any
> third-party code.
> 
> It also allows to simplify the arch-specific implementation on x86 and
> powerpc to remove the hack to disable the internal route to non iFUNC
> variant for internal symbol.
> 
> This patch also fixes a missing optimization on aarch64, powerpc, and
> x86 where the code used on static build do not use the vDSO.
> 
> Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
> powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.
> 
> Co-authored-by: Zack Weinberg <zackw@panix.com>
> ---
>  NEWS                                          | 15 ++++
>  include/sys/time.h                            |  2 -
>  sysdeps/{unix => mach}/clock_gettime.c        | 37 +++++-----
>  sysdeps/mach/gettimeofday.c                   | 43 ------------
>  sysdeps/posix/gettimeofday.c                  | 67 ------------------
>  sysdeps/unix/syscalls.list                    |  1 -
>  .../unix/sysv/linux/aarch64/gettimeofday.c    | 34 ++++-----
>  .../sysv/linux/{i386 => alpha}/gettimeofday.c | 25 ++-----
>  .../unix/sysv/linux/alpha/osf_gettimeofday.c  | 11 ++-
>  sysdeps/unix/sysv/linux/gettimeofday.c        | 49 -------------
>  .../unix/sysv/linux/powerpc/gettimeofday.c    | 69
> +++++-------------- sysdeps/unix/sysv/linux/x86/gettimeofday.c    |
> 43 +++++------- .../unix/sysv/linux/x86_64/x32/gettimeofday.c |  1 +
>  .../unix/sysv/linux/x86_64/x32/syscalls.list  |  1 -
>  time/gettimeofday.c                           | 32 ++++++---
>  15 files changed, 121 insertions(+), 309 deletions(-)
>  rename sysdeps/{unix => mach}/clock_gettime.c (65%)
>  delete mode 100644 sysdeps/mach/gettimeofday.c
>  delete mode 100644 sysdeps/posix/gettimeofday.c
>  rename sysdeps/unix/sysv/linux/{i386 => alpha}/gettimeofday.c (58%)
>  delete mode 100644 sysdeps/unix/sysv/linux/gettimeofday.c
>  create mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c
> 
> diff --git a/NEWS b/NEWS
> index 6d109f84f0..12d6af2fc0 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -21,6 +21,21 @@ Major new features:
>    18661-1:2014 and TS 18661-3:2015 as amended by the resolution of
>    Clarification Request 13 to TS 18661-3.
>  
> +* The gettimeofday function will no longer report information about a
> +  system-wide time zone, expect for aarch64, powerpc, and x86 on
> Linux
> +  which still uses the vDSO symbol (when available).
> +
> +  This 4.2-BSD-era feature has been deprecated for many years, as it
> cannot
> +  handle the full complexity of the world’s timezones, but hitherto
> we have
> +  supported it on a best-effort basis.  Changes required to support
> 64-bit
> +  time_t on 32-bit architectures have made this no longer practical.
> +
> +  As of this release, callers of gettimeofday with a non-null ‘tzp’
> argument
> +  will always receive a ‘struct timezone’ whose tz_minuteswest and
> +  tz_dsttime fields are zero.  We have also arranged for call sites
> that
> +  pass a non-null ‘tzp’ argument to gettimeofday to receive
> compile-time
> +  warnings, if the compiler makes this possible.
> +
>  Deprecated and removed features, and other changes affecting
> compatibility: 
>  * The totalorder and totalordermag functions, and the corresponding
> diff --git a/include/sys/time.h b/include/sys/time.h
> index c0e30e70fb..2bf4297e76 100644
> --- a/include/sys/time.h
> +++ b/include/sys/time.h
> @@ -22,8 +22,6 @@
>  # ifndef _ISOMAC
>  extern int __gettimeofday (struct timeval *__tv,
>  			   struct timezone *__tz);
> -libc_hidden_proto (__gettimeofday)
> -libc_hidden_proto (gettimeofday)
>  extern int __settimezone (const struct timezone *__tz)
>  	attribute_hidden;
>  extern int __adjtime (const struct timeval *__delta,
> diff --git a/sysdeps/unix/clock_gettime.c
> b/sysdeps/mach/clock_gettime.c similarity index 65%
> rename from sysdeps/unix/clock_gettime.c
> rename to sysdeps/mach/clock_gettime.c
> index aa74e11703..0f872e5a45 100644
> --- a/sysdeps/unix/clock_gettime.c
> +++ b/sysdeps/mach/clock_gettime.c
> @@ -1,5 +1,4 @@
> -/* clock_gettime -- Get the current time from a POSIX clockid_t.
> Unix version.
> -   Copyright (C) 1999-2019 Free Software Foundation, Inc.
> +/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>  
>     The GNU C Library is free software; you can redistribute it and/or
> @@ -18,32 +17,28 @@
>  
>  #include <errno.h>
>  #include <time.h>
> -#include <sys/time.h>
> +#include <mach.h>
>  #include <shlib-compat.h>
>  
> -/* Get current value of CLOCK and store it in TP.  */
> +/* Get the current time of day, putting it into *TS.
> +   Returns 0 on success, -1 on errors.  */
>  int
> -__clock_gettime (clockid_t clock_id, struct timespec *tp)
> +__clock_gettime (clockid_t clock_id, struct timespec *ts)
>  {
> -  int retval = -1;
> -
> -  switch (clock_id)
> +  if (clock_id != CLOCK_REALTIME)
>      {
> -    case CLOCK_REALTIME:
> -      {
> -	struct timeval tv;
> -	retval = __gettimeofday (&tv, NULL);
> -	if (retval == 0)
> -	  TIMEVAL_TO_TIMESPEC (&tv, tp);
> -      }
> -      break;
> -
> -    default:
> -      __set_errno (EINVAL);
> -      break;
> +      errno = EINVAL;
> +      return -1;
>      }
>  
> -  return retval;
> +  /* __host_get_time can only fail if passed an invalid host_t.
> +     __mach_host_self could theoretically fail (producing an
> +     invalid host_t) due to resource exhaustion, but we assume
> +     this will never happen.  */
> +  time_value_t tv;
> +  __host_get_time (__mach_host_self (), &tv);
> +  TIME_VALUE_TO_TIMESPEC (&tv, ts);
> +  return 0;
>  }
>  libc_hidden_def (__clock_gettime)
>  
> diff --git a/sysdeps/mach/gettimeofday.c b/sysdeps/mach/gettimeofday.c
> deleted file mode 100644
> index f6df00306b..0000000000
> --- a/sysdeps/mach/gettimeofday.c
> +++ /dev/null
> @@ -1,43 +0,0 @@
> -/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be
> useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <stddef.h>
> -#include <sys/time.h>
> -#include <mach.h>
> -
> -/* Get the current time of day and timezone information,
> -   putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.
> -   Returns 0 on success, -1 on errors.  */
> -int
> -__gettimeofday (struct timeval *tv, struct timezone *tz)
> -{
> -  kern_return_t err;
> -
> -  if (tz != NULL)
> -    *tz = (struct timezone){0, 0}; /* XXX */
> -
> -  if (err = __host_get_time (__mach_host_self (), (time_value_t *)
> tv))
> -    {
> -      errno = err;
> -      return -1;
> -    }
> -  return 0;
> -}
> -libc_hidden_def (__gettimeofday)
> -weak_alias (__gettimeofday, gettimeofday)
> -libc_hidden_weak (gettimeofday)
> diff --git a/sysdeps/posix/gettimeofday.c
> b/sysdeps/posix/gettimeofday.c deleted file mode 100644
> index 6bb98cd018..0000000000
> --- a/sysdeps/posix/gettimeofday.c
> +++ /dev/null
> @@ -1,67 +0,0 @@
> -/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be
> useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <time.h>
> -#include <sys/time.h>
> -
> -/* Get the current time of day and timezone information,
> -   putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.
> -   Returns 0 on success, -1 on errors.  */
> -int
> -__gettimeofday (struct timeval *tv, struct timezone *tz)
> -{
> -  if (tv == NULL)
> -    {
> -      __set_errno (EINVAL);
> -      return -1;
> -    }
> -
> -  tv->tv_sec = (long int) time ((time_t *) NULL);
> -  tv->tv_usec = 0L;
> -
> -  if (tz != NULL)
> -    {
> -      const time_t timer = tv->tv_sec;
> -      struct tm tm;
> -      const struct tm *tmp;
> -
> -      const long int save_timezone = __timezone;
> -      const long int save_daylight = __daylight;
> -      char *save_tzname[2];
> -      save_tzname[0] = __tzname[0];
> -      save_tzname[1] = __tzname[1];
> -
> -      tmp = localtime_r (&timer, &tm);
> -
> -      tz->tz_minuteswest = __timezone / 60;
> -      tz->tz_dsttime = __daylight;
> -
> -      __timezone = save_timezone;
> -      __daylight = save_daylight;
> -      __tzname[0] = save_tzname[0];
> -      __tzname[1] = save_tzname[1];
> -
> -      if (tmp == NULL)
> -	return -1;
> -    }
> -
> -  return 0;
> -}
> -libc_hidden_def (__gettimeofday)
> -weak_alias (__gettimeofday, gettimeofday)
> -libc_hidden_weak (gettimeofday)
> diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list
> index 5fedd5733d..e28e801c7a 100644
> --- a/sysdeps/unix/syscalls.list
> +++ b/sysdeps/unix/syscalls.list
> @@ -33,7 +33,6 @@ getrlimit	-	getrlimit
> i:ip	__getrlimit	getrlimit getrusage	-
> getrusage	i:ip	__getrusage	getrusage
> getsockname	-	getsockname	i:ibN
> __getsockname	getsockname getsockopt	-
> getsockopt	i:iiiBN	getsockopt -gettimeofday
> -	gettimeofday	i:pP	__gettimeofday
> gettimeofday getuid		-	getuid
> Ei:	__getuid	getuid ioctl		-
> ioctl		i:iiI	__ioctl		ioctl
> kill		-	kill		i:ii
> __kill		kill diff --git
> a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
> b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c index
> 4ff74fa285..075af3d0d3 100644 ---
> a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c +++
> b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c @@ -20,39 +20,39 @@
> putting it into *tv and *tz.  If tz is null, *tz is not filled.
> Returns 0 on success, -1 on errors.  */ -#include <sys/time.h>
> +#include <time.h> +#include <sysdep.h> 
> -#ifdef SHARED
> -
> -# include <dl-vdso.h>
> -# include <sysdep-vdso.h>
> +#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
> +# define HAVE_VSYSCALL
> +#endif
> +#include <sysdep-vdso.h>
>  
>  /* Used as a fallback in the ifunc resolver if VDSO is not available
>     and for libc.so internal __gettimeofday calls.  */
> -
>  static int
>  __gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
>  {
> +  if (__glibc_unlikely (tz != 0))
> +    memset (tz, 0, sizeof *tz);
> +
>    return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
>  }
>  
> +#ifdef SHARED
> +# include <dl-vdso.h>
> +# include <sysdep-vdso.h>
> +
>  # define INIT_ARCH()
> -libc_ifunc_hidden (__gettimeofday, __gettimeofday,
> -		   (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
> -		    ?: __gettimeofday_vsyscall))
> -libc_hidden_def (__gettimeofday)
> +libc_ifunc (__gettimeofday,
> +	    (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
> +	    ?: __gettimeofday_vsyscall))
>  
>  #else
> -
> -# include <sysdep.h>
>  int
>  __gettimeofday (struct timeval *tv, struct timezone *tz)
>  {
> -  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> +  return __gettimeofday_vsyscall (tv, tz);
>  }
> -libc_hidden_def (__gettimeofday)
> -
>  #endif
> -
>  weak_alias (__gettimeofday, gettimeofday)
> -libc_hidden_weak (gettimeofday)
> diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c
> b/sysdeps/unix/sysv/linux/alpha/gettimeofday.c similarity index 58%
> rename from sysdeps/unix/sysv/linux/i386/gettimeofday.c
> rename to sysdeps/unix/sysv/linux/alpha/gettimeofday.c
> index f6faecb21e..262a3c2352 100644
> --- a/sysdeps/unix/sysv/linux/i386/gettimeofday.c
> +++ b/sysdeps/unix/sysv/linux/alpha/gettimeofday.c
> @@ -1,5 +1,5 @@
> -/* gettimeofday - get the time.  Linux/i386 version.
> -   Copyright (C) 2015-2019 Free Software Foundation, Inc.
> +/* gettimeofday -- Get the current time of day.  Linux/Alpha/tv64
> version.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>  
>     The GNU C Library is free software; you can redistribute it and/or
> @@ -16,20 +16,7 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#ifdef SHARED
> -# define __gettimeofday __redirect___gettimeofday
> -#endif
> -
> -#include <sys/time.h>
> -
> -#ifdef SHARED
> -# undef __gettimeofday
> -# define __gettimeofday_type __redirect___gettimeofday
> -
> -# undef libc_hidden_def
> -# define libc_hidden_def(name) \
> -  __hidden_ver1 (__gettimeofday_syscall, __GI___gettimeofday, \
> -	       __gettimeofday_syscall);
> -#endif
> -
> -#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
> +/* We can use the generic implementation, but we have to override its
> +   default symbol version.  */
> +#define VERSION_gettimeofday GLIBC_2.1
> +#include <time/gettimeofday.c>
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
> b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c index
> e6cc522dd1..f602d8dcf9 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c +++
> b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c @@ -20,6 +20,8 @@
>  
>  #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
>  
> +#include <string.h>
> +#include <time.h>
>  #include <sys/time.h>
>  #include <tv32-compat.h>
>  
> @@ -30,10 +32,13 @@ int
>  attribute_compat_text_section
>  __gettimeofday_tv32 (struct timeval32 *restrict tv32, void *restrict
> tz) {
> -  struct timeval tv;
> -  __gettimeofday (&tv, tz);
> +  if (__glibc_unlikely (tz != 0))
> +    memset (tz, 0, sizeof (struct timezone));
>  
> -  tv64_to_tv32 (tv32, &tv);
> +  struct timespec ts;
> +  __clock_gettime (CLOCK_REALTIME, &ts);
> +
> +  ts64_to_tv32 (tv32, &ts);

IMHO, this shall be replaced with valid_* functions from include/time.h

>    return 0;
>  }
>  
> diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c
> b/sysdeps/unix/sysv/linux/gettimeofday.c deleted file mode 100644
> index c9597d6405..0000000000
> --- a/sysdeps/unix/sysv/linux/gettimeofday.c
> +++ /dev/null
> @@ -1,49 +0,0 @@
> -/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
> -
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> License as
> -   published by the Free Software Foundation; either version 2.1 of
> the
> -   License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be
> useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <sys/time.h>
> -
> -#undef __gettimeofday
> -
> -#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
> -# define HAVE_VSYSCALL
> -#endif
> -#include <sysdep-vdso.h>
> -
> -/* Get the current time of day and timezone information,
> -   putting it into *tv and *tz.  If tz is null, *tz is not filled.
> -   Returns 0 on success, -1 on errors.  */
> -int
> -___gettimeofday (struct timeval *tv, struct timezone *tz)
> -{
> -  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
> -}
> -
> -#ifdef VERSION_gettimeofday
> -weak_alias (___gettimeofday, __wgettimeofday);
> -default_symbol_version (___gettimeofday, __gettimeofday,
> VERSION_gettimeofday); -default_symbol_version (__wgettimeofday,
> gettimeofday, VERSION_gettimeofday); -libc_hidden_ver
> (___gettimeofday, __gettimeofday); -libc_hidden_ver (___gettimeofday,
> gettimeofday); -#else
> -strong_alias (___gettimeofday, __gettimeofday)
> -weak_alias (___gettimeofday, gettimeofday)
> -libc_hidden_def (__gettimeofday)
> -libc_hidden_weak (gettimeofday)
> -#endif
> diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
> b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c index
> 13a1fd292a..02486dee3a 100644 ---
> a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c +++
> b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c @@ -15,71 +15,40 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#if defined SHARED && !defined __powerpc64__
> -# define __gettimeofday __redirect___gettimeofday
> -#else
> -# define __redirect___gettimeofday __gettimeofday
> -#endif
> -
> -#include <sys/time.h>
> -
> -#ifdef SHARED
> -
> -# include <dl-vdso.h>
> -# include <libc-vdso.h>
> -# include <dl-machine.h>
> -# include <sysdep.h>
> -
> -# ifndef __powerpc64__
> -#  undef __gettimeofday
> -
> -int
> -__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
> -{
> -  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
> -}
> -
> -/* __GI___gettimeofday is defined as hidden and for ppc32 it enables
> the
> -   compiler make a local call (symbol@local) for internal GLIBC
> usage. It
> -   means the PLT won't be used and the ifunc resolver will be called
> directly.
> -   For ppc64 a call to a function in another translation unit might
> use a
> -   different toc pointer thus disallowing direct branchess and
> making internal
> -   ifuncs calls safe.  */
> -#  undef libc_hidden_def
> -#  define libc_hidden_def(name)
> 	\
> -  __hidden_ver1 (__gettimeofday_vsyscall,
> __GI___gettimeofday,	\
> -	       __gettimeofday_vsyscall);
> +#include <time.h>
> +#include <sysdep.h>
>  
> -# endif /* !__powerpc64__  */
> +#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
> +# define HAVE_VSYSCALL
> +#endif
> +#include <sysdep-vdso.h>
>  
>  static int
>  __gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
>  {
> -  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> +  if (__glibc_unlikely (tz != 0))
> +    memset (tz, 0, sizeof *tz);
> +
> +  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
>  }
>  
> +#ifdef SHARED
> +# include <dl-vdso.h>
> +# include <libc-vdso.h>
> +
>  # define INIT_ARCH() \
>    void *vdso_gettimeofday = get_vdso_symbol
> (HAVE_GETTIMEOFDAY_VSYSCALL) 
>  /* If the vDSO is not available we fall back syscall.  */
> -libc_ifunc_hidden (__redirect___gettimeofday, __gettimeofday,
> -		   vdso_gettimeofday
> -		   ? VDSO_IFUNC_RET (vdso_gettimeofday)
> -		   : (void *) __gettimeofday_syscall);
> -libc_hidden_def (__gettimeofday)
> -
> +libc_ifunc (__gettimeofday,
> +	    vdso_gettimeofday
> +	    ? VDSO_IFUNC_RET (vdso_gettimeofday)
> +	    : (void *) __gettimeofday_syscall);
>  #else
> -
> -# include <sysdep.h>
> -# include <errno.h>
> -
>  int
>  __gettimeofday (struct timeval *tv, struct timezone *tz)
>  {
> -  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> +  return __gettimeofday_syscall (tv, tz);
>  }
> -libc_hidden_def (__gettimeofday)
> -
>  #endif
>  weak_alias (__gettimeofday, gettimeofday)
> -libc_hidden_weak (gettimeofday)
> diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
> b/sysdeps/unix/sysv/linux/x86/gettimeofday.c index
> 2d9248ee26..cb20e358d8 100644 ---
> a/sysdeps/unix/sysv/linux/x86/gettimeofday.c +++
> b/sysdeps/unix/sysv/linux/x86/gettimeofday.c @@ -16,47 +16,38 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#include <sys/time.h>
> +#include <time.h>
> +#include <sysdep.h>
>  
> -#ifdef SHARED
> -
> -# include <dl-vdso.h>
> -# include <errno.h>
> -# include <sysdep-vdso.h>
> -# include <sysdep-vdso.h>
> +#ifdef HAVE_GETTIMEOFDAY_VSYSCALL
> +# define HAVE_VSYSCALL
> +#endif
> +#include <sysdep-vdso.h>
>  
>  static int
>  __gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
>  {
> -  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> +  if (__glibc_unlikely (tz != 0))
> +    memset (tz, 0, sizeof *tz);
> +
> +  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
>  }
>  
> -# ifndef __gettimeofday_type
> -/* The i386 gettimeofday.c includes this file with a defined
> -   __gettimeofday_type macro.  For x86_64 we have to define it to
> __gettimeofday
> -   as the internal symbol is the ifunc'ed one.  */
> -#  define __gettimeofday_type __gettimeofday
> -# endif
> +#ifdef SHARED
> +# include <dl-vdso.h>
> +# include <libc-vdso.h>
>  
>  # define INIT_ARCH()
>  /* If the vDSO is not available we fall back to syscall.  */
> -libc_ifunc_hidden (__gettimeofday_type, __gettimeofday,
> -		   (get_vdso_symbol ("__vdso_gettimeofday")
> -		    ?: __gettimeofday_syscall));
> -libc_hidden_def (__gettimeofday)
> +libc_ifunc (__gettimeofday,
> +	    (get_vdso_symbol (HAVE_GETTIMEOFDAY_VSYSCALL)
> +	    ?: __gettimeofday_syscall));
>  
>  #else
> -
> -# include <sysdep.h>
> -# include <errno.h>
> -
>  int
>  __gettimeofday (struct timeval *tv, struct timezone *tz)
>  {
> -  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> +  return __gettimeofday_syscall (tv, tz);
>  }
> -libc_hidden_def (__gettimeofday)
> -
>  #endif
>  weak_alias (__gettimeofday, gettimeofday)
> -libc_hidden_weak (gettimeofday)
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c
> b/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c new file mode
> 100644 index 0000000000..cd342f33ad
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/gettimeofday.c
> @@ -0,0 +1 @@
> +#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
> b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list index
> b44f6f99e9..786c884232 100644 ---
> a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list +++
> b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list @@ -1,6 +1,5 @@
>  # File name	Caller	Syscall name	# args
> Strong name	Weak names 
> -gettimeofday	-
> gettimeofday:__vdso_gettimeofday@LINUX_2.6	i:pP
> __gettimeofday	gettimeofday personality	EXTRA
> personality	Ei:i	__personality	personality
> posix_fadvise64	-	fadvise64	Vi:iiii
> posix_fadvise	posix_fadvise64 time		-
> time:__vdso_time@LINUX_2.6			Ei:P	time
> diff --git a/time/gettimeofday.c b/time/gettimeofday.c index
> 1fd2669abd..e8055b397d 100644 --- a/time/gettimeofday.c +++
> b/time/gettimeofday.c @@ -15,20 +15,32 @@ License along with the GNU
> C Library; if not, see <https://www.gnu.org/licenses/>.  */
>  
> -#include <errno.h>
> +#include <string.h>
> +#include <time.h>
>  #include <sys/time.h>
>  
> -/* Get the current time of day and timezone information,
> -   putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.
> +/* Get the current time of day, putting it into *TV.
> +   If *TZ is not NULL, clear it.
>     Returns 0 on success, -1 on errors.  */
>  int
> -__gettimeofday (struct timeval *tv, struct timezone *tz)
> +___gettimeofday (struct timeval *tv, struct timezone *tz)
>  {
> -  __set_errno (ENOSYS);
> -  return -1;
> +  if (__glibc_unlikely (tz != 0))
> +    memset (tz, 0, sizeof *tz);
> +
> +  struct timespec ts;
> +  if (__clock_gettime (CLOCK_REALTIME, &ts))
> +    return -1;
> +
> +  TIMESPEC_TO_TIMEVAL (tv, &ts);
> +  return 0;
>  }
> -libc_hidden_def (__gettimeofday)
> -weak_alias (__gettimeofday, gettimeofday)
> -libc_hidden_weak (gettimeofday)
>  
> -stub_warning (gettimeofday)
> +#ifdef VERSION_gettimeofday
> +weak_alias (___gettimeofday, __wgettimeofday);
> +default_symbol_version (___gettimeofday, __gettimeofday,
> VERSION_gettimeofday); +default_symbol_version (__wgettimeofday,
> gettimeofday, VERSION_gettimeofday); +#else
> +strong_alias (___gettimeofday, __gettimeofday)
> +weak_alias (___gettimeofday, gettimeofday)
> +#endif

Reviewed-by: Lukasz Majewski <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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 10/11] Make second argument of gettimeofday as 'void *'
  2019-10-25 12:09 ` [PATCH v2 10/11] Make second argument of gettimeofday as 'void *' Adhemerval Zanella
@ 2019-10-28 14:23   ` Lukasz Majewski
  0 siblings, 0 replies; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-28 14:23 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Zack Weinberg

[-- Attachment #1: Type: text/plain, Size: 6964 bytes --]

On Fri, 25 Oct 2019 09:08:31 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> From: Zack Weinberg <zackw@panix.com>
> 
> Changes from previous version:
> 
>   - Remove warning for use of gettimeofday with a non-null __tz
> argument, the conditionals of making this work without false-positive
> seems quite specific and fragile (gcc-only, optimized build,
> workaround for gcc bug).
> 
> --
> 
> Also make the public prototype of gettimeofday declare its second
> argument with type "void *" unconditionally, consistent with POSIX.
> 
> It is also consistent with POSIX.
> 
> Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
> powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu.
> 
> Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
>  include/sys/time.h                            |  2 +-
>  .../unix/sysv/linux/aarch64/gettimeofday.c    |  4 ++--
>  .../unix/sysv/linux/powerpc/gettimeofday.c    |  4 ++--
>  sysdeps/unix/sysv/linux/x86/gettimeofday.c    |  4 ++--
>  time/gettimeofday.c                           |  4 ++--
>  time/sys/time.h                               | 23
> ++++++++++--------- 6 files changed, 21 insertions(+), 20 deletions(-)
> 
> diff --git a/include/sys/time.h b/include/sys/time.h
> index 2bf4297e76..a461295c6a 100644
> --- a/include/sys/time.h
> +++ b/include/sys/time.h
> @@ -21,7 +21,7 @@
>  
>  # ifndef _ISOMAC
>  extern int __gettimeofday (struct timeval *__tv,
> -			   struct timezone *__tz);
> +			   void *__tz);
>  extern int __settimezone (const struct timezone *__tz)
>  	attribute_hidden;
>  extern int __adjtime (const struct timeval *__delta,
> diff --git a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
> b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c index
> 075af3d0d3..7e772e05ce 100644 ---
> a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c +++
> b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c @@ -31,7 +31,7 @@
>  /* Used as a fallback in the ifunc resolver if VDSO is not available
>     and for libc.so internal __gettimeofday calls.  */
>  static int
> -__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
> +__gettimeofday_vsyscall (struct timeval *restrict tv, void *restrict
> tz) {
>    if (__glibc_unlikely (tz != 0))
>      memset (tz, 0, sizeof *tz);
> @@ -50,7 +50,7 @@ libc_ifunc (__gettimeofday,
>  
>  #else
>  int
> -__gettimeofday (struct timeval *tv, struct timezone *tz)
> +__gettimeofday (struct timeval *restrict tv, void *restrict tz)
>  {
>    return __gettimeofday_vsyscall (tv, tz);
>  }
> diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
> b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c index
> 02486dee3a..18d8f7cb7a 100644 ---
> a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c +++
> b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c @@ -24,7 +24,7 @@
>  #include <sysdep-vdso.h>
>  
>  static int
> -__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
> +__gettimeofday_syscall (struct timeval *restrict tv, void *restrict
> tz) {
>    if (__glibc_unlikely (tz != 0))
>      memset (tz, 0, sizeof *tz);
> @@ -46,7 +46,7 @@ libc_ifunc (__gettimeofday,
>  	    : (void *) __gettimeofday_syscall);
>  #else
>  int
> -__gettimeofday (struct timeval *tv, struct timezone *tz)
> +__gettimeofday (struct timeval *restrict tv, void *restrict tz)
>  {
>    return __gettimeofday_syscall (tv, tz);
>  }
> diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
> b/sysdeps/unix/sysv/linux/x86/gettimeofday.c index
> cb20e358d8..190127d31e 100644 ---
> a/sysdeps/unix/sysv/linux/x86/gettimeofday.c +++
> b/sysdeps/unix/sysv/linux/x86/gettimeofday.c @@ -25,7 +25,7 @@
>  #include <sysdep-vdso.h>
>  
>  static int
> -__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
> +__gettimeofday_syscall (struct timeval *restrict tv, void *restrict
> tz) {
>    if (__glibc_unlikely (tz != 0))
>      memset (tz, 0, sizeof *tz);
> @@ -45,7 +45,7 @@ libc_ifunc (__gettimeofday,
>  
>  #else
>  int
> -__gettimeofday (struct timeval *tv, struct timezone *tz)
> +__gettimeofday (struct timeval *restrict tv, void *restrict tz)
>  {
>    return __gettimeofday_syscall (tv, tz);
>  }
> diff --git a/time/gettimeofday.c b/time/gettimeofday.c
> index e8055b397d..ddaf46f481 100644
> --- a/time/gettimeofday.c
> +++ b/time/gettimeofday.c
> @@ -23,10 +23,10 @@
>     If *TZ is not NULL, clear it.
>     Returns 0 on success, -1 on errors.  */
>  int
> -___gettimeofday (struct timeval *tv, struct timezone *tz)
> +___gettimeofday (struct timeval *restrict tv, void *restrict tz)
>  {
>    if (__glibc_unlikely (tz != 0))
> -    memset (tz, 0, sizeof *tz);
> +    memset (tz, 0, sizeof (struct timezone));
>  
>    struct timespec ts;
>    if (__clock_gettime (CLOCK_REALTIME, &ts))
> diff --git a/time/sys/time.h b/time/sys/time.h
> index f8c946f94e..0473dae339 100644
> --- a/time/sys/time.h
> +++ b/time/sys/time.h
> @@ -54,23 +54,24 @@ struct timezone
>      int tz_minuteswest;		/* Minutes west of GMT.  */
>      int tz_dsttime;		/* Nonzero if DST is ever in
> effect.  */ };
> -
> -typedef struct timezone *__restrict __timezone_ptr_t;
> -#else
> -typedef void *__restrict __timezone_ptr_t;
>  #endif
>  
> -/* Get the current time of day and timezone information,
> -   putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.
> -   Returns 0 on success, -1 on errors.
> -   NOTE: This form of timezone information is obsolete.
> -   Use the functions and variables declared in <time.h> instead.  */
> +/* Get the current time of day, putting it into *TV.
> +   If TZ is not null, *TZ must be a struct timezone, and both fields
> +   will be set to zero.
> +   Calling this function with a non-null TZ is obsolete;
> +   use localtime etc. instead.
> +   This function itself is semi-obsolete;
> +   most callers should use time or clock_gettime instead. */
>  extern int gettimeofday (struct timeval *__restrict __tv,
> -			 __timezone_ptr_t __tz) __THROW __nonnull
> ((1));
> +			 void *__restrict __tz) __THROW __nonnull
> ((1)); 
>  #ifdef __USE_MISC
>  /* Set the current time of day and timezone information.
> -   This call is restricted to the super-user.  */
> +   This call is restricted to the super-user.
> +   Setting the timezone in this way is obsolete, but we don't yet
> +   warn about it because it still has some uses for which there is
> +   no alternative.  */
>  extern int settimeofday (const struct timeval *__tv,
>  			 const struct timezone *__tz)
>       __THROW;

Reviewed-by: Lukasz Majewski <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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 09/11] Use clock_gettime to implement gettimeofday.
  2019-10-28 14:16   ` Lukasz Majewski
@ 2019-10-28 18:01     ` Joseph Myers
  2019-10-29  9:08       ` Lukasz Majewski
  0 siblings, 1 reply; 34+ messages in thread
From: Joseph Myers @ 2019-10-28 18:01 UTC (permalink / raw)
  To: Lukasz Majewski; +Cc: Adhemerval Zanella, libc-alpha

On Mon, 28 Oct 2019, Lukasz Majewski wrote:

> >  attribute_compat_text_section
> >  __gettimeofday_tv32 (struct timeval32 *restrict tv32, void *restrict
> > tz) {
> > -  struct timeval tv;
> > -  __gettimeofday (&tv, tz);
> > +  if (__glibc_unlikely (tz != 0))
> > +    memset (tz, 0, sizeof (struct timezone));
> >  
> > -  tv64_to_tv32 (tv32, &tv);
> > +  struct timespec ts;
> > +  __clock_gettime (CLOCK_REALTIME, &ts);
> > +
> > +  ts64_to_tv32 (tv32, &ts);
> 
> IMHO, this shall be replaced with valid_* functions from include/time.h

This is dealing with an alpha-specific timeval32 structure; I don't see 
how the functions in include/time.h are applicable.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls.
  2019-10-25 13:05   ` Lukasz Majewski
@ 2019-10-28 18:10     ` Adhemerval Zanella
  2019-10-29  9:11       ` Lukasz Majewski
  0 siblings, 1 reply; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-28 18:10 UTC (permalink / raw)
  To: Lukasz Majewski; +Cc: libc-alpha, Zack Weinberg


[-- Attachment #1.1: Type: text/plain, Size: 1644 bytes --]



On 25/10/2019 10:04, Lukasz Majewski wrote:
> Hi Adhemerval,
> 
> Thanks for re-sending those patches to ML. Please find some comments
> below.
> 
[...]
>> +/* Conversion functions.  If the seconds field of a timeval32 would
>> +   overflow, they write { INT32_MAX, TV_USEC_MAX } to the output.  */
>> +
>> +static inline void
>> +tv32_to_tv64 (struct timeval *restrict tv64,
>> +              const struct timeval32 *restrict tv32)
>> +{
>> +  tv64->tv_sec = tv32->tv_sec;
>> +  tv64->tv_usec = tv32->tv_usec;
>> +}
>> +
>> +static inline void
>> +tv32_to_ts64 (struct timespec *restrict ts64,
>> +              const struct timeval32 *restrict tv32)
>> +{
>> +  ts64->tv_sec = tv32->tv_sec;
>> +  ts64->tv_nsec = tv32->tv_usec * 1000;
>> +}
> 
> The ./include/time.h already provides such helper conversion function -
> valid_timeval_to_timespec64 ();
> 
> There are also defined:
> valid_timespec_to_timespec64 ();
> valid_timespec64_to_timespec ();
> valid_timespec64_to_timeval ();
> 
> There is also a different approach (as suggested some time ago by Paul)
> - those helper functions now return the converted structure and accept
>   value (not pointer) to convert.

They are not really the same since they use different types.  The timeval32
for alpha is not exported anymore, it just support the time64 types.  Alpha
is really an outlier and I don't think it really fits on the time64 
refactoring you are doing for 32-bit archs.  So I think we should really
add this arch-specific transformation function.

I changed the required routines to mimic the valid_* one on include/time.h.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls.
  2019-10-26  1:08   ` Alistair Francis
@ 2019-10-28 18:13     ` Adhemerval Zanella
  2019-10-29 10:30       ` Alistair Francis
  0 siblings, 1 reply; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-28 18:13 UTC (permalink / raw)
  To: Alistair Francis; +Cc: GNU C Library, Lukasz Majewski, Zack Weinberg



On 25/10/2019 22:08, Alistair Francis wrote:
> On Fri, Oct 25, 2019 at 5:09 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>> From: Zack Weinberg <zackw@panix.com>
>>
[...]
>> +
>> +#include <sys/timex.h>
>> +#include <sysdep.h>
>> +
>> +int
>> +___adjtimex (struct timex *buf)
>> +{
>> +  return INLINE_SYSCALL_CALL (adjtimex, buf);
> 
> The y2038 safe platforms don't have the adjtimex syscall, instead they
> have the clock_adjtime call. Can this fall back to clock_adjtime if
> __NR_adjtimex isn't defined?
> 
> Alistair
> 

This change is just a direct transformation from the definition at
syscalls.list (below) to a C implementation.

My plan to add *another* patch on this set to add the specific 
adjtimex refactor to make it call __clock_adjtime instead.

>> diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
>> index e374f97b5f..cdcf6c127b 100644
>> --- a/sysdeps/unix/sysv/linux/syscalls.list
>> +++ b/sysdeps/unix/sysv/linux/syscalls.list
>> @@ -1,6 +1,5 @@
>>  # File name    Caller  Syscall name    Args    Strong name     Weak names
>>
>> -adjtimex       adjtime adjtimex        i:p     __adjtimex      adjtimex ntp_adjtime
>>  alarm          -       alarm           i:i     alarm
>>  bdflush                EXTRA   bdflush         i:ii    __compat_bdflush        bdflush@GLIBC_2.0:GLIBC_2.23
>>  capget         EXTRA   capget          i:pp    capget
>> --
>> 2.17.1
>>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 04/11] Use clock_settime to implement settimeofday.
  2019-10-25 15:28   ` Lukasz Majewski
@ 2019-10-28 18:28     ` Adhemerval Zanella
  0 siblings, 0 replies; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-28 18:28 UTC (permalink / raw)
  To: Lukasz Majewski; +Cc: libc-alpha, Zack Weinberg


[-- Attachment #1.1: Type: text/plain, Size: 985 bytes --]



On 25/10/2019 12:28, Lukasz Majewski wrote:
> On Fri, 25 Oct 2019 09:08:25 -0300
> Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:
> 
>> From: Zack Weinberg <zackw@panix.com>
>>
[...]
>> fb2a36df19..914f5ac57b 100644 ---
>> a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c +++
>> b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c @@ -32,9 +32,19 @@
>> attribute_compat_text_section __settimeofday_tv32 (const struct
>> timeval32 *tv32, const struct timezone *tz) {
>> -  struct timeval tv;
>> -  tv32_to_tv64 (&tv, tv32);
>> -  return __settimeofday (&tv, tz);
>> +  if (__glibc_unlikely (tz != 0))
>> +    {
>> +      if (tv32 != 0)
>> +	{
>> +	  __set_errno (EINVAL);
>> +	  return -1;
>> +	}
>> +      return __settimezone (tz);
>> +    }
>> +
>> +  struct timespec ts;
>> +  tv32_to_ts64 (&ts, tv32);
> 
> This can be replaced with valid_timeval_to_timespec64() from
> include/time.h

Not really, the timeval32 is alpha-specific.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 04/11] Use clock_settime to implement settimeofday.
  2019-10-25 20:42   ` Alistair Francis
@ 2019-10-28 18:29     ` Adhemerval Zanella
  0 siblings, 0 replies; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-28 18:29 UTC (permalink / raw)
  To: Alistair Francis; +Cc: GNU C Library, Lukasz Majewski, Zack Weinberg



On 25/10/2019 17:42, Alistair Francis wrote:
> On Fri, Oct 25, 2019 at 5:09 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>> From: Zack Weinberg <zackw@panix.com>

[...]

>> +
>> +/* Set the system-wide timezone.
>> +   This call is restricted to the super-user.
>> +   This operation is considered obsolete, kernel support may not be
>> +   available on all architectures.  */
>> +int
>> +__settimezone (const struct timezone *tz)
>> +{
>> +#ifdef __NR_settimeofday
>> +  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
>> +#else
>> +  __set_errno (ENOSYS);
>> +  return -1
> 
> You are missing a semi-colon here.
> 
> Alistair

Ack, fixed.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 04/11] Use clock_settime to implement settimeofday.
  2019-10-25 23:34   ` Rafal Luzynski
@ 2019-10-28 18:46     ` Adhemerval Zanella
  0 siblings, 0 replies; 34+ messages in thread
From: Adhemerval Zanella @ 2019-10-28 18:46 UTC (permalink / raw)
  To: Rafal Luzynski, libc-alpha; +Cc: Lukasz Majewski, Zack Weinberg



On 25/10/2019 20:20, Rafal Luzynski wrote:
> 25.10.2019 14:08 Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:
>>
>>
>> From: Zack Weinberg <zackw@panix.com>
>>
>> Use clock_settime to implement settimeofday.
>>
>> Changes from previous version:
>>
>>   - Added a NEWS entry.
>>
>> --
>>
>> [...]
>> diff --git a/NEWS b/NEWS
>> index 8727b5e7f0..0b1476e745 100644
>> --- a/NEWS
>> +++ b/NEWS
>> @@ -34,6 +34,30 @@ Deprecated and removed features, and other changes
>> affecting compatibility:
>>    binaries and it has been removed from <time.h> header.  This function
>>    has been deprecated in favor of clock_settime.
>>  
>> +* The settimeofday function can still be used to set a system-wide time
>> +  zone when the operating system supports it.  This is because the Linux
>> +  kernel reused the API, on some architectures, to describe a system-wide
>> +  time-zone-like offset between the software clock maintained by the
>> kernel,
>> +  and the “RTC” clock that keeps time when the system is shut down.
> 
> That's little off-topic and little nit-picky but are you sure you want to
> use the Unicode quotes like “” instead of plain ASCII "" ?  No problem if
> this is what you really want but I suspect your editor converted this.

I think this came from the original patchset from Zack, I have split 
the last commit that added the NEWS entry for all the changes.
I changed to plan ASCII version.

> 
>> +  However, to reduce the odds of this offset being set by accident,
>> +  settimeofday can no longer be used to set the time and the offset
>> +  simultaneously.  If both of its two arguments are non-null, the call
>> +  will fail (setting errno to EINVAL).
>> +
>> +  Callers attempting to set this offset should also be prepared for the
>> call
>> +  to fail and set errno to ENOSYS; this already happens on the Hurd and
>> on
>> +  some Linux architectures.  The Linux kernel maintainers are discussing
>> a
>> +  more principled replacement for the reused API.  After a replacement
>> +  becomes available, we will change settimeofday to fail with ENOSYS on
>> all
>> +  platforms when its ‘tzp’ argument is not a null pointer.
> 
> Same here, the Unicode ‘’ instead of plain ASCII '' .

Ack, fixed.

> 
>> +  Note that settimeofday itself is obsolescent according to POSIX.
>> +  Programs that set the system time should use clock_settime and/or
>> +  the adjtime family of functions instead.  We may also cease to make
>> +  settimeofday available to newly linked binaries after there is a
>> +  replacement for Linux’s time-zone-like offset API.
> 
> Again the Unicode apostrophe ’ instead of plain ASCII ' .

Ack, fixed.

> 
> Regards,
> 
> Rafal
> 

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 09/11] Use clock_gettime to implement gettimeofday.
  2019-10-28 18:01     ` Joseph Myers
@ 2019-10-29  9:08       ` Lukasz Majewski
  0 siblings, 0 replies; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-29  9:08 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Adhemerval Zanella, libc-alpha

[-- Attachment #1: Type: text/plain, Size: 1414 bytes --]

Hi Joseph,

> On Mon, 28 Oct 2019, Lukasz Majewski wrote:
> 
> > >  attribute_compat_text_section
> > >  __gettimeofday_tv32 (struct timeval32 *restrict tv32, void
> > > *restrict tz) {
> > > -  struct timeval tv;
> > > -  __gettimeofday (&tv, tz);
> > > +  if (__glibc_unlikely (tz != 0))
> > > +    memset (tz, 0, sizeof (struct timezone));
> > >  
> > > -  tv64_to_tv32 (tv32, &tv);
> > > +  struct timespec ts;
> > > +  __clock_gettime (CLOCK_REALTIME, &ts);
> > > +
> > > +  ts64_to_tv32 (tv32, &ts);  
> > 
> > IMHO, this shall be replaced with valid_* functions from
> > include/time.h  
> 
> This is dealing with an alpha-specific timeval32 structure; 

Maybe I did not noticed it earlier.

The tv32-compat.h defines [1]:
struct timeval32
{
  int32_t tv_sec;
  int32_t tv_usec;
};

and conversion functions - like ts64_to_tv32() are to handle this
specific type.

I do think that if struct timeval32 is alpha specific, then the
conversion functions shall be kept.

> I don't
> see how the functions in include/time.h are applicable.
> 

Ok.

Note:
[1] - https://patchwork.ozlabs.org/patch/1184084/


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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls.
  2019-10-28 18:10     ` Adhemerval Zanella
@ 2019-10-29  9:11       ` Lukasz Majewski
  0 siblings, 0 replies; 34+ messages in thread
From: Lukasz Majewski @ 2019-10-29  9:11 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Zack Weinberg

[-- Attachment #1: Type: text/plain, Size: 2195 bytes --]

On Mon, 28 Oct 2019 15:10:36 -0300
Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> On 25/10/2019 10:04, Lukasz Majewski wrote:
> > Hi Adhemerval,
> > 
> > Thanks for re-sending those patches to ML. Please find some comments
> > below.
> >   
> [...]
> >> +/* Conversion functions.  If the seconds field of a timeval32
> >> would
> >> +   overflow, they write { INT32_MAX, TV_USEC_MAX } to the output.
> >>  */ +
> >> +static inline void
> >> +tv32_to_tv64 (struct timeval *restrict tv64,
> >> +              const struct timeval32 *restrict tv32)
> >> +{
> >> +  tv64->tv_sec = tv32->tv_sec;
> >> +  tv64->tv_usec = tv32->tv_usec;
> >> +}
> >> +
> >> +static inline void
> >> +tv32_to_ts64 (struct timespec *restrict ts64,
> >> +              const struct timeval32 *restrict tv32)
> >> +{
> >> +  ts64->tv_sec = tv32->tv_sec;
> >> +  ts64->tv_nsec = tv32->tv_usec * 1000;
> >> +}  
> > 
> > The ./include/time.h already provides such helper conversion
> > function - valid_timeval_to_timespec64 ();
> > 
> > There are also defined:
> > valid_timespec_to_timespec64 ();
> > valid_timespec64_to_timespec ();
> > valid_timespec64_to_timeval ();
> > 
> > There is also a different approach (as suggested some time ago by
> > Paul)
> > - those helper functions now return the converted structure and
> > accept value (not pointer) to convert.  
> 
> They are not really the same since they use different types.  The
> timeval32 for alpha is not exported anymore, it just support the
> time64 types.  Alpha is really an outlier and I don't think it really
> fits on the time64 refactoring you are doing for 32-bit archs.  So I
> think we should really add this arch-specific transformation function.
> 

Yes. You are right (I didn't notice the aplha specific struct
timeval32).

> I changed the required routines to mimic the valid_* one on
> include/time.h.
> 

Ok.


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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls.
  2019-10-28 18:13     ` Adhemerval Zanella
@ 2019-10-29 10:30       ` Alistair Francis
  0 siblings, 0 replies; 34+ messages in thread
From: Alistair Francis @ 2019-10-29 10:30 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: GNU C Library, Lukasz Majewski, Zack Weinberg

On Mon, Oct 28, 2019 at 7:13 PM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 25/10/2019 22:08, Alistair Francis wrote:
> > On Fri, Oct 25, 2019 at 5:09 AM Adhemerval Zanella
> > <adhemerval.zanella@linaro.org> wrote:
> >>
> >> From: Zack Weinberg <zackw@panix.com>
> >>
> [...]
> >> +
> >> +#include <sys/timex.h>
> >> +#include <sysdep.h>
> >> +
> >> +int
> >> +___adjtimex (struct timex *buf)
> >> +{
> >> +  return INLINE_SYSCALL_CALL (adjtimex, buf);
> >
> > The y2038 safe platforms don't have the adjtimex syscall, instead they
> > have the clock_adjtime call. Can this fall back to clock_adjtime if
> > __NR_adjtimex isn't defined?
> >
> > Alistair
> >
>
> This change is just a direct transformation from the definition at
> syscalls.list (below) to a C implementation.
>
> My plan to add *another* patch on this set to add the specific
> adjtimex refactor to make it call __clock_adjtime instead.

That works for me.

Alistair

>
> >> diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
> >> index e374f97b5f..cdcf6c127b 100644
> >> --- a/sysdeps/unix/sysv/linux/syscalls.list
> >> +++ b/sysdeps/unix/sysv/linux/syscalls.list
> >> @@ -1,6 +1,5 @@
> >>  # File name    Caller  Syscall name    Args    Strong name     Weak names
> >>
> >> -adjtimex       adjtime adjtimex        i:p     __adjtimex      adjtimex ntp_adjtime
> >>  alarm          -       alarm           i:i     alarm
> >>  bdflush                EXTRA   bdflush         i:ii    __compat_bdflush        bdflush@GLIBC_2.0:GLIBC_2.23
> >>  capget         EXTRA   capget          i:pp    capget
> >> --
> >> 2.17.1
> >>

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2019-10-29 10:30 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-25 12:08 [PATCH v2 00/11] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Adhemerval Zanella
2019-10-25 12:08 ` [PATCH v2 01/11] Linux/Alpha: don't use timeval32 system calls Adhemerval Zanella
2019-10-25 13:05   ` Lukasz Majewski
2019-10-28 18:10     ` Adhemerval Zanella
2019-10-29  9:11       ` Lukasz Majewski
2019-10-26  1:08   ` Alistair Francis
2019-10-28 18:13     ` Adhemerval Zanella
2019-10-29 10:30       ` Alistair Francis
2019-10-25 12:08 ` [PATCH v2 03/11] Use clock_settime to implement stime; withdraw stime Adhemerval Zanella
2019-10-25 13:59   ` Lukasz Majewski
2019-10-25 12:09 ` [PATCH v2 10/11] Make second argument of gettimeofday as 'void *' Adhemerval Zanella
2019-10-28 14:23   ` Lukasz Majewski
2019-10-25 12:09 ` [PATCH v2 11/11] Revise the documentation of simple calendar time Adhemerval Zanella
2019-10-25 12:09 ` [PATCH v2 04/11] Use clock_settime to implement settimeofday Adhemerval Zanella
2019-10-25 15:28   ` Lukasz Majewski
2019-10-28 18:28     ` Adhemerval Zanella
2019-10-25 20:42   ` Alistair Francis
2019-10-28 18:29     ` Adhemerval Zanella
2019-10-25 23:34   ` Rafal Luzynski
2019-10-28 18:46     ` Adhemerval Zanella
2019-10-25 12:09 ` [PATCH v2 07/11] Consolidate and deprecate ftime Adhemerval Zanella
2019-10-28 13:23   ` Lukasz Majewski
2019-10-25 12:09 ` [PATCH v2 02/11] Change most internal uses of __gettimeofday to __clock_gettime Adhemerval Zanella
2019-10-25 13:26   ` Lukasz Majewski
2019-10-25 12:09 ` [PATCH v2 06/11] Change most internal uses of time " Adhemerval Zanella
2019-10-25 21:22   ` Lukasz Majewski
2019-10-25 12:09 ` [PATCH v2 09/11] Use clock_gettime to implement gettimeofday Adhemerval Zanella
2019-10-28 14:16   ` Lukasz Majewski
2019-10-28 18:01     ` Joseph Myers
2019-10-29  9:08       ` Lukasz Majewski
2019-10-25 12:09 ` [PATCH v2 05/11] Use clock_gettime to implement time Adhemerval Zanella
2019-10-25 20:59   ` Lukasz Majewski
2019-10-25 12:09 ` [PATCH v2 08/11] Use clock_gettime to implement timespec_get Adhemerval Zanella
2019-10-28 13:30   ` Lukasz Majewski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).