unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions.
@ 2019-08-28 15:32 Zack Weinberg
  2019-08-28 15:32 ` [PATCH v2 01/10] Change most internal uses of __gettimeofday to __clock_gettime Zack Weinberg
                   ` (10 more replies)
  0 siblings, 11 replies; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 15:32 UTC (permalink / raw)
  To: libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

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.  Internal uses of time() are
mostly left alone, since time() is easier and clearer when you don't
care about sub-second resolution and don't need a struct timespec for
some other reason.

The user-visible consequences of this patchset are:

 - The obsolete functions ftime and stime are no longer available to
   new binaries.  The header <sys/timeb.h> is no longer installed.
 - 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).
 - On Linux, the (v)syscalls time and gettimeofday are no longer used
   under any circumstances.

See the final patch in the series for edits to NEWS describing these
changes in more detail.

This patchset also includes a partial revision of manual/time.tex.i
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.)

This patchset has a structural dependency on the patch "Linux/Alpha:
don't use timeval32 system calls."  I think that patch needs to be
reviewed and discussed separately since it has implications for how we
implement 32-bit time_t compatibility in general.  Some but not all of
the patches in this set could be re-done to avoid the dependency, but
I don't think there's much point.

Each individual patch in this series has been tested with
build-many-glibcs targeting alpha-linux-gnu, i686-gnu, and
x86_64-linux-gnu-enable-obsolete.  The complete patch series has been
tested with a full build-many-glibcs run and a full "make xcheck" run
in the x86_64-linux-gnu-enable-obsolete configuration.

Changes since v1:

 - Demote ftime and stime to compat symbols.
 - Also use clock_gettime to implement timespec_get.
 - Better implementation of warnings for gettimeofday with non-null
   tzp argument.
 - Patch series reorganized for ease of review and to ensure all
   intermediate stages work correctly on all supported platforms.
   In particular, gettimeofday and settimeofday have fully operational
   implementations on the Hurd at all stages of the series.
 - I believe all previous review comments have been addressed.

Zack Weinberg (10):
  Change most internal uses of __gettimeofday to __clock_gettime.
  Finish move of clock_* functions to libc.
  Use clock_settime to implement stime; withdraw stime.
  Use clock_settime to implement settimeofday.
  Use clock_gettime to implement time.
  Use clock_gettime to implement ftime; withdraw ftime.
  Use clock_gettime to implement timespec_get.
  Use clock_gettime to implement gettimeofday.
  Warn when gettimeofday is called with non-null tzp argument.
  Revise the documentation of simple calendar time.

 NEWS                                          |   62 +-
 conform/Makefile                              |    9 +
 debug/warning-nop.c                           |    9 +
 include/sys/time.h                            |    7 +-
 include/time.h                                |    4 +-
 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                              | 1071 ++++++++++-------
 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 +-
 rt/Makefile                                   |   15 +-
 rt/Versions                                   |   16 -
 rt/clock-compat.c                             |   63 -
 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/clock_gettime.c                  |   51 +
 sysdeps/mach/gettimeofday.c                   |   43 -
 .../hurd/{settimeofday.c => clock_settime.c}  |   36 +-
 sysdeps/mach/hurd/getitimer.c                 |    6 +-
 sysdeps/mach/hurd/i386/libc.abilist           |    5 +
 sysdeps/mach/hurd/i386/librt.abilist          |    5 -
 sysdeps/mach/hurd/setitimer.c                 |    8 +-
 sysdeps/mach/hurd/times.c                     |    7 +-
 sysdeps/mach/nanosleep.c                      |   36 +-
 sysdeps/mach/usleep.c                         |    5 -
 sysdeps/posix/clock_getres.c                  |   11 +-
 sysdeps/posix/gettimeofday.c                  |   67 --
 sysdeps/posix/tempname.c                      |    9 +-
 sysdeps/posix/time.c                          |   40 -
 sysdeps/posix/timespec_get.c                  |   38 -
 sysdeps/pthread/aio_misc.c                    |    6 +-
 sysdeps/pthread/aio_suspend.c                 |    6 +-
 sysdeps/unix/bsd/ftime.c                      |   40 -
 sysdeps/unix/clock_gettime.c                  |   64 -
 sysdeps/unix/clock_nanosleep.c                |   10 +-
 sysdeps/unix/clock_settime.c                  |   54 -
 sysdeps/unix/make-syscalls.sh                 |    2 +-
 sysdeps/unix/syscalls.list                    |    2 -
 .../unix/sysv/linux/aarch64/gettimeofday.c    |   71 --
 sysdeps/unix/sysv/linux/aarch64/init-first.c  |    7 +-
 sysdeps/unix/sysv/linux/aarch64/libc-vdso.h   |    2 -
 .../linux/{time.c => alpha/gettimeofday.c}    |   31 +-
 sysdeps/unix/sysv/linux/alpha/libc.abilist    |    5 +
 sysdeps/unix/sysv/linux/alpha/librt.abilist   |    5 -
 .../unix/sysv/linux/alpha/osf_gettimeofday.c  |   11 +-
 .../unix/sysv/linux/alpha/osf_settimeofday.c  |   16 +-
 sysdeps/unix/sysv/linux/alpha/settimeofday.c  |   22 +
 sysdeps/unix/sysv/linux/alpha/syscalls.list   |    2 -
 sysdeps/unix/sysv/linux/arm/init-first.c      |    7 +-
 sysdeps/unix/sysv/linux/arm/libc-vdso.h       |    2 -
 sysdeps/unix/sysv/linux/arm/libc.abilist      |    5 +
 sysdeps/unix/sysv/linux/arm/librt.abilist     |    5 -
 sysdeps/unix/sysv/linux/clock_getcpuclockid.c |   10 +-
 sysdeps/unix/sysv/linux/clock_getres.c        |   11 +-
 sysdeps/unix/sysv/linux/clock_gettime.c       |   11 +-
 sysdeps/unix/sysv/linux/clock_nanosleep.c     |   10 +-
 sysdeps/unix/sysv/linux/clock_settime.c       |   11 +-
 sysdeps/unix/sysv/linux/ftime.c               |    3 -
 sysdeps/unix/sysv/linux/gettimeofday.c        |   49 -
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |    5 +
 sysdeps/unix/sysv/linux/hppa/librt.abilist    |    5 -
 sysdeps/unix/sysv/linux/i386/gettimeofday.c   |   35 -
 sysdeps/unix/sysv/linux/i386/libc.abilist     |    5 +
 sysdeps/unix/sysv/linux/i386/librt.abilist    |    5 -
 sysdeps/unix/sysv/linux/i386/time.c           |   34 -
 sysdeps/unix/sysv/linux/ia64/libc.abilist     |    5 +
 sysdeps/unix/sysv/linux/ia64/librt.abilist    |    5 -
 .../sysv/linux/m68k/coldfire/libc.abilist     |    5 +
 .../sysv/linux/m68k/coldfire/librt.abilist    |    5 -
 .../unix/sysv/linux/m68k/m680x0/libc.abilist  |    5 +
 .../unix/sysv/linux/m68k/m680x0/librt.abilist |    5 -
 .../unix/sysv/linux/microblaze/librt.abilist  |    5 -
 sysdeps/unix/sysv/linux/mips/init-first.c     |    7 +-
 sysdeps/unix/sysv/linux/mips/libc-vdso.h      |    2 -
 .../sysv/linux/mips/mips32/fpu/libc.abilist   |    5 +
 .../unix/sysv/linux/mips/mips32/librt.abilist |    5 -
 .../sysv/linux/mips/mips32/nofpu/libc.abilist |    5 +
 .../unix/sysv/linux/mips/mips64/librt.abilist |    5 -
 .../sysv/linux/mips/mips64/n32/libc.abilist   |    5 +
 .../sysv/linux/mips/mips64/n64/libc.abilist   |    5 +
 sysdeps/unix/sysv/linux/powerpc/Versions      |    1 -
 .../unix/sysv/linux/powerpc/gettimeofday.c    |   85 --
 sysdeps/unix/sysv/linux/powerpc/init-first.c  |   13 +-
 sysdeps/unix/sysv/linux/powerpc/libc-vdso.h   |    2 -
 .../linux/powerpc/powerpc32/fpu/libc.abilist  |    5 +
 .../linux/powerpc/powerpc32/librt.abilist     |    5 -
 .../powerpc/powerpc32/nofpu/libc.abilist      |    5 +
 .../linux/powerpc/powerpc64/be/libc.abilist   |    5 +
 .../linux/powerpc/powerpc64/be/librt.abilist  |    5 -
 sysdeps/unix/sysv/linux/powerpc/time.c        |   84 --
 sysdeps/unix/sysv/linux/riscv/init-first.c    |   10 +-
 sysdeps/unix/sysv/linux/riscv/libc-vdso.h     |    2 -
 sysdeps/unix/sysv/linux/s390/init-first.c     |    9 +-
 sysdeps/unix/sysv/linux/s390/libc-vdso.h      |    3 -
 .../unix/sysv/linux/s390/s390-32/libc.abilist |    5 +
 .../sysv/linux/s390/s390-32/librt.abilist     |    5 -
 .../unix/sysv/linux/s390/s390-64/libc.abilist |    5 +
 .../sysv/linux/s390/s390-64/librt.abilist     |    5 -
 .../{stime.c => sysv/linux/settimezone.c}     |   30 +-
 sysdeps/unix/sysv/linux/sh/libc.abilist       |    5 +
 sysdeps/unix/sysv/linux/sh/librt.abilist      |    5 -
 sysdeps/unix/sysv/linux/sparc/init-first.c    |    8 +-
 sysdeps/unix/sysv/linux/sparc/libc-vdso.h     |    2 -
 .../sysv/linux/sparc/sparc32/libc.abilist     |    5 +
 .../sysv/linux/sparc/sparc32/librt.abilist    |    5 -
 .../sysv/linux/sparc/sparc64/libc.abilist     |    5 +
 .../sysv/linux/sparc/sparc64/librt.abilist    |    5 -
 sysdeps/unix/sysv/linux/sparc/sparc64/time.c  |    1 -
 sysdeps/unix/sysv/linux/syscalls.list         |    1 -
 sysdeps/unix/sysv/linux/timespec_get.c        |   46 -
 sysdeps/unix/sysv/linux/x86/gettimeofday.c    |   61 -
 sysdeps/unix/sysv/linux/x86/time.c            |   59 -
 .../unix/sysv/linux/x86_64/64/libc.abilist    |    5 +
 .../unix/sysv/linux/x86_64/64/librt.abilist   |    5 -
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |    5 +
 .../unix/sysv/linux/x86_64/x32/librt.abilist  |    5 -
 .../unix/sysv/linux/x86_64/x32/syscalls.list  |    2 -
 time/Makefile                                 |   20 +-
 time/Versions                                 |   13 +
 {rt => time}/clock_getcpuclockid.c            |    9 +-
 time/clock_getres.c                           |   39 +
 {rt => time}/clock_gettime.c                  |   11 +-
 {rt => time}/clock_nanosleep.c                |   11 +-
 {rt => time}/clock_settime.c                  |   12 +-
 time/ftime.c                                  |   40 +-
 time/gettimeofday.c                           |   32 +-
 time/settimeofday.c                           |   24 +-
 rt/clock_getres.c => time/settimezone.c       |   12 +-
 time/stime.c                                  |   25 +-
 time/sys/time.h                               |   47 +-
 time/sys/timeb.h                              |   43 -
 time/time.c                                   |   12 +-
 time/time.h                                   |    6 -
 time/timespec_get.c                           |   14 +-
 {rt => time}/tst-clock.c                      |    0
 {rt => time}/tst-clock2.c                     |    0
 {rt => time}/tst-clock_nanosleep.c            |    0
 {rt => time}/tst-cpuclock1.c                  |    0
 time/tst-ftime.c                              |   58 -
 time/{tst-ftime_l.c => tst-strftime_l.c}      |    0
 153 files changed, 1376 insertions(+), 2011 deletions(-)
 delete mode 100644 rt/clock-compat.c
 create mode 100644 sysdeps/mach/clock_gettime.c
 delete mode 100644 sysdeps/mach/gettimeofday.c
 rename sysdeps/mach/hurd/{settimeofday.c => clock_settime.c} (60%)
 delete mode 100644 sysdeps/posix/gettimeofday.c
 delete mode 100644 sysdeps/posix/time.c
 delete mode 100644 sysdeps/posix/timespec_get.c
 delete mode 100644 sysdeps/unix/bsd/ftime.c
 delete mode 100644 sysdeps/unix/clock_gettime.c
 delete mode 100644 sysdeps/unix/clock_settime.c
 delete mode 100644 sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
 rename sysdeps/unix/sysv/linux/{time.c => alpha/gettimeofday.c} (64%)
 create mode 100644 sysdeps/unix/sysv/linux/alpha/settimeofday.c
 delete mode 100644 sysdeps/unix/sysv/linux/ftime.c
 delete mode 100644 sysdeps/unix/sysv/linux/gettimeofday.c
 delete mode 100644 sysdeps/unix/sysv/linux/i386/gettimeofday.c
 delete mode 100644 sysdeps/unix/sysv/linux/i386/time.c
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/time.c
 rename sysdeps/unix/{stime.c => sysv/linux/settimezone.c} (64%)
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/time.c
 delete mode 100644 sysdeps/unix/sysv/linux/timespec_get.c
 delete mode 100644 sysdeps/unix/sysv/linux/x86/gettimeofday.c
 delete mode 100644 sysdeps/unix/sysv/linux/x86/time.c
 rename {rt => time}/clock_getcpuclockid.c (75%)
 create mode 100644 time/clock_getres.c
 rename {rt => time}/clock_gettime.c (74%)
 rename {rt => time}/clock_nanosleep.c (76%)
 rename {rt => time}/clock_settime.c (71%)
 rename rt/clock_getres.c => time/settimezone.c (73%)
 delete mode 100644 time/sys/timeb.h
 rename {rt => time}/tst-clock.c (100%)
 rename {rt => time}/tst-clock2.c (100%)
 rename {rt => time}/tst-clock_nanosleep.c (100%)
 rename {rt => time}/tst-cpuclock1.c (100%)
 delete mode 100644 time/tst-ftime.c
 rename time/{tst-ftime_l.c => tst-strftime_l.c} (100%)

-- 
2.23.0


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

* [PATCH v2 01/10] Change most internal uses of __gettimeofday to __clock_gettime.
  2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
@ 2019-08-28 15:32 ` Zack Weinberg
  2019-08-29 20:30   ` Adhemerval Zanella
  2019-08-28 15:32 ` [PATCH v2 02/10] Finish move of clock_* functions to libc Zack Weinberg
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 15:32 UTC (permalink / raw)
  To: libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

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.

	* inet/deadline.c (__deadline_current_time)
	* login/logout.c (logout)
	* login/logwtmp.c (logwtmp)
	* nis/nis_call.c (__nisfind_server)
	* nptl/pthread_join_common.c (timedwait_tid)
	* nptl/pthread_mutex_timedlock.c (__pthread_mutex_clocklock_common)
	* nscd/nscd_helper.c (wait_on_socket, open_socket)
	* resolv/gai_misc.c (handle_requests)
	* resolv/gai_suspend.c (gai_suspend)
	* resolv/res_send.c (evNowTime)
	* sunrpc/auth_des.c (authdes_marshal, authdes_destroy)
	* sunrpc/auth_unix.c (authunix_create, authunix_refresh)
	* sunrpc/create_xid.c (_create_xid)
	* sunrpc/svcauth_des.c (_svcauth_des)
	* sysdeps/generic/memusage.h (GETTIME)
	* sysdeps/mach/nanosleep.c (__libc_nanosleep)
	* sysdeps/posix/tempname.c (RANDOM_BITS)
	* sysdeps/pthread/aio_misc.c (handle_fildes_io)
	* sysdeps/pthread/aio_suspend.c (aio_suspend):
	Use __clock_gettime (CLOCK_REALTIME) instead of __gettimeofday.
	Assume __clock_gettime (CLOCK_REALTIME) cannot fail.
	Include time.h if necessary.

	* sysdeps/posix/timespec_get.c (timespec_get):
	Assume __clock_gettime (CLOCK_REALTIME) cannot fail.

	* sysdeps/mach/hurd/getitimer.c (__getitimer)
	* sysdeps/mach/hurd/setitimer.c (setitimer_locked)
	* sysdeps/mach/hurd/times.c (__times):
	Use __host_get_time instead of __gettimeofday.
	Include mach.h if necessary.
	Assume __host_get_time (__mach_host_self ()) cannot fail.

	* sysdeps/mach/usleep.c (usleep): Remove unnecessary calls to
	__gettimeofday.

	* support/support_test_main.c (print_timestamp): Take a struct
	timespec argument, not a struct timeval.
	(signal_handler): Update to match.
	Use clock_gettime (CLOCK_REALTIME) instead of gettimeofday.
	Assume clock_gettime (CLOCK_REALTIME) cannot fail.

	* sysdeps/generic/memusage.h (GETTIME): Correct typo causing
	the seconds field of each timestamp to be ignored.

	* sysdeps/unix/make-syscall.sh: Change an example in a comment
	from referring to gettimeofday, to referring to sigaction.
---
 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  |  6 +++---
 sysdeps/mach/hurd/setitimer.c  |  8 ++------
 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, 127 insertions(+), 137 deletions(-)

diff --git a/inet/deadline.c b/inet/deadline.c
index ab275c266d..082e279bce 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 5015c1af0b..f1313ded77 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 50d14976c7..ec41375383 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 a48ecc39a8..db81fa3568 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 5224ee2110..f1b14266de 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 52c258e33d..2b194e5bee 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 733c2a60cd..a6568d07c8 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 69d7086ae6..5d1e310147 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 eee3bcebe9..8f81e5a3dd 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 ed27f3abf8..2b971cf5d2 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..9079b30397 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 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 a44187f07c..8d1e722dad 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 7e7b9edbb0..d8397a840c 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 480bdf79ee..c29feb8edd 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 69a0751ead..5af723f62a 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,7 @@ __getitimer (enum __itimer_which which, struct itimerval *value)
     }
 
   /* Get the time now.  */
-  if (__gettimeofday (&elapsed, NULL) < 0)
-    return -1;
+  __host_get_time (__mach_host_self (), (time_value_t *) &elapsed);
 
   /* 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 61e37c5f5d..b82582a60f 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.  */
@@ -239,12 +240,7 @@ 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;
-	}
+      __host_get_time (__mach_host_self (), (time_value_t *) &now);
       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 7758311d83..0f48c784a9 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 b4790aaf31..f9b821a6e2 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 5d4bd205e1..8428ace6ef 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 310df3c4ca..c3956498ce 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 98d3136287..781a624c7d 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 0180ddb3c3..49ab08de3a 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 06bd914672..fdd4087abb 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 6a5c10d54e..2b8c9ea49c 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.23.0


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

* [PATCH v2 02/10] Finish move of clock_* functions to libc.
  2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
  2019-08-28 15:32 ` [PATCH v2 01/10] Change most internal uses of __gettimeofday to __clock_gettime Zack Weinberg
@ 2019-08-28 15:32 ` Zack Weinberg
  2019-08-30 17:40   ` Adhemerval Zanella
  2019-09-03  7:29   ` Florian Weimer
  2019-08-28 15:32 ` [PATCH v2 03/10] Use clock_settime to implement stime; withdraw stime Zack Weinberg
                   ` (8 subsequent siblings)
  10 siblings, 2 replies; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 15:32 UTC (permalink / raw)
  To: libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

In glibc 2.17, the functions clock_getcpuclockid, clock_getres,
clock_gettime, clock_nanosleep, and clock_settime were moved from
librt.so to libc.so, leaving compatibility stubs behind.  Now that the
dynamic linker no longer insists on finding versioned symbols in the
same library that originally defined them, we do not need the stubs
anymore, and this means we don't need GLIBC_PRIVATE __-prefix aliases
for most of the functions anymore either.  (clock_gettime still needs
one.)  For ports added before 2.17, libc.so needs to provide two
symbol versions for each, the default at GLIBC_2.17 plus a compat
version matching what librt had.

While I'm at it, move the clock_*.c files and their tests from rt/ to
time/.

	* rt/clock_getcpuclockid.c: Move to time/clock_getcpuclockid.c.
	* rt/clock_getres.c: Move to time/clock_getres.c.
	* rt/clock_gettime.c: Move to time/clock_gettime.c.
	* rt/clock_nanosleep.c: Move to time/clock_nanosleep.c.
	* rt/clock_settime.c: Move to time/clock_settime.c.
	* rt/tst-clock.c: Move to time/tst-clock.c.
	* rt/tst-clock2.c: Move to time/tst-clock2.c.
	* rt/tst-clock_nanosleep.c: Move to time/tst-clock_nanosleep.c.
	* rt/tst-cpuclock1.c: Move to time/tst-cpuclock1.c.
	* rt/clock-compat.c: Delete file.

	* time/clock_getcpuclockid.c
	* time/clock_getres.c
	* time/clock_gettime.c
	* time/clock_nanosleep.c
	* time/clock_settime.c
	* sysdeps/posix/clock_getres.c
	* sysdeps/unix/clock_gettime.c
	* sysdeps/unix/clock_nanosleep.c
	* sysdeps/unix/clock_settime.c
	* sysdeps/unix/sysv/linux/clock_getcpuclockid.c
	* sysdeps/unix/sysv/linux/clock_getres.c
	* sysdeps/unix/sysv/linux/clock_gettime.c
	* sysdeps/unix/sysv/linux/clock_nanosleep.c
	* sysdeps/unix/sysv/linux/clock_settime.c: Define the function
	defined by this file with default symbol version GLIBC_2_17,
	and optionally a compatibility alias at symbol version GLIBC_2_2.
	* include/time.h: Remove internal prototypes for clock_getres,
	clock_nanosleep, and clock_getcpuclockid.

	* sysdeps/unix/sysv/linux/clock_gettime.c: Prune includes.
	Remove unused function realtime_gettime.

	* rt/Makefile (clock-routines, routines): Remove variable.
	(librt-routines): Remove clock-compat.
	(tests): Remove tst-clock, tst-clock2, tst-clock_nanosleep,
	and tst-cpuclock1.
	* time/Makefile (routines): Add clock_getres, clock_gettime,
	clock_settime, clock_getcpuclockid, and clock_nanosleep.
	(tests): Add tst-clock, tst-clock2, tst-clock_nanosleep,
	and tst-cpuclock1.

	* rt/Versions (libc): Remove entire stanza.
	(librt GLIBC_2.2): Remove all clock_* functions.
	* time/Versions (libc GLIBC_2.2, libc GLIBC_2.17):
	Add clock_getres, clock_gettime, clock_settime,
	clock_getcpuclockid, and clock_nanosleep.
	(libc GLIBC_PRIVATE): Add __clock_gettime.

	* sysdeps/mach/hurd/i386/librt.abilist
	* sysdeps/unix/sysv/linux/alpha/librt.abilist
	* sysdeps/unix/sysv/linux/arm/librt.abilist
	* sysdeps/unix/sysv/linux/hppa/librt.abilist
	* sysdeps/unix/sysv/linux/i386/librt.abilist
	* sysdeps/unix/sysv/linux/ia64/librt.abilist
	* sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist
	* sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist
	* sysdeps/unix/sysv/linux/microblaze/librt.abilist
	* sysdeps/unix/sysv/linux/mips/mips32/librt.abilist
	* sysdeps/unix/sysv/linux/mips/mips64/librt.abilist
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/librt.abilist
	* sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist
	* sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist
	* sysdeps/unix/sysv/linux/sh/librt.abilist
	* sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist
	* sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist
	* sysdeps/unix/sysv/linux/x86_64/64/librt.abilist
	* sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist:
	Remove entries for clock_getres, clock_gettime, clock_settime,
	clock_getcpuclockid, and clock_nanosleep.

	* sysdeps/mach/hurd/i386/libc.abilist
	* sysdeps/unix/sysv/linux/alpha/libc.abilist
	* sysdeps/unix/sysv/linux/arm/libc.abilist
	* sysdeps/unix/sysv/linux/hppa/libc.abilist
	* sysdeps/unix/sysv/linux/i386/libc.abilist
	* sysdeps/unix/sysv/linux/ia64/libc.abilist
	* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
	* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
	* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
	* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
	* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
	* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
	* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
	* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
	* sysdeps/unix/sysv/linux/sh/libc.abilist
	* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
	* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
	* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
	* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist:
	Add another set of entries for clock_getres, clock_gettime,
	clock_settime, clock_getcpuclockid, and clock_nanosleep at
	whatever version GLIBC_2.2 maps to.
---
 include/time.h                                |  4 +-
 rt/Makefile                                   | 15 ++---
 rt/Versions                                   | 16 -----
 rt/clock-compat.c                             | 63 -------------------
 sysdeps/mach/hurd/i386/libc.abilist           |  5 ++
 sysdeps/mach/hurd/i386/librt.abilist          |  5 --
 sysdeps/posix/clock_getres.c                  | 11 +++-
 sysdeps/unix/clock_gettime.c                  | 26 +++-----
 sysdeps/unix/clock_nanosleep.c                | 10 ++-
 sysdeps/unix/clock_settime.c                  | 13 +++-
 sysdeps/unix/sysv/linux/alpha/libc.abilist    |  5 ++
 sysdeps/unix/sysv/linux/alpha/librt.abilist   |  5 --
 sysdeps/unix/sysv/linux/arm/libc.abilist      |  5 ++
 sysdeps/unix/sysv/linux/arm/librt.abilist     |  5 --
 sysdeps/unix/sysv/linux/clock_getcpuclockid.c | 10 ++-
 sysdeps/unix/sysv/linux/clock_getres.c        | 11 +++-
 sysdeps/unix/sysv/linux/clock_gettime.c       | 11 +++-
 sysdeps/unix/sysv/linux/clock_nanosleep.c     | 10 ++-
 sysdeps/unix/sysv/linux/clock_settime.c       | 11 +++-
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |  5 ++
 sysdeps/unix/sysv/linux/hppa/librt.abilist    |  5 --
 sysdeps/unix/sysv/linux/i386/libc.abilist     |  5 ++
 sysdeps/unix/sysv/linux/i386/librt.abilist    |  5 --
 sysdeps/unix/sysv/linux/ia64/libc.abilist     |  5 ++
 sysdeps/unix/sysv/linux/ia64/librt.abilist    |  5 --
 .../sysv/linux/m68k/coldfire/libc.abilist     |  5 ++
 .../sysv/linux/m68k/coldfire/librt.abilist    |  5 --
 .../unix/sysv/linux/m68k/m680x0/libc.abilist  |  5 ++
 .../unix/sysv/linux/m68k/m680x0/librt.abilist |  5 --
 .../unix/sysv/linux/microblaze/librt.abilist  |  5 --
 .../sysv/linux/mips/mips32/fpu/libc.abilist   |  5 ++
 .../unix/sysv/linux/mips/mips32/librt.abilist |  5 --
 .../sysv/linux/mips/mips32/nofpu/libc.abilist |  5 ++
 .../unix/sysv/linux/mips/mips64/librt.abilist |  5 --
 .../sysv/linux/mips/mips64/n32/libc.abilist   |  5 ++
 .../sysv/linux/mips/mips64/n64/libc.abilist   |  5 ++
 .../linux/powerpc/powerpc32/fpu/libc.abilist  |  5 ++
 .../linux/powerpc/powerpc32/librt.abilist     |  5 --
 .../powerpc/powerpc32/nofpu/libc.abilist      |  5 ++
 .../linux/powerpc/powerpc64/be/libc.abilist   |  5 ++
 .../linux/powerpc/powerpc64/be/librt.abilist  |  5 --
 .../unix/sysv/linux/s390/s390-32/libc.abilist |  5 ++
 .../sysv/linux/s390/s390-32/librt.abilist     |  5 --
 .../unix/sysv/linux/s390/s390-64/libc.abilist |  5 ++
 .../sysv/linux/s390/s390-64/librt.abilist     |  5 --
 sysdeps/unix/sysv/linux/sh/libc.abilist       |  5 ++
 sysdeps/unix/sysv/linux/sh/librt.abilist      |  5 --
 .../sysv/linux/sparc/sparc32/libc.abilist     |  5 ++
 .../sysv/linux/sparc/sparc32/librt.abilist    |  5 --
 .../sysv/linux/sparc/sparc64/libc.abilist     |  5 ++
 .../sysv/linux/sparc/sparc64/librt.abilist    |  5 --
 .../unix/sysv/linux/x86_64/64/libc.abilist    |  5 ++
 .../unix/sysv/linux/x86_64/64/librt.abilist   |  5 --
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |  5 ++
 .../unix/sysv/linux/x86_64/x32/librt.abilist  |  5 --
 time/Makefile                                 |  8 ++-
 time/Versions                                 | 13 ++++
 {rt => time}/clock_getcpuclockid.c            |  9 ++-
 {rt => time}/clock_getres.c                   | 11 +++-
 {rt => time}/clock_gettime.c                  | 11 +++-
 {rt => time}/clock_nanosleep.c                | 11 +++-
 {rt => time}/clock_settime.c                  | 12 +++-
 {rt => time}/tst-clock.c                      |  0
 {rt => time}/tst-clock2.c                     |  0
 {rt => time}/tst-clock_nanosleep.c            |  0
 {rt => time}/tst-cpuclock1.c                  |  0
 66 files changed, 268 insertions(+), 228 deletions(-)
 delete mode 100644 rt/clock-compat.c
 rename {rt => time}/clock_getcpuclockid.c (75%)
 rename {rt => time}/clock_getres.c (73%)
 rename {rt => time}/clock_gettime.c (74%)
 rename {rt => time}/clock_nanosleep.c (76%)
 rename {rt => time}/clock_settime.c (71%)
 rename {rt => time}/tst-clock.c (100%)
 rename {rt => time}/tst-clock2.c (100%)
 rename {rt => time}/tst-clock_nanosleep.c (100%)
 rename {rt => time}/tst-cpuclock1.c (100%)

diff --git a/include/time.h b/include/time.h
index ac3163c2a5..dcf91855ad 100644
--- a/include/time.h
+++ b/include/time.h
@@ -18,12 +18,10 @@ libc_hidden_proto (localtime)
 libc_hidden_proto (strftime)
 libc_hidden_proto (strptime)
 
-extern __typeof (clock_getres) __clock_getres;
 extern __typeof (clock_gettime) __clock_gettime;
 libc_hidden_proto (__clock_gettime)
 extern __typeof (clock_settime) __clock_settime;
-extern __typeof (clock_nanosleep) __clock_nanosleep;
-extern __typeof (clock_getcpuclockid) __clock_getcpuclockid;
+libc_hidden_proto (__clock_settime)
 
 /* Now define the internal interfaces.  */
 struct tm;
diff --git a/rt/Makefile b/rt/Makefile
index 9ea8394565..e6fbc32438 100644
--- a/rt/Makefile
+++ b/rt/Makefile
@@ -28,9 +28,6 @@ aio-routines   := aio_cancel aio_error aio_fsync aio_misc aio_read	\
 		  aio_read64 aio_return aio_suspend aio_write		\
 		  aio_write64 lio_listio lio_listio64 aio_sigqueue	\
 		  aio_notify
-clock-routines := clock_getcpuclockid					\
-		  clock_getres clock_gettime clock_settime		\
-		  clock_nanosleep
 timer-routines := timer_create timer_delete timer_getoverr		\
 		  timer_gettime timer_settime
 shm-routines   := shm_open shm_unlink
@@ -38,22 +35,18 @@ mq-routines    := mq_open mq_close mq_unlink mq_getattr mq_setattr	\
 		  mq_notify mq_send mq_receive mq_timedsend		\
 		  mq_timedreceive
 
-routines = $(clock-routines)
-
 librt-routines = $(aio-routines) \
 		 $(timer-routines) \
-		 $(shm-routines) $(mq-routines) \
-		 clock-compat
+		 $(shm-routines) $(mq-routines)
 
-tests := tst-shm tst-clock tst-clock_nanosleep tst-timer tst-timer2 \
+tests := tst-shm tst-timer tst-timer2 \
 	 tst-aio tst-aio64 tst-aio2 tst-aio3 tst-aio4 tst-aio5 tst-aio6 \
 	 tst-aio7 tst-aio8 tst-aio9 tst-aio10 \
 	 tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \
 	 tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \
 	 tst-timer3 tst-timer4 tst-timer5 \
-	 tst-cpuclock1 tst-cpuclock2 \
-	 tst-cputimer1 tst-cputimer2 tst-cputimer3 \
-	 tst-clock2 tst-shm-cancel
+	 tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \
+	 tst-shm-cancel
 
 extra-libs := librt
 extra-libs-others := $(extra-libs)
diff --git a/rt/Versions b/rt/Versions
index 91e3fd2a20..84d1345420 100644
--- a/rt/Versions
+++ b/rt/Versions
@@ -1,15 +1,3 @@
-libc {
-  GLIBC_2.17 {
-    # c*
-    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
-    clock_nanosleep;
-  }
-  GLIBC_PRIVATE {
-    __clock_getres; __clock_gettime; __clock_settime; __clock_getcpuclockid;
-    __clock_nanosleep;
-  }
-}
-
 librt {
   GLIBC_2.1 {
     # AIO functions.
@@ -18,10 +6,6 @@ librt {
     aio_suspend64; aio_write; aio_write64; lio_listio; lio_listio64;
   }
   GLIBC_2.2 {
-    # These have moved to libc and are still here only for compatibility.
-    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
-    clock_nanosleep;
-
     # s*
     shm_open; shm_unlink;
 
diff --git a/rt/clock-compat.c b/rt/clock-compat.c
deleted file mode 100644
index d8ced3cdc1..0000000000
--- a/rt/clock-compat.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* ABI compatibility redirects for clock_* symbols in librt.
-   Copyright (C) 2012-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>
-
-/* The clock_* symbols were originally defined in librt and so
-   are part of its ABI.  As of 2.17, they have moved to libc.
-   So we supply definitions for librt that just redirect to
-   their libc counterparts.  */
-
-#if SHLIB_COMPAT (librt, GLIBC_2_2, GLIBC_2_17)
-
-#include <time.h>
-
-#if HAVE_IFUNC
-# undef INIT_ARCH
-# define INIT_ARCH()
-# define COMPAT_REDIRECT(name, proto, arglist) libc_ifunc (name, &__##name) \
-    compat_symbol (librt, name, name, GLIBC_2_2);
-#else
-# define COMPAT_REDIRECT(name, proto, arglist)				      \
-  int									      \
-  name proto								      \
-  {									      \
-    return __##name arglist;						      \
-  }									      \
-  compat_symbol (librt, name, name, GLIBC_2_2);
-#endif
-
-COMPAT_REDIRECT (clock_getres,
-		 (clockid_t clock_id, struct timespec *res),
-		 (clock_id, res))
-COMPAT_REDIRECT (clock_gettime,
-		 (clockid_t clock_id, struct timespec *tp),
-		 (clock_id, tp))
-COMPAT_REDIRECT (clock_settime,
-		 (clockid_t clock_id, const struct timespec *tp),
-		 (clock_id, tp))
-COMPAT_REDIRECT (clock_getcpuclockid,
-		 (pid_t pid, clockid_t *clock_id),
-		 (pid, clock_id))
-COMPAT_REDIRECT (clock_nanosleep,
-		 (clockid_t clock_id, int flags,
-		  const struct timespec *req,
-		  struct timespec *rem),
-		 (clock_id, flags, req, rem))
-
-#endif
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 1fc7ab2433..7c2cb2b05a 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -711,6 +711,11 @@ GLIBC_2.2.6 clntudp_bufcreate F
 GLIBC_2.2.6 clntudp_create F
 GLIBC_2.2.6 clntunix_create F
 GLIBC_2.2.6 clock F
+GLIBC_2.2.6 clock_getcpuclockid F
+GLIBC_2.2.6 clock_getres F
+GLIBC_2.2.6 clock_gettime F
+GLIBC_2.2.6 clock_nanosleep F
+GLIBC_2.2.6 clock_settime F
 GLIBC_2.2.6 close F
 GLIBC_2.2.6 closedir F
 GLIBC_2.2.6 closelog F
diff --git a/sysdeps/mach/hurd/i386/librt.abilist b/sysdeps/mach/hurd/i386/librt.abilist
index d5fe32b3a9..3726e41f06 100644
--- a/sysdeps/mach/hurd/i386/librt.abilist
+++ b/sysdeps/mach/hurd/i386/librt.abilist
@@ -13,11 +13,6 @@ GLIBC_2.2.6 aio_suspend F
 GLIBC_2.2.6 aio_suspend64 F
 GLIBC_2.2.6 aio_write F
 GLIBC_2.2.6 aio_write64 F
-GLIBC_2.2.6 clock_getcpuclockid F
-GLIBC_2.2.6 clock_getres F
-GLIBC_2.2.6 clock_gettime F
-GLIBC_2.2.6 clock_nanosleep F
-GLIBC_2.2.6 clock_settime F
 GLIBC_2.2.6 lio_listio F
 GLIBC_2.2.6 lio_listio64 F
 GLIBC_2.2.6 shm_open F
diff --git a/sysdeps/posix/clock_getres.c b/sysdeps/posix/clock_getres.c
index 01024a3f55..e529cadb1f 100644
--- a/sysdeps/posix/clock_getres.c
+++ b/sysdeps/posix/clock_getres.c
@@ -22,7 +22,7 @@
 #include <unistd.h>
 #include <sys/param.h>
 #include <libc-internal.h>
-
+#include <shlib-compat.h>
 
 static inline int
 realtime_getres (struct timespec *res)
@@ -62,4 +62,11 @@ __clock_getres (clockid_t clock_id, struct timespec *res)
 
   return retval;
 }
-weak_alias (__clock_getres, clock_getres)
+
+versioned_symbol (libc, __clock_getres, clock_getres, GLIBC_2_17);
+/* clock_getres moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_getres, __clock_getres_2);
+compat_symbol (libc, __clock_getres_2, clock_getres, GLIBC_2_2);
+#endif
diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/unix/clock_gettime.c
index 10a6c96d9d..2a82fc1066 100644
--- a/sysdeps/unix/clock_gettime.c
+++ b/sysdeps/unix/clock_gettime.c
@@ -17,24 +17,9 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
-#include <stdint.h>
 #include <time.h>
 #include <sys/time.h>
-#include <libc-internal.h>
-#include <ldsodefs.h>
-
-
-static inline int
-realtime_gettime (struct timespec *tp)
-{
-  struct timeval tv;
-  int retval = __gettimeofday (&tv, NULL);
-  if (retval == 0)
-    /* Convert into `timespec'.  */
-    TIMEVAL_TO_TIMESPEC (&tv, tp);
-  return retval;
-}
-
+#include <shlib-compat.h>
 
 /* Get current value of CLOCK and store it in TP.  */
 int
@@ -60,5 +45,12 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp)
 
   return retval;
 }
-weak_alias (__clock_gettime, clock_gettime)
 libc_hidden_def (__clock_gettime)
+
+versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17);
+/* clock_gettime moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_gettime, __clock_gettime_2);
+compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2);
+#endif
diff --git a/sysdeps/unix/clock_nanosleep.c b/sysdeps/unix/clock_nanosleep.c
index b27608570c..6a477520d1 100644
--- a/sysdeps/unix/clock_nanosleep.c
+++ b/sysdeps/unix/clock_nanosleep.c
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <time.h>
 #include <sysdep-cancel.h>
+#include <shlib-compat.h>
 
 /* This implementation assumes that these is only a `nanosleep' system
    call.  So we have to remap all other activities.  */
@@ -76,4 +77,11 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
 
   return __nanosleep (req, rem), 0 ? errno : 0;
 }
-weak_alias (__clock_nanosleep, clock_nanosleep)
+
+versioned_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_17);
+/* clock_nanosleep moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_nanosleep, __clock_nanosleep_2);
+compat_symbol (libc, __clock_nanosleep_2, clock_nanosleep, GLIBC_2_2);
+#endif
diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/unix/clock_settime.c
index 109a1ad872..5b398491ab 100644
--- a/sysdeps/unix/clock_settime.c
+++ b/sysdeps/unix/clock_settime.c
@@ -18,8 +18,7 @@
 #include <errno.h>
 #include <time.h>
 #include <sys/time.h>
-#include <ldsodefs.h>
-
+#include <shlib-compat.h>
 
 /* Set CLOCK to value TP.  */
 int
@@ -51,4 +50,12 @@ __clock_settime (clockid_t clock_id, const struct timespec *tp)
 
   return retval;
 }
-weak_alias (__clock_settime, clock_settime)
+libc_hidden_def (__clock_settime)
+
+versioned_symbol (libc, __clock_settime, clock_settime, GLIBC_2_17);
+/* clock_settime moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_settime, __clock_settime_2);
+compat_symbol (libc, __clock_settime_2, clock_settime, GLIBC_2_2);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index fe85a35620..e7f2174ac2 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -1863,6 +1863,11 @@ GLIBC_2.2 __xpg_sigpause F
 GLIBC_2.2 _flushlbf F
 GLIBC_2.2 _res_hconf D 0x48
 GLIBC_2.2 bind_textdomain_codeset F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 dcngettext F
 GLIBC_2.2 dngettext F
 GLIBC_2.2 fgetpos F
diff --git a/sysdeps/unix/sysv/linux/alpha/librt.abilist b/sysdeps/unix/sysv/linux/alpha/librt.abilist
index d7a049cf60..71f86e03ce 100644
--- a/sysdeps/unix/sysv/linux/alpha/librt.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/librt.abilist
@@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
 GLIBC_2.1 aio_write64 F
 GLIBC_2.1 lio_listio F
 GLIBC_2.1 lio_listio64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 shm_open F
 GLIBC_2.2 shm_unlink F
 GLIBC_2.2 timer_create F
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index bc3df8dcea..9371927927 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -766,6 +766,11 @@ GLIBC_2.4 clntudp_bufcreate F
 GLIBC_2.4 clntudp_create F
 GLIBC_2.4 clntunix_create F
 GLIBC_2.4 clock F
+GLIBC_2.4 clock_getcpuclockid F
+GLIBC_2.4 clock_getres F
+GLIBC_2.4 clock_gettime F
+GLIBC_2.4 clock_nanosleep F
+GLIBC_2.4 clock_settime F
 GLIBC_2.4 clone F
 GLIBC_2.4 close F
 GLIBC_2.4 closedir F
diff --git a/sysdeps/unix/sysv/linux/arm/librt.abilist b/sysdeps/unix/sysv/linux/arm/librt.abilist
index cfbbd27557..3c0647b251 100644
--- a/sysdeps/unix/sysv/linux/arm/librt.abilist
+++ b/sysdeps/unix/sysv/linux/arm/librt.abilist
@@ -13,11 +13,6 @@ GLIBC_2.4 aio_suspend F
 GLIBC_2.4 aio_suspend64 F
 GLIBC_2.4 aio_write F
 GLIBC_2.4 aio_write64 F
-GLIBC_2.4 clock_getcpuclockid F
-GLIBC_2.4 clock_getres F
-GLIBC_2.4 clock_gettime F
-GLIBC_2.4 clock_nanosleep F
-GLIBC_2.4 clock_settime F
 GLIBC_2.4 lio_listio F
 GLIBC_2.4 lio_listio64 F
 GLIBC_2.4 mq_close F
diff --git a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
index f4a652966f..f2d8b916cb 100644
--- a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
+++ b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
@@ -20,6 +20,7 @@
 #include <time.h>
 #include <unistd.h>
 #include "kernel-posix-cpu-timers.h"
+#include <shlib-compat.h>
 
 int
 __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
@@ -45,4 +46,11 @@ __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
   else
     return INTERNAL_SYSCALL_ERRNO (r, err);
 }
-weak_alias (__clock_getcpuclockid, clock_getcpuclockid)
+
+versioned_symbol (libc, __clock_getcpuclockid, clock_getcpuclockid, GLIBC_2_17);
+/* clock_getcpuclockid moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_getcpuclockid, __clock_getcpuclockid_2);
+compat_symbol (libc, __clock_getcpuclockid_2, clock_getcpuclockid, GLIBC_2_2);
+#endif
diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
index 24b2299938..18a7ce53c0 100644
--- a/sysdeps/unix/sysv/linux/clock_getres.c
+++ b/sysdeps/unix/sysv/linux/clock_getres.c
@@ -26,10 +26,19 @@
 #endif
 #include <sysdep-vdso.h>
 
+#include <shlib-compat.h>
+
 /* Get resolution of clock.  */
 int
 __clock_getres (clockid_t clock_id, struct timespec *res)
 {
   return INLINE_VSYSCALL (clock_getres, 2, clock_id, res);
 }
-weak_alias (__clock_getres, clock_getres)
+
+versioned_symbol (libc, __clock_getres, clock_getres, GLIBC_2_17);
+/* clock_getres moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_getres, __clock_getres_2);
+compat_symbol (libc, __clock_getres_2, clock_getres, GLIBC_2_2);
+#endif
diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
index 5fc47fb7dc..7ad1c91be6 100644
--- a/sysdeps/unix/sysv/linux/clock_gettime.c
+++ b/sysdeps/unix/sysv/linux/clock_gettime.c
@@ -26,11 +26,20 @@
 #endif
 #include <sysdep-vdso.h>
 
+#include <shlib-compat.h>
+
 /* Get current value of CLOCK and store it in TP.  */
 int
 __clock_gettime (clockid_t clock_id, struct timespec *tp)
 {
   return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp);
 }
-weak_alias (__clock_gettime, clock_gettime)
 libc_hidden_def (__clock_gettime)
+
+versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17);
+/* clock_gettime moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_gettime, __clock_gettime_2);
+compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2);
+#endif
diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c
index 0cb6614dc9..e19e09d197 100644
--- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
+++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
@@ -21,6 +21,7 @@
 #include <sysdep-cancel.h>
 #include "kernel-posix-cpu-timers.h"
 
+#include <shlib-compat.h>
 
 /* We can simply use the syscall.  The CPU clocks are not supported
    with this function.  */
@@ -41,4 +42,11 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
   return (INTERNAL_SYSCALL_ERROR_P (r, err)
 	  ? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
 }
-weak_alias (__clock_nanosleep, clock_nanosleep)
+
+versioned_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_17);
+/* clock_nanosleep moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_nanosleep, __clock_nanosleep_2);
+compat_symbol (libc, __clock_nanosleep_2, clock_nanosleep, GLIBC_2_2);
+#endif
diff --git a/sysdeps/unix/sysv/linux/clock_settime.c b/sysdeps/unix/sysv/linux/clock_settime.c
index d837e3019c..0586d15722 100644
--- a/sysdeps/unix/sysv/linux/clock_settime.c
+++ b/sysdeps/unix/sysv/linux/clock_settime.c
@@ -18,6 +18,7 @@
 #include <errno.h>
 #include <sysdep.h>
 #include <time.h>
+#include <shlib-compat.h>
 
 #include "kernel-posix-cpu-timers.h"
 
@@ -34,4 +35,12 @@ __clock_settime (clockid_t clock_id, const struct timespec *tp)
 
   return INLINE_SYSCALL_CALL (clock_settime, clock_id, tp);
 }
-weak_alias (__clock_settime, clock_settime)
+libc_hidden_def (__clock_settime)
+
+versioned_symbol (libc, __clock_settime, clock_settime, GLIBC_2_17);
+/* clock_settime moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_settime, __clock_settime_2);
+compat_symbol (libc, __clock_settime_2, clock_settime, GLIBC_2_2);
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 75edece94a..df6d96fbae 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -615,6 +615,11 @@ GLIBC_2.2 clntudp_bufcreate F
 GLIBC_2.2 clntudp_create F
 GLIBC_2.2 clntunix_create F
 GLIBC_2.2 clock F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 clone F
 GLIBC_2.2 close F
 GLIBC_2.2 closedir F
diff --git a/sysdeps/unix/sysv/linux/hppa/librt.abilist b/sysdeps/unix/sysv/linux/hppa/librt.abilist
index 595f1b712a..bb03781dcc 100644
--- a/sysdeps/unix/sysv/linux/hppa/librt.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/librt.abilist
@@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
 GLIBC_2.1 aio_write64 F
 GLIBC_2.1 lio_listio F
 GLIBC_2.1 lio_listio64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 shm_open F
 GLIBC_2.2 shm_unlink F
 GLIBC_2.2 timer_create F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index edeaf8e722..fcb625b6bf 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -1869,6 +1869,11 @@ GLIBC_2.2 _flushlbf F
 GLIBC_2.2 _res_hconf D 0x30
 GLIBC_2.2 alphasort64 F
 GLIBC_2.2 bind_textdomain_codeset F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 dcngettext F
 GLIBC_2.2 dngettext F
 GLIBC_2.2 fgetpos F
diff --git a/sysdeps/unix/sysv/linux/i386/librt.abilist b/sysdeps/unix/sysv/linux/i386/librt.abilist
index 595f1b712a..bb03781dcc 100644
--- a/sysdeps/unix/sysv/linux/i386/librt.abilist
+++ b/sysdeps/unix/sysv/linux/i386/librt.abilist
@@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
 GLIBC_2.1 aio_write64 F
 GLIBC_2.1 lio_listio F
 GLIBC_2.1 lio_listio64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 shm_open F
 GLIBC_2.2 shm_unlink F
 GLIBC_2.2 timer_create F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index b5d460eeb2..cb556c5998 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -627,6 +627,11 @@ GLIBC_2.2 clntudp_bufcreate F
 GLIBC_2.2 clntudp_create F
 GLIBC_2.2 clntunix_create F
 GLIBC_2.2 clock F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 close F
 GLIBC_2.2 closedir F
 GLIBC_2.2 closelog F
diff --git a/sysdeps/unix/sysv/linux/ia64/librt.abilist b/sysdeps/unix/sysv/linux/ia64/librt.abilist
index 804622a14a..08384c9065 100644
--- a/sysdeps/unix/sysv/linux/ia64/librt.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/librt.abilist
@@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
 GLIBC_2.1 aio_write64 F
 GLIBC_2.1 lio_listio F
 GLIBC_2.1 lio_listio64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 shm_open F
 GLIBC_2.2 shm_unlink F
 GLIBC_2.2 timer_create F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 05633b3cb8..f3aa47d090 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -755,6 +755,11 @@ GLIBC_2.4 clntudp_bufcreate F
 GLIBC_2.4 clntudp_create F
 GLIBC_2.4 clntunix_create F
 GLIBC_2.4 clock F
+GLIBC_2.4 clock_getcpuclockid F
+GLIBC_2.4 clock_getres F
+GLIBC_2.4 clock_gettime F
+GLIBC_2.4 clock_nanosleep F
+GLIBC_2.4 clock_settime F
 GLIBC_2.4 clone F
 GLIBC_2.4 close F
 GLIBC_2.4 closedir F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist
index cfbbd27557..3c0647b251 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist
@@ -13,11 +13,6 @@ GLIBC_2.4 aio_suspend F
 GLIBC_2.4 aio_suspend64 F
 GLIBC_2.4 aio_write F
 GLIBC_2.4 aio_write64 F
-GLIBC_2.4 clock_getcpuclockid F
-GLIBC_2.4 clock_getres F
-GLIBC_2.4 clock_gettime F
-GLIBC_2.4 clock_nanosleep F
-GLIBC_2.4 clock_settime F
 GLIBC_2.4 lio_listio F
 GLIBC_2.4 lio_listio64 F
 GLIBC_2.4 mq_close F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 47eb7b4608..64d4623b6b 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1825,6 +1825,11 @@ GLIBC_2.2 _flushlbf F
 GLIBC_2.2 _res_hconf D 0x30
 GLIBC_2.2 alphasort64 F
 GLIBC_2.2 bind_textdomain_codeset F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 dcngettext F
 GLIBC_2.2 dngettext F
 GLIBC_2.2 fgetpos F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist
index 595f1b712a..bb03781dcc 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist
@@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
 GLIBC_2.1 aio_write64 F
 GLIBC_2.1 lio_listio F
 GLIBC_2.1 lio_listio64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 shm_open F
 GLIBC_2.2 shm_unlink F
 GLIBC_2.2 timer_create F
diff --git a/sysdeps/unix/sysv/linux/microblaze/librt.abilist b/sysdeps/unix/sysv/linux/microblaze/librt.abilist
index fb85d8729e..889dfbc0ee 100644
--- a/sysdeps/unix/sysv/linux/microblaze/librt.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/librt.abilist
@@ -14,11 +14,6 @@ GLIBC_2.18 aio_suspend F
 GLIBC_2.18 aio_suspend64 F
 GLIBC_2.18 aio_write F
 GLIBC_2.18 aio_write64 F
-GLIBC_2.18 clock_getcpuclockid F
-GLIBC_2.18 clock_getres F
-GLIBC_2.18 clock_gettime F
-GLIBC_2.18 clock_nanosleep F
-GLIBC_2.18 clock_settime F
 GLIBC_2.18 lio_listio F
 GLIBC_2.18 lio_listio64 F
 GLIBC_2.18 mq_close F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index e49dc4272e..06c2e64edd 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1612,6 +1612,11 @@ GLIBC_2.2 capget F
 GLIBC_2.2 capset F
 GLIBC_2.2 cbc_crypt F
 GLIBC_2.2 clntunix_create F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 creat64 F
 GLIBC_2.2 dcngettext F
 GLIBC_2.2 des_setparity F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist b/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist
index 84837c8a2e..1539c1cef9 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist
@@ -13,11 +13,6 @@ GLIBC_2.2 aio_suspend F
 GLIBC_2.2 aio_suspend64 F
 GLIBC_2.2 aio_write F
 GLIBC_2.2 aio_write64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 lio_listio F
 GLIBC_2.2 lio_listio64 F
 GLIBC_2.2 shm_open F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index daa3b60c5b..bdfd073b86 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1610,6 +1610,11 @@ GLIBC_2.2 capget F
 GLIBC_2.2 capset F
 GLIBC_2.2 cbc_crypt F
 GLIBC_2.2 clntunix_create F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 creat64 F
 GLIBC_2.2 dcngettext F
 GLIBC_2.2 des_setparity F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist b/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist
index 84837c8a2e..1539c1cef9 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist
@@ -13,11 +13,6 @@ GLIBC_2.2 aio_suspend F
 GLIBC_2.2 aio_suspend64 F
 GLIBC_2.2 aio_write F
 GLIBC_2.2 aio_write64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 lio_listio F
 GLIBC_2.2 lio_listio64 F
 GLIBC_2.2 shm_open F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 457ce0b6f2..3d61d4974a 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1611,6 +1611,11 @@ GLIBC_2.2 capget F
 GLIBC_2.2 capset F
 GLIBC_2.2 cbc_crypt F
 GLIBC_2.2 clntunix_create F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 creat64 F
 GLIBC_2.2 dcngettext F
 GLIBC_2.2 des_setparity F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 63d5c03bfb..675acca5db 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1607,6 +1607,11 @@ GLIBC_2.2 capget F
 GLIBC_2.2 capset F
 GLIBC_2.2 cbc_crypt F
 GLIBC_2.2 clntunix_create F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 creat64 F
 GLIBC_2.2 dcngettext F
 GLIBC_2.2 des_setparity F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 9200a54309..1e8ff6f83e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1830,6 +1830,11 @@ GLIBC_2.2 __xstat64 F
 GLIBC_2.2 _flushlbf F
 GLIBC_2.2 _res_hconf D 0x30
 GLIBC_2.2 bind_textdomain_codeset F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 dcngettext F
 GLIBC_2.2 dngettext F
 GLIBC_2.2 fgetpos F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
index 595f1b712a..bb03781dcc 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
@@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
 GLIBC_2.1 aio_write64 F
 GLIBC_2.1 lio_listio F
 GLIBC_2.1 lio_listio64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 shm_open F
 GLIBC_2.2 shm_unlink F
 GLIBC_2.2 timer_create F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index ef7779905f..b5a0751d90 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1834,6 +1834,11 @@ GLIBC_2.2 __xstat64 F
 GLIBC_2.2 _flushlbf F
 GLIBC_2.2 _res_hconf D 0x30
 GLIBC_2.2 bind_textdomain_codeset F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 dcngettext F
 GLIBC_2.2 dngettext F
 GLIBC_2.2 fgetpos F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 2860df8ebc..0c86217fc6 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -673,6 +673,11 @@ GLIBC_2.3 clntudp_bufcreate F
 GLIBC_2.3 clntudp_create F
 GLIBC_2.3 clntunix_create F
 GLIBC_2.3 clock F
+GLIBC_2.3 clock_getcpuclockid F
+GLIBC_2.3 clock_getres F
+GLIBC_2.3 clock_gettime F
+GLIBC_2.3 clock_nanosleep F
+GLIBC_2.3 clock_settime F
 GLIBC_2.3 clone F
 GLIBC_2.3 close F
 GLIBC_2.3 closedir F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/librt.abilist
index e76b7eb495..6a5bd96963 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/librt.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/librt.abilist
@@ -13,11 +13,6 @@ GLIBC_2.3 aio_suspend F
 GLIBC_2.3 aio_suspend64 F
 GLIBC_2.3 aio_write F
 GLIBC_2.3 aio_write64 F
-GLIBC_2.3 clock_getcpuclockid F
-GLIBC_2.3 clock_getres F
-GLIBC_2.3 clock_gettime F
-GLIBC_2.3 clock_nanosleep F
-GLIBC_2.3 clock_settime F
 GLIBC_2.3 lio_listio F
 GLIBC_2.3 lio_listio64 F
 GLIBC_2.3 shm_open F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 576295deff..122d0fb65a 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -1829,6 +1829,11 @@ GLIBC_2.2 _flushlbf F
 GLIBC_2.2 _res_hconf D 0x30
 GLIBC_2.2 alphasort64 F
 GLIBC_2.2 bind_textdomain_codeset F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 dcngettext F
 GLIBC_2.2 dngettext F
 GLIBC_2.2 fgetpos F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist
index 595f1b712a..bb03781dcc 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist
@@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
 GLIBC_2.1 aio_write64 F
 GLIBC_2.1 lio_listio F
 GLIBC_2.1 lio_listio64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 shm_open F
 GLIBC_2.2 shm_unlink F
 GLIBC_2.2 timer_create F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index abf0473683..efe588a072 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -632,6 +632,11 @@ GLIBC_2.2 clntudp_bufcreate F
 GLIBC_2.2 clntudp_create F
 GLIBC_2.2 clntunix_create F
 GLIBC_2.2 clock F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 clone F
 GLIBC_2.2 close F
 GLIBC_2.2 closedir F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist
index 41be3bb84b..5905498a48 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist
@@ -13,11 +13,6 @@ GLIBC_2.2 aio_suspend F
 GLIBC_2.2 aio_suspend64 F
 GLIBC_2.2 aio_write F
 GLIBC_2.2 aio_write64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 lio_listio F
 GLIBC_2.2 lio_listio64 F
 GLIBC_2.2 shm_open F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index 41977f6e9c..4b057bf4a2 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -618,6 +618,11 @@ GLIBC_2.2 clntudp_bufcreate F
 GLIBC_2.2 clntudp_create F
 GLIBC_2.2 clntunix_create F
 GLIBC_2.2 clock F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 clone F
 GLIBC_2.2 close F
 GLIBC_2.2 closedir F
diff --git a/sysdeps/unix/sysv/linux/sh/librt.abilist b/sysdeps/unix/sysv/linux/sh/librt.abilist
index 595f1b712a..bb03781dcc 100644
--- a/sysdeps/unix/sysv/linux/sh/librt.abilist
+++ b/sysdeps/unix/sysv/linux/sh/librt.abilist
@@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
 GLIBC_2.1 aio_write64 F
 GLIBC_2.1 lio_listio F
 GLIBC_2.1 lio_listio64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 shm_open F
 GLIBC_2.2 shm_unlink F
 GLIBC_2.2 timer_create F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 3d2f00ca52..49cd597fd6 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1826,6 +1826,11 @@ GLIBC_2.2 __xstat64 F
 GLIBC_2.2 _flushlbf F
 GLIBC_2.2 _res_hconf D 0x30
 GLIBC_2.2 bind_textdomain_codeset F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 dcngettext F
 GLIBC_2.2 dngettext F
 GLIBC_2.2 fgetpos F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist
index cb874f4147..38f0aad791 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist
@@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
 GLIBC_2.1 aio_write64 F
 GLIBC_2.1 lio_listio F
 GLIBC_2.1 lio_listio64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 shm_open F
 GLIBC_2.2 shm_unlink F
 GLIBC_2.2 timer_create F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 2f20643e8e..95e68e0ba1 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -660,6 +660,11 @@ GLIBC_2.2 clntudp_bufcreate F
 GLIBC_2.2 clntudp_create F
 GLIBC_2.2 clntunix_create F
 GLIBC_2.2 clock F
+GLIBC_2.2 clock_getcpuclockid F
+GLIBC_2.2 clock_getres F
+GLIBC_2.2 clock_gettime F
+GLIBC_2.2 clock_nanosleep F
+GLIBC_2.2 clock_settime F
 GLIBC_2.2 clone F
 GLIBC_2.2 close F
 GLIBC_2.2 closedir F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist
index d7a049cf60..71f86e03ce 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist
@@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
 GLIBC_2.1 aio_write64 F
 GLIBC_2.1 lio_listio F
 GLIBC_2.1 lio_listio64 F
-GLIBC_2.2 clock_getcpuclockid F
-GLIBC_2.2 clock_getres F
-GLIBC_2.2 clock_gettime F
-GLIBC_2.2 clock_nanosleep F
-GLIBC_2.2 clock_settime F
 GLIBC_2.2 shm_open F
 GLIBC_2.2 shm_unlink F
 GLIBC_2.2 timer_create F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 59f85d9373..1f2dbd1451 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -621,6 +621,11 @@ GLIBC_2.2.5 clntudp_bufcreate F
 GLIBC_2.2.5 clntudp_create F
 GLIBC_2.2.5 clntunix_create F
 GLIBC_2.2.5 clock F
+GLIBC_2.2.5 clock_getcpuclockid F
+GLIBC_2.2.5 clock_getres F
+GLIBC_2.2.5 clock_gettime F
+GLIBC_2.2.5 clock_nanosleep F
+GLIBC_2.2.5 clock_settime F
 GLIBC_2.2.5 clone F
 GLIBC_2.2.5 close F
 GLIBC_2.2.5 closedir F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist b/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist
index e2e8b60bf8..95e3f22daa 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist
@@ -13,11 +13,6 @@ GLIBC_2.2.5 aio_suspend F
 GLIBC_2.2.5 aio_suspend64 F
 GLIBC_2.2.5 aio_write F
 GLIBC_2.2.5 aio_write64 F
-GLIBC_2.2.5 clock_getcpuclockid F
-GLIBC_2.2.5 clock_getres F
-GLIBC_2.2.5 clock_gettime F
-GLIBC_2.2.5 clock_nanosleep F
-GLIBC_2.2.5 clock_settime F
 GLIBC_2.2.5 lio_listio F
 GLIBC_2.2.5 lio_listio64 F
 GLIBC_2.2.5 shm_open F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 67a4e238d6..59da85a5d8 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -660,6 +660,11 @@ GLIBC_2.16 clntudp_create F
 GLIBC_2.16 clntunix_create F
 GLIBC_2.16 clock F
 GLIBC_2.16 clock_adjtime F
+GLIBC_2.16 clock_getcpuclockid F
+GLIBC_2.16 clock_getres F
+GLIBC_2.16 clock_gettime F
+GLIBC_2.16 clock_nanosleep F
+GLIBC_2.16 clock_settime F
 GLIBC_2.16 clone F
 GLIBC_2.16 close F
 GLIBC_2.16 closedir F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist
index 94e84e4dcf..66969fb9ab 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist
@@ -14,11 +14,6 @@ GLIBC_2.16 aio_suspend F
 GLIBC_2.16 aio_suspend64 F
 GLIBC_2.16 aio_write F
 GLIBC_2.16 aio_write64 F
-GLIBC_2.16 clock_getcpuclockid F
-GLIBC_2.16 clock_getres F
-GLIBC_2.16 clock_gettime F
-GLIBC_2.16 clock_nanosleep F
-GLIBC_2.16 clock_settime F
 GLIBC_2.16 lio_listio F
 GLIBC_2.16 lio_listio64 F
 GLIBC_2.16 mq_close F
diff --git a/time/Makefile b/time/Makefile
index a428f55245..85a62c0376 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -36,14 +36,18 @@ routines := offtime asctime clock ctime ctime_r difftime \
 	    stime dysize timegm ftime			 \
 	    getdate strptime strptime_l			 \
 	    strftime wcsftime strftime_l wcsftime_l	 \
-	    timespec_get
+	    timespec_get 	 			 \
+	    clock_getcpuclockid clock_getres 		 \
+	    clock_gettime clock_settime clock_nanosleep
+
 aux :=	    era alt_digit lc-time-cleanup
 
 tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
 	   tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
 	   tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
 	   tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime \
-	   tst-tzname tst-y2039 bug-mktime4 tst-strftime2 tst-strftime3
+	   tst-tzname tst-y2039 bug-mktime4 tst-strftime2 tst-strftime3 \
+	   tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1
 
 include ../Rules
 
diff --git a/time/Versions b/time/Versions
index fd838181e4..8788e192ce 100644
--- a/time/Versions
+++ b/time/Versions
@@ -49,6 +49,10 @@ libc {
   GLIBC_2.2 {
     # w*
     wcsftime;
+
+    # c*; actually in librt in version 2.2, moved to libc in 2.17
+    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
+    clock_nanosleep;
   }
   GLIBC_2.3 {
     # these internal names are used by libstdc++
@@ -65,4 +69,13 @@ libc {
   GLIBC_2.16 {
     timespec_get;
   }
+  GLIBC_2.17 {
+    # c*
+    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
+    clock_nanosleep;
+  }
+  GLIBC_PRIVATE {
+    # same as clock_gettime; used in other libraries
+    __clock_gettime;
+  }
 }
diff --git a/rt/clock_getcpuclockid.c b/time/clock_getcpuclockid.c
similarity index 75%
rename from rt/clock_getcpuclockid.c
rename to time/clock_getcpuclockid.c
index 22b9f1383c..8d205abfa9 100644
--- a/rt/clock_getcpuclockid.c
+++ b/time/clock_getcpuclockid.c
@@ -19,6 +19,7 @@
 #include <errno.h>
 #include <time.h>
 #include <unistd.h>
+#include <shlib-compat.h>
 
 int
 __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
@@ -37,4 +38,10 @@ __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
   return ENOENT;
 #endif
 }
-weak_alias (__clock_getcpuclockid, clock_getcpuclockid)
+versioned_symbol (libc, __clock_getcpuclockid, clock_getcpuclockid, GLIBC_2_17);
+/* clock_getcpuclockid moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_getcpuclockid, __clock_getcpuclockid_2);
+compat_symbol (libc, __clock_getcpuclockid_2, clock_getcpuclockid, GLIBC_2_2);
+#endif
diff --git a/rt/clock_getres.c b/time/clock_getres.c
similarity index 73%
rename from rt/clock_getres.c
rename to time/clock_getres.c
index b990bf0af0..412f80fbec 100644
--- a/rt/clock_getres.c
+++ b/time/clock_getres.c
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <time.h>
+#include <shlib-compat.h>
 
 /* Get resolution of clock.  */
 int
@@ -26,5 +27,13 @@ __clock_getres (clockid_t clock_id, struct timespec *res)
   __set_errno (ENOSYS);
   return -1;
 }
-weak_alias (__clock_getres, clock_getres)
+
+versioned_symbol (libc, __clock_getres, clock_getres, GLIBC_2_17);
+/* clock_getres moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_getres, __clock_getres_2);
+compat_symbol (libc, __clock_getres_2, clock_getres, GLIBC_2_2);
+#endif
+
 stub_warning (clock_getres)
diff --git a/rt/clock_gettime.c b/time/clock_gettime.c
similarity index 74%
rename from rt/clock_gettime.c
rename to time/clock_gettime.c
index 0426dd2c76..92c6081dcb 100644
--- a/rt/clock_gettime.c
+++ b/time/clock_gettime.c
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <time.h>
+#include <shlib-compat.h>
 
 /* Get current value of CLOCK and store it in TP.  */
 int
@@ -26,6 +27,14 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp)
   __set_errno (ENOSYS);
   return -1;
 }
-weak_alias (__clock_gettime, clock_gettime)
 libc_hidden_def (__clock_gettime)
+
+versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17);
+/* clock_gettime moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_gettime, __clock_gettime_2);
+compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2);
+#endif
+
 stub_warning (clock_gettime)
diff --git a/rt/clock_nanosleep.c b/time/clock_nanosleep.c
similarity index 76%
rename from rt/clock_nanosleep.c
rename to time/clock_nanosleep.c
index 5b724e593b..c53c820880 100644
--- a/rt/clock_nanosleep.c
+++ b/time/clock_nanosleep.c
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <time.h>
+#include <shlib-compat.h>
 
 int
 __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
@@ -33,5 +34,13 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
   /* Not implemented.  */
   return ENOSYS;
 }
-weak_alias (__clock_nanosleep, clock_nanosleep)
+
+versioned_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_17);
+/* clock_nanosleep moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_nanosleep, __clock_nanosleep_2);
+compat_symbol (libc, __clock_nanosleep_2, clock_nanosleep, GLIBC_2_2);
+#endif
+
 stub_warning (clock_nanosleep)
diff --git a/rt/clock_settime.c b/time/clock_settime.c
similarity index 71%
rename from rt/clock_settime.c
rename to time/clock_settime.c
index 891925ab2c..dd86a1c189 100644
--- a/rt/clock_settime.c
+++ b/time/clock_settime.c
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <time.h>
+#include <shlib-compat.h>
 
 /* Set CLOCK to value TP.  */
 int
@@ -26,5 +27,14 @@ __clock_settime (clockid_t clock_id, const struct timespec *tp)
   __set_errno (ENOSYS);
   return -1;
 }
-weak_alias (__clock_settime, clock_settime)
+libc_hidden_def (__clock_settime)
+
+versioned_symbol (libc, __clock_settime, clock_settime, GLIBC_2_17);
+/* clock_settime moved to libc in version 2.17;
+   old binaries may expect the symbol version it had in librt.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_settime, __clock_settime_2);
+compat_symbol (libc, __clock_settime_2, clock_settime, GLIBC_2_2);
+#endif
+
 stub_warning (clock_settime)
diff --git a/rt/tst-clock.c b/time/tst-clock.c
similarity index 100%
rename from rt/tst-clock.c
rename to time/tst-clock.c
diff --git a/rt/tst-clock2.c b/time/tst-clock2.c
similarity index 100%
rename from rt/tst-clock2.c
rename to time/tst-clock2.c
diff --git a/rt/tst-clock_nanosleep.c b/time/tst-clock_nanosleep.c
similarity index 100%
rename from rt/tst-clock_nanosleep.c
rename to time/tst-clock_nanosleep.c
diff --git a/rt/tst-cpuclock1.c b/time/tst-cpuclock1.c
similarity index 100%
rename from rt/tst-cpuclock1.c
rename to time/tst-cpuclock1.c
-- 
2.23.0


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

* [PATCH v2 03/10] Use clock_settime to implement stime; withdraw stime.
  2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
  2019-08-28 15:32 ` [PATCH v2 01/10] Change most internal uses of __gettimeofday to __clock_gettime Zack Weinberg
  2019-08-28 15:32 ` [PATCH v2 02/10] Finish move of clock_* functions to libc Zack Weinberg
@ 2019-08-28 15:32 ` Zack Weinberg
  2019-08-30 17:54   ` Adhemerval Zanella
  2019-08-28 15:32 ` [PATCH v2 04/10] Use clock_settime to implement settimeofday Zack Weinberg
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 15:32 UTC (permalink / raw)
  To: libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

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.

	* time/stime.c (stime): No longer a stub implementation.
	Call __clock_settime.  Demote to a compatibility symbol.

	* sysdeps/unix/stime.c: Delete file.
	* sysdeps/unix/sysv/linux/syscalls.list: Remove entry for stime.

	* time/time.h: Remove prototype for stime.
---
 sysdeps/unix/stime.c                  | 39 ---------------------------
 sysdeps/unix/sysv/linux/syscalls.list |  1 -
 time/stime.c                          | 25 ++++++++---------
 time/time.h                           |  6 -----
 4 files changed, 13 insertions(+), 58 deletions(-)
 delete mode 100644 sysdeps/unix/stime.c

diff --git a/sysdeps/unix/stime.c b/sysdeps/unix/stime.c
deleted file mode 100644
index b0809be400..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
-   <http://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 de58c49562..754e2da0b0 100644
--- a/time/stime.c
+++ b/time/stime.c
@@ -15,23 +15,24 @@
    License along with the GNU C Library; if not, see
    <http://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 cba6d15260..57cfd4d330 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.23.0


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

* [PATCH v2 04/10] Use clock_settime to implement settimeofday.
  2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
                   ` (2 preceding siblings ...)
  2019-08-28 15:32 ` [PATCH v2 03/10] Use clock_settime to implement stime; withdraw stime Zack Weinberg
@ 2019-08-28 15:32 ` Zack Weinberg
  2019-09-02 13:22   ` Adhemerval Zanella
  2019-08-28 15:32 ` [PATCH v2 05/10] Use clock_gettime to implement time Zack Weinberg
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 15:32 UTC (permalink / raw)
  To: libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

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 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.

	* time/settimeofday.c (settimeofday): No longer a stub
	implementation.  Call __clock_settime or __settimezone depending
	on arguments.  Optionally override the default symbol version for
	settimeofday.
	* include/sys/time.h: Remove prototype for __settimeofday.
	Add prototype for __settimezone.
	* sysdeps/unix/syscalls.list: Remove entry for settimeofday.

	* time/settimezone.c: New file.
	(__settimezone): New stub implementation.
	* sysdeps/unix/sysv/linux/settimezone.c: New file.
	(__settimezone): Implement using settimeofday system call,
	if available.
	* time/Makefile (routines): Add settimezone.

	* sysdeps/unix/sysv/linux/alpha/syscalls.list:
	Remove entries for settimeofday and osf_settimeofday.
	* sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
	New file, defines settimeofday@GLIBC_2.0.
	* sysdeps/unix/sysv/linux/alpha/settimeofday.c:
	New file, defines settimeofday@@GLIBC_2.1.

	* sysdeps/unix/clock_gettime.c: Delete file.
	* sysdeps/mach/hurd/settimeofday.c: Rename to
	sysdeps/mach/hurd/clock_settime.c and convert into an
	implementation of clock_settime.
---
 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         | 39 ++++++++++++++
 time/Makefile                                 |  8 +--
 time/settimeofday.c                           | 24 +++++++--
 .../hurd/settimeofday.c => time/settimezone.c | 34 ++-----------
 10 files changed, 126 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/include/sys/time.h b/include/sys/time.h
index 7ba0ca7c2d..a57752e8c7 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 5b398491ab..0a32f8d1a0 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 475e0fd656..9221deb80f 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..823f4fe42f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/settimezone.c
@@ -0,0 +1,39 @@
+/* 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.  */
+
+#ifdef __NR_settimeofday
+
+int
+__settimezone (const struct timezone *tz)
+{
+  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
+}
+
+#else
+
+#include <time/settimezone.c>
+
+#endif
diff --git a/time/Makefile b/time/Makefile
index 85a62c0376..791db1c8e3 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 4620559652..78f666e352 100644
--- a/time/settimeofday.c
+++ b/time/settimeofday.c
@@ -16,6 +16,7 @@
    <http://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 bd0ffd64ac..eb005da213 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.23.0


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

* [PATCH v2 05/10] Use clock_gettime to implement time.
  2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
                   ` (3 preceding siblings ...)
  2019-08-28 15:32 ` [PATCH v2 04/10] Use clock_settime to implement settimeofday Zack Weinberg
@ 2019-08-28 15:32 ` Zack Weinberg
  2019-08-28 18:16   ` Florian Weimer
  2019-08-28 15:32 ` [PATCH v2 06/10] Use clock_gettime to implement ftime; withdraw ftime Zack Weinberg
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 15:32 UTC (permalink / raw)
  To: libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

Most ports were using gettimeofday to implement time, or they were
making a direct (v)syscall.  Unconditionally switch to using
clock_gettime instead.  All sysdeps implementations of time are
removed.

	* time/time.c (time): No longer a stub implementation.
	Call __clock_gettime.

	* sysdeps/unix/sysv/linux/powerpc/Versions (GLIBC_PRIVATE):
	Remove __vdso_time.
	* sysdeps/unix/sysv/linux/powerpc/init-first.c (__vdso_time): Delete.
	(_libc_vdso_platform_setup): Don't initialize __vdso_time.
	* sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list: Remove entry
	for time.

	* sysdeps/posix/time.c
	* sysdeps/unix/sysv/linux/time.c
	* sysdeps/unix/sysv/linux/i386/time.c
	* sysdeps/unix/sysv/linux/powerpc/time.c
	* sysdeps/unix/sysv/linux/sparc/sparc64/time.c
	* sysdeps/unix/sysv/linux/x86/time.c:
	Delete file.
---
 sysdeps/posix/time.c                          | 40 ---------
 sysdeps/unix/sysv/linux/i386/time.c           | 34 --------
 sysdeps/unix/sysv/linux/powerpc/Versions      |  1 -
 sysdeps/unix/sysv/linux/powerpc/init-first.c  |  5 --
 sysdeps/unix/sysv/linux/powerpc/time.c        | 84 -------------------
 sysdeps/unix/sysv/linux/sparc/sparc64/time.c  |  1 -
 sysdeps/unix/sysv/linux/time.c                | 41 ---------
 sysdeps/unix/sysv/linux/x86/time.c            | 59 -------------
 .../unix/sysv/linux/x86_64/x32/syscalls.list  |  1 -
 time/time.c                                   | 12 ++-
 10 files changed, 5 insertions(+), 273 deletions(-)
 delete mode 100644 sysdeps/posix/time.c
 delete mode 100644 sysdeps/unix/sysv/linux/i386/time.c
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/time.c
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/time.c
 delete mode 100644 sysdeps/unix/sysv/linux/time.c
 delete mode 100644 sysdeps/unix/sysv/linux/x86/time.c

diff --git a/sysdeps/posix/time.c b/sysdeps/posix/time.c
deleted file mode 100644
index e1b3bc8d4c..0000000000
--- a/sysdeps/posix/time.c
+++ /dev/null
@@ -1,40 +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
-   <http://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)
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
deleted file mode 100644
index 440e3e6ab4..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
-   <http://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/powerpc/Versions b/sysdeps/unix/sysv/linux/powerpc/Versions
index 8ebeea15a1..859e0d7daf 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Versions
+++ b/sysdeps/unix/sysv/linux/powerpc/Versions
@@ -10,7 +10,6 @@ libc {
     __vdso_clock_gettime;
     __vdso_clock_getres;
     __vdso_getcpu;
-    __vdso_time;
   }
 }
 libm {
diff --git a/sysdeps/unix/sysv/linux/powerpc/init-first.c b/sysdeps/unix/sysv/linux/powerpc/init-first.c
index 831f910788..4f12b59e76 100644
--- a/sysdeps/unix/sysv/linux/powerpc/init-first.c
+++ b/sysdeps/unix/sysv/linux/powerpc/init-first.c
@@ -25,7 +25,6 @@ int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
 int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
 unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void);
 int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *);
-time_t (*VDSO_SYMBOL(time)) (time_t *);
 
 #if defined(__PPC64__) || defined(__powerpc64__)
 void *VDSO_SYMBOL(sigtramp_rt64);
@@ -59,10 +58,6 @@ _libc_vdso_platform_setup (void)
   PTR_MANGLE (p);
   VDSO_SYMBOL (getcpu) = p;
 
-  p = _dl_vdso_vsym ("__kernel_time", &linux2615);
-  PTR_MANGLE (p);
-  VDSO_SYMBOL (time) = p;
-
   /* PPC64 uses only one signal trampoline symbol, while PPC32 will use
      two depending if SA_SIGINFO is used (__kernel_sigtramp_rt32) or not
      (__kernel_sigtramp32).
diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c
deleted file mode 100644
index cb3e8b9a73..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/time.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* time system call for Linux/PowerPC.
-   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
-   <http://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>
-
-# ifndef __powerpc64__
-#  undef time
-
-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;
-}
-
-# define INIT_ARCH()						\
-  PREPARE_VERSION_KNOWN (linux2615, LINUX_2_6_15);		\
-  void *vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615);
-
-/* 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)
-
-#else
-
-#include <sysdeps/posix/time.c>
-
-#endif /* !SHARED */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/time.c b/sysdeps/unix/sysv/linux/sparc/sparc64/time.c
deleted file mode 100644
index 509b580c55..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/time.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/posix/time.c>
diff --git a/sysdeps/unix/sysv/linux/time.c b/sysdeps/unix/sysv/linux/time.c
deleted file mode 100644
index 1978f6d817..0000000000
--- a/sysdeps/unix/sysv/linux/time.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (C) 2005-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 <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
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
deleted file mode 100644
index 3d72488500..0000000000
--- a/sysdeps/unix/sysv/linux/x86/time.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* time -- Get number of seconds since Epoch.  Linux/x86 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
-   <http://www.gnu.org/licenses/>.  */
-
-#include <time.h>
-
-#ifdef SHARED
-
-#include <dl-vdso.h>
-#include <errno.h>
-
-static time_t
-__time_syscall (time_t *t)
-{
-  INTERNAL_SYSCALL_DECL (err);
-  return INTERNAL_SYSCALL (time, err, 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
-
-#undef INIT_ARCH
-#define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
-/* If the vDSO is not available we fall back on the syscall.  */
-libc_ifunc_hidden (time_type, time,
-		   (_dl_vdso_vsym ("__vdso_time", &linux26)
-		    ?:  &__time_syscall))
-libc_hidden_def (time)
-
-#else
-
-# include <sysdep.h>
-
-time_t
-time (time_t *t)
-{
-  INTERNAL_SYSCALL_DECL (err);
-  return INTERNAL_SYSCALL (time, err, 1, t);
-}
-
-#endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
index b44f6f99e9..c0cfa7b0da 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
@@ -3,4 +3,3 @@
 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/time.c b/time/time.c
index 88612d6c76..bae0fd14dd 100644
--- a/time/time.c
+++ b/time/time.c
@@ -15,19 +15,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
 #include <time.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 (CLOCK_REALTIME, &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.23.0


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

* [PATCH v2 06/10] Use clock_gettime to implement ftime; withdraw ftime.
  2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
                   ` (4 preceding siblings ...)
  2019-08-28 15:32 ` [PATCH v2 05/10] Use clock_gettime to implement time Zack Weinberg
@ 2019-08-28 15:32 ` Zack Weinberg
  2019-09-02 18:42   ` Adhemerval Zanella
  2019-08-28 15:32 ` [PATCH v2 07/10] Use clock_gettime to implement timespec_get Zack Weinberg
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 15:32 UTC (permalink / raw)
  To: libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

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 made a compatibility symbol.  The public
header file that declared it, its result structure, and nothing else,
is removed.

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.

	* time/tst-ftime.c
	* time/sys/timeb.h
	* sysdeps/unix/bsd/ftime.c
	* sysdeps/unix/sysv/linux/ftime.c: Delete file.
	* time/tst-ftime_l.c: Rename to tst-strftime_l.c.

	* time/ftime.c (ftime): Make a compatibility-only symbol.
	Replace implementation with the code formerly in
	sysdeps/unix/bsd/ftime.c, then change that code to use
	__clock_gettime instead of __gettimeofday and to truncate
	rather than rounding.  Always set the timezone and dstflag
	fields of the timebuf argument to zero.

	* time/Makefile (headers): Remove sys/timeb.h.
	(tests): Remove tst-ftime, change tst-ftime_l to
	tst-strftime_l.

	* conform/Makefile: XFAIL all tests related to sys/timeb.h.
---
 conform/Makefile                         |  9 ++++
 sysdeps/unix/bsd/ftime.c                 | 40 ----------------
 sysdeps/unix/sysv/linux/ftime.c          |  3 --
 time/Makefile                            |  8 ++--
 time/ftime.c                             | 40 +++++++++-------
 time/sys/timeb.h                         | 43 ------------------
 time/tst-ftime.c                         | 58 ------------------------
 time/{tst-ftime_l.c => tst-strftime_l.c} |  0
 8 files changed, 36 insertions(+), 165 deletions(-)
 delete mode 100644 sysdeps/unix/bsd/ftime.c
 delete mode 100644 sysdeps/unix/sysv/linux/ftime.c
 delete mode 100644 time/sys/timeb.h
 delete mode 100644 time/tst-ftime.c
 rename time/{tst-ftime_l.c => tst-strftime_l.c} (100%)

diff --git a/conform/Makefile b/conform/Makefile
index 59d569c4c5..8671c695e8 100644
--- a/conform/Makefile
+++ b/conform/Makefile
@@ -241,3 +241,12 @@ test-xfail-XPG42/ndbm.h/linknamespace = yes
 test-xfail-UNIX98/ndbm.h/linknamespace = yes
 test-xfail-XOPEN2K/ndbm.h/linknamespace = yes
 test-xfail-XOPEN2K8/ndbm.h/linknamespace = yes
+
+# Header no longer provided by glibc (obsoleted in newer POSIX
+# standards).
+test-xfail-UNIX98/sys/timeb.h/conform = yes
+test-xfail-UNIX98/sys/timeb.h/linknamespace = yes
+test-xfail-XOPEN2K/sys/timeb.h/conform = yes
+test-xfail-XOPEN2K/sys/timeb.h/linknamespace = yes
+test-xfail-XPG42/sys/timeb.h/conform = yes
+test-xfail-XPG42/sys/timeb.h/linknamespace = yes
diff --git a/sysdeps/unix/bsd/ftime.c b/sysdeps/unix/bsd/ftime.c
deleted file mode 100644
index 3a1c6e9b01..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
-   <http://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/Makefile b/time/Makefile
index 791db1c8e3..93c7cc28d4 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -22,7 +22,7 @@ subdir	:= time
 
 include ../Makeconfig
 
-headers := time.h sys/time.h sys/timeb.h bits/time.h			\
+headers := time.h sys/time.h bits/time.h				\
 	   bits/types/clockid_t.h bits/types/clock_t.h			\
 	   bits/types/struct_itimerspec.h				\
 	   bits/types/struct_timespec.h bits/types/struct_timeval.h	\
@@ -43,9 +43,9 @@ routines := offtime asctime clock ctime ctime_r difftime \
 aux :=	    era alt_digit lc-time-cleanup
 
 tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
-	   tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
+	   tst-getdate tst-mktime tst-mktime2 tst-strftime tst-strftime_l \
 	   tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
-	   tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime \
+	   tst-strptime3 bug-getdate1 tst-strptime-whitespace \
 	   tst-tzname tst-y2039 bug-mktime4 tst-strftime2 tst-strftime3 \
 	   tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1
 
@@ -59,7 +59,7 @@ LOCALES := de_DE.ISO-8859-1 en_US.ISO-8859-1 ja_JP.EUC-JP fr_FR.UTF-8 \
 	   nan_TW.UTF-8 lzh_TW.UTF-8
 include ../gen-locales.mk
 
-$(objpfx)tst-ftime_l.out: $(gen-locales)
+$(objpfx)tst-strftime_l.out: $(gen-locales)
 $(objpfx)tst-strptime.out: $(gen-locales)
 endif
 
diff --git a/time/ftime.c b/time/ftime.c
index 6c2a256048..0db6b70adf 100644
--- a/time/ftime.c
+++ b/time/ftime.c
@@ -15,27 +15,33 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <time.h>
-#include <sys/timeb.h>
+#include <shlib-compat.h>
 
-int
-ftime (struct timeb *timebuf)
-{
-  int save = errno;
-  struct tm tp;
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_31)
 
-  __set_errno (0);
-  if (time (&timebuf->time) == (time_t) -1 && errno != 0)
-    return -1;
-  timebuf->millitm = 0;
+#include <time.h>
 
-  if (__localtime_r (&timebuf->time, &tp) == NULL)
-    return -1;
+struct timeb
+{
+  time_t time;			/* Seconds since epoch, as from `time'.  */
+  unsigned short int millitm;	/* Additional milliseconds.  */
+  short int timezone;		/* Minutes west of GMT.  */
+  short int dstflag;		/* Nonzero if Daylight Savings Time used.  */
+};
 
-  timebuf->timezone = tp.tm_gmtoff / 60;
-  timebuf->dstflag = tp.tm_isdst;
+int
+attribute_compat_text_section
+__ftime (struct timeb *timebuf)
+{
+  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;
 }
+compat_symbol (libc, __ftime, ftime, GLIBC_2_0);
+
+#endif
diff --git a/time/sys/timeb.h b/time/sys/timeb.h
deleted file mode 100644
index 6333e8074d..0000000000
--- a/time/sys/timeb.h
+++ /dev/null
@@ -1,43 +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
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_TIMEB_H
-#define _SYS_TIMEB_H	1
-
-#include <features.h>
-
-#include <bits/types/time_t.h>
-
-__BEGIN_DECLS
-
-/* Structure returned by the `ftime' function.  */
-
-struct timeb
-  {
-    time_t time;		/* Seconds since epoch, as from `time'.  */
-    unsigned short int millitm;	/* Additional milliseconds.  */
-    short int timezone;		/* Minutes west of GMT.  */
-    short int dstflag;		/* Nonzero if Daylight Savings Time used.  */
-  };
-
-/* Fill in TIMEBUF with information about the current time.  */
-
-extern int ftime (struct timeb *__timebuf);
-
-__END_DECLS
-
-#endif	/* sys/timeb.h */
diff --git a/time/tst-ftime.c b/time/tst-ftime.c
deleted file mode 100644
index 65b753dec8..0000000000
--- a/time/tst-ftime.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Verify that ftime is sane.
-   Copyright (C) 2014-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sys/timeb.h>
-#include <stdio.h>
-
-static int
-do_test (void)
-{
-  struct timeb prev, curr = {.time = 0, .millitm = 0};
-  int sec = 0;
-
-  while (sec != 3)
-    {
-      prev = curr;
-
-      if (ftime (&curr))
-        {
-          printf ("ftime returned an error\n");
-          return 1;
-        }
-
-      if (curr.time < prev.time)
-        {
-          printf ("ftime's time flowed backwards\n");
-          return 1;
-        }
-
-      if (curr.time == prev.time
-          && curr.millitm < prev.millitm)
-        {
-          printf ("ftime's millitm flowed backwards\n");
-          return 1;
-        }
-
-      if (curr.time > prev.time)
-        sec ++;
-    }
-  return 0;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/time/tst-ftime_l.c b/time/tst-strftime_l.c
similarity index 100%
rename from time/tst-ftime_l.c
rename to time/tst-strftime_l.c
-- 
2.23.0


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

* [PATCH v2 07/10] Use clock_gettime to implement timespec_get.
  2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
                   ` (5 preceding siblings ...)
  2019-08-28 15:32 ` [PATCH v2 06/10] Use clock_gettime to implement ftime; withdraw ftime Zack Weinberg
@ 2019-08-28 15:32 ` Zack Weinberg
  2019-09-02 19:25   ` Adhemerval Zanella
  2019-08-28 15:32 ` [PATCH v2 08/10] Use clock_gettime to implement gettimeofday Zack Weinberg
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 15:32 UTC (permalink / raw)
  To: libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

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.

As such I think the most sensible GNUish policy for this function is
that we will provide it, but we will not recommend its use, we will
not go out of our way to make it efficient, and we will not attempt to
extend the set of TIME_* constants beyond the ones defined in ISO
C (and in POSIX, if it ever appears in POSIX).

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.  Oh well.

	* sysdeps/posix/timespec_get.c
	* sysdeps/unix/sysv/linux/timespec_get.c: Delete file.
	* time/timespec_get.c: No longer a stub.  Replace implementation
	with the code formerly in sysdeps/posix/timespec_get.c.
---
 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 781a624c7d..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
-   <http://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 52080ddf08..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
-   <http://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 c9e58be5d8..5ac765add1 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.23.0


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

* [PATCH v2 08/10] Use clock_gettime to implement gettimeofday.
  2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
                   ` (6 preceding siblings ...)
  2019-08-28 15:32 ` [PATCH v2 07/10] Use clock_gettime to implement timespec_get Zack Weinberg
@ 2019-08-28 15:32 ` Zack Weinberg
  2019-08-28 18:27   ` Florian Weimer
  2019-08-28 15:32 ` [PATCH v2 09/10] Warn when gettimeofday is called with non-null tzp argument Zack Weinberg
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 15:32 UTC (permalink / raw)
  To: libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

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.

Most Linux ports supplied a vDSO symbol for gettimeofday, and some
wrapped that with an ifunc, so this patch deletes a lot of code.
For ease of future edits to the many copies of _libc_vdso_platform_setup,
the variable "p" in each is now declared separately from any use of it.

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.

	* time/gettimeofday.c: No longer a stub implementation.
	Call __clock_gettime.  If tz argument is not NULL, clear the
	object it points to.  Remove libc_hidden_* for __gettimeofday
	and gettimeofday.  Optionally override the default symbol
	version for gettimeofday and __gettimeofday.
	* include/sys/time.h: Remove internal prototype and libc_hidden_proto
	for __gettimeofday, and libc_hidden_proto for gettimeofday.

	* sysdeps/unix/sysv/linux/alpha/gettimeofday.c: Switch to
	including time/gettimeofday.c.

	* sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
	(gettimeofday@GLIBC_2.0): Use __clock_gettime instead of __gettimeofday.
	If tz argument is not NULL, clear the object it points to.

	* sysdeps/unix/sysv/linux/aarch64/init-first.c
	* sysdeps/unix/sysv/linux/arm/init-first.c
	* sysdeps/unix/sysv/linux/mips/init-first.c
	* sysdeps/unix/sysv/linux/powerpc/init-first.c
	* sysdeps/unix/sysv/linux/riscv/init-first.c
	* sysdeps/unix/sysv/linux/s390/init-first.c
	* sysdeps/unix/sysv/linux/sparc/init-first.c:
	Do not define nor initialize VDSO_SYMBOL(gettimeofday).

	* sysdeps/unix/sysv/linux/aarch64/libc-vdso.h
	* sysdeps/unix/sysv/linux/arm/libc-vdso.h
	* sysdeps/unix/sysv/linux/mips/libc-vdso.h
	* sysdeps/unix/sysv/linux/powerpc/libc-vdso.h
	* sysdeps/unix/sysv/linux/riscv/libc-vdso.h
	* sysdeps/unix/sysv/linux/s390/libc-vdso.h
	* sysdeps/unix/sysv/linux/sparc/libc-vdso.h:
	Do not declare VDSO_SYMBOL(gettimeofday).

	* sysdeps/unix/syscalls.list: Remove entry for gettimeofday.
	* sysdeps/unix/sysv/linux/alpha/syscalls.list:
	Remove entries for gettimeofday and osf_gettimeofday.
	* sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list:
	Remove entry for gettimeofday.

	* sysdeps/posix/gettimeofday.c
	* sysdeps/unix/clock_gettime.c
	* sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
	* sysdeps/unix/sysv/linux/gettimeofday.c
	* sysdeps/unix/sysv/linux/i386/gettimeofday.c
	* sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
	* sysdeps/unix/sysv/linux/x86/gettimeofday.c: Delete file.

	* sysdeps/mach/gettimeofday.c: Rename to
	sysdeps/mach/clock_gettime.c and convert into an
	implementation of clock_gettime.
---
 include/sys/time.h                            |  4 -
 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    | 71 ----------------
 sysdeps/unix/sysv/linux/aarch64/init-first.c  |  7 +-
 sysdeps/unix/sysv/linux/aarch64/libc-vdso.h   |  2 -
 .../sysv/linux/{i386 => alpha}/gettimeofday.c | 25 ++----
 .../unix/sysv/linux/alpha/osf_gettimeofday.c  | 11 ++-
 sysdeps/unix/sysv/linux/alpha/syscalls.list   |  1 -
 sysdeps/unix/sysv/linux/arm/init-first.c      |  7 +-
 sysdeps/unix/sysv/linux/arm/libc-vdso.h       |  2 -
 sysdeps/unix/sysv/linux/gettimeofday.c        | 49 -----------
 sysdeps/unix/sysv/linux/mips/init-first.c     |  7 +-
 sysdeps/unix/sysv/linux/mips/libc-vdso.h      |  2 -
 .../unix/sysv/linux/powerpc/gettimeofday.c    | 85 -------------------
 sysdeps/unix/sysv/linux/powerpc/init-first.c  |  8 +-
 sysdeps/unix/sysv/linux/powerpc/libc-vdso.h   |  2 -
 sysdeps/unix/sysv/linux/riscv/init-first.c    | 10 +--
 sysdeps/unix/sysv/linux/riscv/libc-vdso.h     |  2 -
 sysdeps/unix/sysv/linux/s390/init-first.c     |  9 +-
 sysdeps/unix/sysv/linux/s390/libc-vdso.h      |  3 -
 sysdeps/unix/sysv/linux/sparc/init-first.c    |  8 +-
 sysdeps/unix/sysv/linux/sparc/libc-vdso.h     |  2 -
 sysdeps/unix/sysv/linux/x86/gettimeofday.c    | 61 -------------
 .../unix/sysv/linux/x86_64/x32/syscalls.list  |  1 -
 time/gettimeofday.c                           | 32 ++++---
 28 files changed, 67 insertions(+), 492 deletions(-)
 rename sysdeps/{unix => mach}/clock_gettime.c (65%)
 delete mode 100644 sysdeps/mach/gettimeofday.c
 delete mode 100644 sysdeps/posix/gettimeofday.c
 delete mode 100644 sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
 rename sysdeps/unix/sysv/linux/{i386 => alpha}/gettimeofday.c (58%)
 delete mode 100644 sysdeps/unix/sysv/linux/gettimeofday.c
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
 delete mode 100644 sysdeps/unix/sysv/linux/x86/gettimeofday.c

diff --git a/include/sys/time.h b/include/sys/time.h
index a57752e8c7..4a91622096 100644
--- a/include/sys/time.h
+++ b/include/sys/time.h
@@ -20,10 +20,6 @@
 # include <time/sys/time.h>
 
 # 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 2a82fc1066..56f518bd16 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 8d0dfbb7dc..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
-   <http://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 6ba625e13e..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
-   <http://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
deleted file mode 100644
index 9180b50bf7..0000000000
--- a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright (C) 2018-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/>.  */
-
-/* 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.  */
-
-#ifdef SHARED
-
-# define __gettimeofday __redirect___gettimeofday
-# include <sys/time.h>
-# undef __gettimeofday
-# define HAVE_VSYSCALL
-# include <dl-vdso.h>
-# 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)
-{
-  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
-}
-
-/* PREPARE_VERSION_KNOWN will need an __LP64__ ifdef when ILP32 support
-   goes in.  See _libc_vdso_platform_setup in
-   sysdeps/unix/sysv/linux/aarch64/init-first.c.  */
-
-# undef INIT_ARCH
-# define INIT_ARCH() \
-	   PREPARE_VERSION_KNOWN (linux_version, LINUX_2_6_39); \
-	   void *vdso_gettimeofday = \
-	     _dl_vdso_vsym ("__kernel_gettimeofday", &linux_version);
-
-libc_ifunc_hidden (__redirect___gettimeofday, __gettimeofday,
-		   vdso_gettimeofday ?: (void *) __gettimeofday_vsyscall)
-
-__hidden_ver1 (__gettimeofday_vsyscall, __GI___gettimeofday,
-	       __gettimeofday_vsyscall);
-
-#else
-
-# include <sys/time.h>
-# include <sysdep.h>
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-libc_hidden_def (__gettimeofday)
-
-#endif
-
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/aarch64/init-first.c b/sysdeps/unix/sysv/linux/aarch64/init-first.c
index 80f7ed91ef..5e4e1fbf8c 100644
--- a/sysdeps/unix/sysv/linux/aarch64/init-first.c
+++ b/sysdeps/unix/sysv/linux/aarch64/init-first.c
@@ -19,23 +19,20 @@
 #include <dl-vdso.h>
 #include <libc-vdso.h>
 
-int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden;
 int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
 int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
 
 static inline void
 _libc_vdso_platform_setup (void)
 {
+  void *p;
+
 #ifdef __LP64__
   PREPARE_VERSION_KNOWN (linux_version, LINUX_2_6_39);
 #else
   PREPARE_VERSION_KNOWN (linux_version, LINUX_4_9);
 #endif
 
-  void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux_version);
-  PTR_MANGLE (p);
-  VDSO_SYMBOL(gettimeofday) = p;
-
   p = _dl_vdso_vsym ("__kernel_clock_gettime", &linux_version);
   PTR_MANGLE (p);
   VDSO_SYMBOL(clock_gettime) = p;
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc-vdso.h b/sysdeps/unix/sysv/linux/aarch64/libc-vdso.h
index 3fcbaa9fce..285ca62fd3 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/aarch64/libc-vdso.h
@@ -22,8 +22,6 @@
 #include <sysdep.h>
 #include <sysdep-vdso.h>
 
-extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
-   attribute_hidden;
 extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
 extern int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
 
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 185450ece6..46dc778427 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
    <http://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 5122f7edac..5ff890d1ca 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/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list
index 95a27e18e8..7cb51f9f4d 100644
--- a/sysdeps/unix/sysv/linux/alpha/syscalls.list
+++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list
@@ -23,7 +23,6 @@ pciconfig_write	EXTRA	pciconfig_write	5	pciconfig_write
 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
 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/arm/init-first.c b/sysdeps/unix/sysv/linux/arm/init-first.c
index e1846df661..c73970d06d 100644
--- a/sysdeps/unix/sysv/linux/arm/init-first.c
+++ b/sysdeps/unix/sysv/linux/arm/init-first.c
@@ -21,17 +21,14 @@
 #include <libc-vdso.h>
 #include <sysdep-vdso.h>
 
-int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden;
 int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
 
 static inline void
 _libc_vdso_platform_setup (void)
 {
-  PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
+  void *p;
 
-  void *p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux26);
-  PTR_MANGLE (p);
-  VDSO_SYMBOL (gettimeofday) = p;
+  PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
 
   p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
   PTR_MANGLE (p);
diff --git a/sysdeps/unix/sysv/linux/arm/libc-vdso.h b/sysdeps/unix/sysv/linux/arm/libc-vdso.h
index 8702165c6b..b7ae61def6 100644
--- a/sysdeps/unix/sysv/linux/arm/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/arm/libc-vdso.h
@@ -22,8 +22,6 @@
 
 #include <sysdep-vdso.h>
 
-extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
-   attribute_hidden;
 extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
 
 #endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
deleted file mode 100644
index 0c86245981..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
-   <http://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/mips/init-first.c b/sysdeps/unix/sysv/linux/mips/init-first.c
index 25884ffd80..a7c3643cb8 100644
--- a/sysdeps/unix/sysv/linux/mips/init-first.c
+++ b/sysdeps/unix/sysv/linux/mips/init-first.c
@@ -20,17 +20,14 @@
 #include <dl-vdso.h>
 #include <libc-vdso.h>
 
-int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden;
 int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
 
 static inline void
 _libc_vdso_platform_setup (void)
 {
-  PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
+  void *p;
 
-  void *p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux26);
-  PTR_MANGLE (p);
-  VDSO_SYMBOL (gettimeofday) = p;
+  PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
 
   p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
   PTR_MANGLE (p);
diff --git a/sysdeps/unix/sysv/linux/mips/libc-vdso.h b/sysdeps/unix/sysv/linux/mips/libc-vdso.h
index 344ea2d750..e0a8fe4a80 100644
--- a/sysdeps/unix/sysv/linux/mips/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/mips/libc-vdso.h
@@ -22,8 +22,6 @@
 
 #include <sysdep-vdso.h>
 
-extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
-   attribute_hidden;
 extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
 
 #endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
deleted file mode 100644
index 463b678ad9..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (C) 2005-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/>.  */
-
-#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>
-
-# 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);
-
-# endif /* !__powerpc64__  */
-
-static int
-__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-
-# define INIT_ARCH()						\
-  PREPARE_VERSION_KNOWN (linux2615, LINUX_2_6_15);		\
-  void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
-
-/* 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)
-
-#else
-
-# include <sysdep.h>
-# include <errno.h>
-
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
-libc_hidden_def (__gettimeofday)
-
-#endif
-weak_alias (__gettimeofday, gettimeofday)
-libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/powerpc/init-first.c b/sysdeps/unix/sysv/linux/powerpc/init-first.c
index 4f12b59e76..166bf3f2fe 100644
--- a/sysdeps/unix/sysv/linux/powerpc/init-first.c
+++ b/sysdeps/unix/sysv/linux/powerpc/init-first.c
@@ -19,8 +19,6 @@
 #include <dl-vdso.h>
 #include <libc-vdso.h>
 
-int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
-  attribute_hidden;
 int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
 int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
 unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void);
@@ -36,11 +34,9 @@ void *VDSO_SYMBOL(sigtramp_rt32);
 static inline void
 _libc_vdso_platform_setup (void)
 {
-  PREPARE_VERSION_KNOWN (linux2615, LINUX_2_6_15);
+  void *p;
 
-  void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
-  PTR_MANGLE (p);
-  VDSO_SYMBOL (gettimeofday) = p;
+  PREPARE_VERSION_KNOWN (linux2615, LINUX_2_6_15);
 
   p = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2615);
   PTR_MANGLE (p);
diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h
index f8184061c0..e233ea18a5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/powerpc/libc-vdso.h
@@ -23,8 +23,6 @@
 #include <sysdep.h>
 #include <sysdep-vdso.h>
 
-extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
-  attribute_hidden;
 extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
 extern int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
 extern unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void);
diff --git a/sysdeps/unix/sysv/linux/riscv/init-first.c b/sysdeps/unix/sysv/linux/riscv/init-first.c
index 98a8ce33ad..014d770861 100644
--- a/sysdeps/unix/sysv/linux/riscv/init-first.c
+++ b/sysdeps/unix/sysv/linux/riscv/init-first.c
@@ -22,8 +22,6 @@
 
 long int (*VDSO_SYMBOL (getcpu)) (unsigned int *, unsigned int *, void *)
     attribute_hidden;
-long int (*VDSO_SYMBOL (gettimeofday)) (struct timeval *, void *)
-    attribute_hidden;
 long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *)
     attribute_hidden;
 long int (*VDSO_SYMBOL (clock_getres)) (clockid_t, struct timespec *)
@@ -32,16 +30,14 @@ long int (*VDSO_SYMBOL (clock_getres)) (clockid_t, struct timespec *)
 static inline void
 _libc_vdso_platform_setup (void)
 {
+  void *p;
+
   PREPARE_VERSION_KNOWN (linux_version, LINUX_4_15);
 
-  void *p = _dl_vdso_vsym ("__vdso_getcpu", &linux_version);
+  p = _dl_vdso_vsym ("__vdso_getcpu", &linux_version);
   PTR_MANGLE (p);
   VDSO_SYMBOL (getcpu) = p;
 
-  p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux_version);
-  PTR_MANGLE (p);
-  VDSO_SYMBOL (gettimeofday) = p;
-
   p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux_version);
   PTR_MANGLE (p);
   VDSO_SYMBOL (clock_gettime) = p;
diff --git a/sysdeps/unix/sysv/linux/riscv/libc-vdso.h b/sysdeps/unix/sysv/linux/riscv/libc-vdso.h
index 2373292ab9..e9a5b239b9 100644
--- a/sysdeps/unix/sysv/linux/riscv/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/riscv/libc-vdso.h
@@ -24,8 +24,6 @@
 
 extern long int (*VDSO_SYMBOL (getcpu)) (unsigned int *, unsigned int *, void *)
     attribute_hidden;
-extern long int (*VDSO_SYMBOL (gettimeofday)) (struct timeval *, void *)
-    attribute_hidden;
 extern long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *)
     attribute_hidden;
 extern long int (*VDSO_SYMBOL (clock_getres)) (clockid_t, struct timespec *)
diff --git a/sysdeps/unix/sysv/linux/s390/init-first.c b/sysdeps/unix/sysv/linux/s390/init-first.c
index a1ad9458e3..3a55935886 100644
--- a/sysdeps/unix/sysv/linux/s390/init-first.c
+++ b/sysdeps/unix/sysv/linux/s390/init-first.c
@@ -19,9 +19,6 @@
 #include <dl-vdso.h>
 #include <libc-vdso.h>
 
-long int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
-   attribute_hidden;
-
 long int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *)
   __attribute__ ((nocommon));
 
@@ -34,11 +31,9 @@ long int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *, void *)
 static inline void
 _libc_vdso_platform_setup (void)
 {
-  PREPARE_VERSION_KNOWN (linux2629, LINUX_2_6_29);
+  void *p;
 
-  void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2629);
-  PTR_MANGLE (p);
-  VDSO_SYMBOL (gettimeofday) = p;
+  PREPARE_VERSION_KNOWN (linux2629, LINUX_2_6_29);
 
   p = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2629);
   PTR_MANGLE (p);
diff --git a/sysdeps/unix/sysv/linux/s390/libc-vdso.h b/sysdeps/unix/sysv/linux/s390/libc-vdso.h
index cc97601383..2cdf44583a 100644
--- a/sysdeps/unix/sysv/linux/s390/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/s390/libc-vdso.h
@@ -22,9 +22,6 @@
 
 #include <sysdep-vdso.h>
 
-extern long int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
-   attribute_hidden;
-
 extern long int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
 
 extern long int (*VDSO_SYMBOL(clock_getres)) (clockid_t, struct timespec *);
diff --git a/sysdeps/unix/sysv/linux/sparc/init-first.c b/sysdeps/unix/sysv/linux/sparc/init-first.c
index 643d6c7c88..520fc25808 100644
--- a/sysdeps/unix/sysv/linux/sparc/init-first.c
+++ b/sysdeps/unix/sysv/linux/sparc/init-first.c
@@ -20,19 +20,15 @@
 #include <dl-vdso.h>
 #include <libc-vdso.h>
 
-long int (*VDSO_SYMBOL (gettimeofday)) (struct timeval *, void *)
-    attribute_hidden;
 long int (*VDSO_SYMBOL (clock_gettime)) (clockid_t, struct timespec *)
     attribute_hidden;
 
 static inline void
 _libc_vdso_platform_setup (void)
 {
-  PREPARE_VERSION_KNOWN (linux_version, LINUX_2_6);
+  void *p;
 
-  void *p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux_version);
-  PTR_MANGLE (p);
-  VDSO_SYMBOL (gettimeofday) = p;
+  PREPARE_VERSION_KNOWN (linux_version, LINUX_2_6);
 
   p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux_version);
   PTR_MANGLE (p);
diff --git a/sysdeps/unix/sysv/linux/sparc/libc-vdso.h b/sysdeps/unix/sysv/linux/sparc/libc-vdso.h
index d20afcdf04..28d1229587 100644
--- a/sysdeps/unix/sysv/linux/sparc/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/sparc/libc-vdso.h
@@ -22,8 +22,6 @@
 
 #include <sysdep-vdso.h>
 
-extern long int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
-   attribute_hidden;
 extern long int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
 
 #endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
deleted file mode 100644
index 8886ccd707..0000000000
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* gettimeofday - get the time.  Linux/x86 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
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sys/time.h>
-
-#ifdef SHARED
-
-# include <dl-vdso.h>
-# include <errno.h>
-
-static int
-__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (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
-
-# undef INIT_ARCH
-# define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6)
-/* If the vDSO is not available we fall back to syscall.  */
-libc_ifunc_hidden (__gettimeofday_type, __gettimeofday,
-		   (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
-		    ?: &__gettimeofday_syscall))
-libc_hidden_def (__gettimeofday)
-
-#else
-
-# include <sysdep.h>
-# include <errno.h>
-
-int
-__gettimeofday (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (gettimeofday, 2, 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/syscalls.list b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
index c0cfa7b0da..58ea31d1fd 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/syscalls.list
@@ -1,5 +1,4 @@
 # 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
diff --git a/time/gettimeofday.c b/time/gettimeofday.c
index 1004ec8911..c4f642631f 100644
--- a/time/gettimeofday.c
+++ b/time/gettimeofday.c
@@ -15,20 +15,32 @@
    License along with the GNU C Library; if not, see
    <http://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.23.0


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

* [PATCH v2 09/10] Warn when gettimeofday is called with non-null tzp argument.
  2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
                   ` (7 preceding siblings ...)
  2019-08-28 15:32 ` [PATCH v2 08/10] Use clock_gettime to implement gettimeofday Zack Weinberg
@ 2019-08-28 15:32 ` Zack Weinberg
  2019-09-03 19:56   ` Adhemerval Zanella
  2019-08-28 15:32 ` [PATCH v2 10/10] Revise the documentation of simple calendar time Zack Weinberg
  2019-08-28 17:15 ` [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Joseph Myers
  10 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 15:32 UTC (permalink / raw)
  To: libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

Since there are no known uses of gettimeofday's vestigial "get time
zone" feature that are not bugs, add a fortify-style wrapper inline to
sys/time.h that issues a warning whenever gettimeofday is called with
a second argument that is not a compile-time null pointer
constant.

At present this is only possible with GCC; clang does not implement
attribute((warning)).  The wrapper is only activated when __OPTIMIZE__
is defined because it throws false positives when optimization is off,
even though it's an always-inline function.

An oversight in the implementation of __builtin_constant_p causes it
to fail to detect compile-time *pointer* constants unless they are
cast to an integer of a different size.  (Loss of data in this cast is
harmless; the overall expression is still constant if and only if the
original pointer was.)  This is GCC bug 95514.  Thanks to
Kamil Cukrowski <kamilcukrowski@gmail.com> for the workaround.
As a precaution, I added a static assertion to debug/warning-nop.c to
make sure that the cast _is_ casting to an integer of a different
size; this is too unlikely a scenario to be worth checking in the
public header, but if someone ever adds a port where short is the
same size as intptr_t, we'll still catch it.

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

	* time/sys/time.h (__timezone_ptr_t): Delete.
	(gettimeofday): Always declare second argument with type "void *".
	When possible, wrap with a fortify-style inline function that
	detects non-null or non-constant second argument and issues a
	warning.  Improve commentary.
	(settimeofday): Improve commentary.

	* time/gettimeofday.c (gettimeofday): Declare second argument with
	type "void *".
	* debug/warning-nop.c: Include sys/time.h and stdint.h.
	Add static_assert to verify the requirements of the workaround
	for GCC bug 95514.
---
 debug/warning-nop.c |  9 +++++++++
 time/gettimeofday.c |  4 ++--
 time/sys/time.h     | 47 ++++++++++++++++++++++++++++++++++-----------
 3 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/debug/warning-nop.c b/debug/warning-nop.c
index 8eeea396c3..3eab53b78f 100644
--- a/debug/warning-nop.c
+++ b/debug/warning-nop.c
@@ -67,4 +67,13 @@ nop (void)
 #define __builtin___strncpy_chk(dest, src, len, bos) NULL
 #define __builtin_object_size(bos, level) 0
 
+/* The code in sys/time.h that uses __warndecl has to work around GCC
+    bug 91554.  The work-around is only effective if intptr_t is not
+    the same size as short.  */
+#include <stdint.h>
+_Static_assert (sizeof (intptr_t) != sizeof (short),
+                "workaround for GCC bug 91554 in sys/time.h"
+                " is only effective when short is smaller than a pointer");
+
 #include <string.h>
+#include <sys/time.h>
diff --git a/time/gettimeofday.c b/time/gettimeofday.c
index c4f642631f..5bc91fc214 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 5dbc7fc627..a4e7fd20d1 100644
--- a/time/sys/time.h
+++ b/time/sys/time.h
@@ -54,23 +54,48 @@ 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));
+
+#if __GNUC_PREREQ (4,3) && defined __REDIRECT && defined __OPTIMIZE__
+/* Issue a warning for use of gettimeofday with a non-null __tz argument.  */
+__warndecl (__warn_gettimeofday_nonnull_timezone,
+            "gettimeofday with non-null or non-constant timezone parameter;"
+            " this is obsolete and inaccurate, use localtime instead");
+
+extern int __REDIRECT_NTH (__gettimeofday_alias,
+                           (struct timeval *__restrict __tv,
+                            void *__restrict __tz), gettimeofday)
+  __nonnull ((1));
+
+/* The double cast below works around a limitation in __builtin_constant_p
+   in all released versions of GCC (as of August 2019).
+   See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91554>.  */
+__fortify_function int
+__NTH (gettimeofday (struct timeval *__restrict __tv, void *__restrict __tz))
+{
+  if (! (__builtin_constant_p ((short) (__intptr_t) __tz) && __tz == 0))
+    __warn_gettimeofday_nonnull_timezone ();
+
+  return __gettimeofday_alias (__tv, __tz);
+}
+#endif
 
 #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.23.0


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

* [PATCH v2 10/10] Revise the documentation of simple calendar time.
  2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
                   ` (8 preceding siblings ...)
  2019-08-28 15:32 ` [PATCH v2 09/10] Warn when gettimeofday is called with non-null tzp argument Zack Weinberg
@ 2019-08-28 15:32 ` Zack Weinberg
  2019-08-29  1:09   ` Paul Eggert
  2019-08-28 17:15 ` [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Joseph Myers
  10 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 15:32 UTC (permalink / raw)
  To: libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

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."

ChangeLog:
	* manual/time.texi: Major revision of text related to simple
	calendar time.  clock_gettime, clock_getres, and clock_settime
	are now documented.
	* manual/filesys.texi, manual/llio.texi, manual/threads.texi:
	Update cross-references to renamed sections in time.texi.
---
 NEWS                |   62 ++-
 manual/filesys.texi |    2 +-
 manual/llio.texi    |   10 +-
 manual/threads.texi |    2 +-
 manual/time.texi    | 1071 ++++++++++++++++++++++++-------------------
 5 files changed, 673 insertions(+), 474 deletions(-)

diff --git a/NEWS b/NEWS
index a64b89986a..75453bbda8 100644
--- a/NEWS
+++ b/NEWS
@@ -3,7 +3,7 @@ Copyright (C) 1992-2019 Free Software Foundation, Inc.
 See the end for copying conditions.
 
 Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
-using `glibc' in the "product" field.
+using ‘glibc’ in the "product" field.
 \f
 Version 2.31
 
@@ -30,6 +30,66 @@ 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 functions ftime and stime are no longer available to newly
+  linked binaries, and the header <sys/timeb.h> has been removed.  Programs
+  that used these functions should be updated to use clock_gettime and
+  clock_settime, respectively.
+
+* On Linux-based systems, glibc now uses the clock_gettime and clock_settime
+  system calls to implement all of the other functions that get or set
+  the time: time, ftime, gettimeofday, timespec_get, stime, and settimeofday.
+
+  System calls and/or vDSO functions, if any, that directly implement these
+  functions will no longer be used, with one exception: ‘settimeofday’ may
+  still invoke the system call of the same name when its ‘tzp’ argument is
+  not a null pointer (see below).
+
+  This change was made because the Linux kernel maintainers intend to
+  provide only clock_gettime and clock_settime system calls on future new
+  architectures, and to deprecate the other system calls on existing
+  architectures.  It potentially breaks programs that use seccomp filters to
+  limit the set of system calls a process can use.
+
+* The gettimeofday function will no longer report information about a
+  system-wide time zone.
+
+  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.
+
+  A similar change has been made to the obsolete function ftime.
+
+* 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/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..b3f02254f4 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,418 @@ 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)}}
+and @code{gettimeofday} (see below).
+
+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}
+System-wide clock measuring calendar time.  This clock reports the
+same time as @code{time} (above) and @code{gettimeofday} (below) and
+uses the POSIX epoch, 00:00:00 on January 1, 1970, Coordinated
+Universal Time.
+@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}.  @code{gettimeofday} uses the same clock as
+@code{time} and @w{@samp{clock_gettime (CLOCK_REALTIME)}}.
+
+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 +849,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 +864,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 +951,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 +1283,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 +2839,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 +3024,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.23.0


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

* Re: [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions.
  2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
                   ` (9 preceding siblings ...)
  2019-08-28 15:32 ` [PATCH v2 10/10] Revise the documentation of simple calendar time Zack Weinberg
@ 2019-08-28 17:15 ` Joseph Myers
  2019-09-03 14:43   ` Zack Weinberg
  10 siblings, 1 reply; 44+ messages in thread
From: Joseph Myers @ 2019-08-28 17:15 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: libc-alpha, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

On Wed, 28 Aug 2019, Zack Weinberg wrote:

>  - The obsolete functions ftime and stime are no longer available to
>    new binaries.  The header <sys/timeb.h> is no longer installed.

It might be advisable to see if this affects the build of libsanitizer, 
and alert sanitizer maintainers if so.  (There appear to be sanitizer 
interceptors for ftime and stime, and an include of <sys/timeb.h>.)

After comments at last year's Cauldron about glibc API changes breaking 
sanitizers and language libraries such as libgo, I added a --full-gcc 
option to build-many-glibcs.py with the hope that the people raising such 
issues would set up bots to monitor for them, but I don't think anyone has 
set up such a bot (and there were a series of pre-existing build issues 
using that option, as well as the need to have a new-enough native Ada 
compiler in the PATH when using it).

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH v2 05/10] Use clock_gettime to implement time.
  2019-08-28 15:32 ` [PATCH v2 05/10] Use clock_gettime to implement time Zack Weinberg
@ 2019-08-28 18:16   ` Florian Weimer
  2019-08-28 18:36     ` Zack Weinberg
  2019-08-28 20:01     ` Paul Eggert
  0 siblings, 2 replies; 44+ messages in thread
From: Florian Weimer @ 2019-08-28 18:16 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: libc-alpha, Joseph Myers, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

* Zack Weinberg:

> Most ports were using gettimeofday to implement time, or they were
> making a direct (v)syscall.  Unconditionally switch to using
> clock_gettime instead.  All sysdeps implementations of time are
> removed.

I'm sorry, but this is clearly not advisable because clock_gettime is
almost an order of magnitude slower than time.

A synthetic benchmark with back-to-back time calls takes 2.3 ns on a
Xeon Gold 6126 CPU, but 17.9 ns on your branch.

Given that time has no stringent accuracy requirements, this shouldn't
come as a surprise.

Thanks,
Florian

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

* Re: [PATCH v2 08/10] Use clock_gettime to implement gettimeofday.
  2019-08-28 15:32 ` [PATCH v2 08/10] Use clock_gettime to implement gettimeofday Zack Weinberg
@ 2019-08-28 18:27   ` Florian Weimer
  2019-09-02 19:31     ` Adhemerval Zanella
  0 siblings, 1 reply; 44+ messages in thread
From: Florian Weimer @ 2019-08-28 18:27 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: libc-alpha, Joseph Myers, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

* Zack Weinberg:

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

This comes at a performance cost.  On a Xeon Gold 6126 with Fedora 31's
5.3.0-0.rc5.git0.1.fc31 kernel, I see 17.6 ns per gettimeofday call
before this change, and 19.6 ns afterwards.

Part of that is the additional overhead of the functional call and the
clock check.  I think gettimeofday should call directly into the vDSO.

Another part according to profiles is the downscaling of the nanoseconds
value.  TIMESPEC_TO_TIMEVAL does not tell GCC that tv_nsec member does
not use the full long range, so GCC emits a full 64-bit division (with a
multiplication and shift).

Both changes will hopefully recover the performance loss.

Thanks,
Florian

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

* Re: [PATCH v2 05/10] Use clock_gettime to implement time.
  2019-08-28 18:16   ` Florian Weimer
@ 2019-08-28 18:36     ` Zack Weinberg
  2019-08-28 18:49       ` Florian Weimer
  2019-08-28 20:01     ` Paul Eggert
  1 sibling, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-28 18:36 UTC (permalink / raw)
  To: Florian Weimer
  Cc: GNU C Library, Joseph Myers, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

On Wed, Aug 28, 2019 at 2:16 PM Florian Weimer <fweimer@redhat.com> wrote:
>
> * Zack Weinberg:
>
> > Most ports were using gettimeofday to implement time, or they were
> > making a direct (v)syscall.  Unconditionally switch to using
> > clock_gettime instead.  All sysdeps implementations of time are
> > removed.
>
> I'm sorry, but this is clearly not advisable because clock_gettime is
> almost an order of magnitude slower than time.

Hmm.  How do we reconcile this with the (Linux) kernel maintainers'
stated intentions to provide only clock_gettime in the future?  We
could use CLOCK_REALTIME_COARSE when available, I suppose; can you see
whether that recovers the lost performance, or else send me your
benchmark code so I can try it?

zw

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

* Re: [PATCH v2 05/10] Use clock_gettime to implement time.
  2019-08-28 18:36     ` Zack Weinberg
@ 2019-08-28 18:49       ` Florian Weimer
  0 siblings, 0 replies; 44+ messages in thread
From: Florian Weimer @ 2019-08-28 18:49 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: GNU C Library, Joseph Myers, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

* Zack Weinberg:

> On Wed, Aug 28, 2019 at 2:16 PM Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * Zack Weinberg:
>>
>> > Most ports were using gettimeofday to implement time, or they were
>> > making a direct (v)syscall.  Unconditionally switch to using
>> > clock_gettime instead.  All sysdeps implementations of time are
>> > removed.
>>
>> I'm sorry, but this is clearly not advisable because clock_gettime is
>> almost an order of magnitude slower than time.
>
> Hmm.  How do we reconcile this with the (Linux) kernel maintainers'
> stated intentions to provide only clock_gettime in the future?  We
> could use CLOCK_REALTIME_COARSE when available, I suppose; can you see
> whether that recovers the lost performance, or else send me your
> benchmark code so I can try it?

I see 4.9 ns with CLOCK_REALTIME_COARSE, compared to 2.2 ns for time.
It still looks significantly slower to me.

We also have to be careful not to use clocks that don't stay in the vDSO
on all supported kernel/hypervisor combinations.

Benchmark code is below.

Thanks,
Florian

#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>

int
main (int argc, char **argv)
{
  int count;
  if (argc != 3 || (count = atoi (argv[2])) <= 0)
    err (1, "usage: %s METHOD ITERATIONS", argv[0]);

  if (strcmp (argv[1], "time") == 0)
    for (int i = 0; i < count; ++i)
      time (NULL);
  else if (strcmp (argv[1], "gettimeofday") == 0)
    for (int i = 0; i < count; ++i)
      {
        struct timeval tv;
        gettimeofday (&tv, NULL);
      }
  else if (strcmp (argv[1], "realtime") == 0)
    for (int i = 0; i < count; ++i)
      {
        struct timespec tv;
        clock_gettime (CLOCK_REALTIME, &tv);
      }
  else if (strcmp (argv[1], "realtime_coarse") == 0)
    for (int i = 0; i < count; ++i)
      {
        struct timespec tv;
        clock_gettime (CLOCK_REALTIME_COARSE, &tv);
      }
  else if (strcmp (argv[1], "monotonic") == 0)
    for (int i = 0; i < count; ++i)
      {
        struct timespec tv;
        clock_gettime (CLOCK_MONOTONIC, &tv);
      }
  else if (strcmp (argv[1], "monotonic_coarse") == 0)
    for (int i = 0; i < count; ++i)
      {
        struct timespec tv;
        clock_gettime (CLOCK_MONOTONIC_COARSE, &tv);
      }
  else if (strcmp (argv[1], "monotonic_raw") == 0)
    for (int i = 0; i < count; ++i)
      {
        struct timespec tv;
        clock_gettime (CLOCK_MONOTONIC_RAW, &tv);
      }
  else
    errx (1, "invalid clock: %s", argv[1]);

  return 0;
}

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

* Re: [PATCH v2 05/10] Use clock_gettime to implement time.
  2019-08-28 18:16   ` Florian Weimer
  2019-08-28 18:36     ` Zack Weinberg
@ 2019-08-28 20:01     ` Paul Eggert
  2019-08-28 20:21       ` Florian Weimer
  1 sibling, 1 reply; 44+ messages in thread
From: Paul Eggert @ 2019-08-28 20:01 UTC (permalink / raw)
  To: Florian Weimer, Zack Weinberg
  Cc: libc-alpha, Joseph Myers, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

Florian Weimer wrote:
> Given that time has no stringent accuracy requirements, this shouldn't
> come as a surprise.

In what sense does 'time' have less-stringent accuracy requirements than 
clock_gettime (CLOCK_REALTIME) does? Can 'time' return a value that disagrees 
with the time_t part of what clock_gettime (CLOCK_REALTIME) returns? Any such 
disagreement would cause application bugs that could well be unlikely and hard 
to track down; also, if there is disagreement, replacing calls to 'time' with 
calls to clock_gettime might not be advisable even aside from performance issues.

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

* Re: [PATCH v2 05/10] Use clock_gettime to implement time.
  2019-08-28 20:01     ` Paul Eggert
@ 2019-08-28 20:21       ` Florian Weimer
  2019-08-28 21:12         ` Paul Eggert
  0 siblings, 1 reply; 44+ messages in thread
From: Florian Weimer @ 2019-08-28 20:21 UTC (permalink / raw)
  To: Paul Eggert
  Cc: Zack Weinberg, libc-alpha, Joseph Myers, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Adhemerval Zanella, Samuel Thibault

* Paul Eggert:

> Florian Weimer wrote:
>> Given that time has no stringent accuracy requirements, this shouldn't
>> come as a surprise.
>
> In what sense does 'time' have less-stringent accuracy requirements
> than clock_gettime (CLOCK_REALTIME) does? Can 'time' return a value
> that disagrees with the time_t part of what clock_gettime
> (CLOCK_REALTIME) returns? Any such disagreement would cause
> application bugs that could well be unlikely and hard to track down;
> also, if there is disagreement, replacing calls to 'time' with calls
> to clock_gettime might not be advisable even aside from performance
> issues.

Maybe accuracy is the wrong word.  But time can definitely return the
value of a variable that is incremented periodically from the timer
interrupt.  That's not possible for gettimeofday or clock_gettime with
CLOCK_REALTIME (from a quality-of-implementation perspective).

Thanks,
Florian

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

* Re: [PATCH v2 05/10] Use clock_gettime to implement time.
  2019-08-28 20:21       ` Florian Weimer
@ 2019-08-28 21:12         ` Paul Eggert
  2019-08-28 21:39           ` Florian Weimer
  0 siblings, 1 reply; 44+ messages in thread
From: Paul Eggert @ 2019-08-28 21:12 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Zack Weinberg, libc-alpha, Joseph Myers, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Adhemerval Zanella, Samuel Thibault

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

Florian Weimer wrote:
> time can definitely return the
> value of a variable that is incremented periodically from the timer
> interrupt.

Is that variable the one that CLOCK_REALTIME_COARSE uses? If so, and if we're 
going to replace calls to 'time' with calls to 'clock_realtime', we can do 
either of the following:

* Use CLOCK_REALTIME_COARSE. This takes less CPU time and its behavior better 
matches what the current glibc does.

* Use CLOCK_REALTIME. This will lessen bugs due to naive code (quite possibly 
some code within glibc!) which assumes that 'time (0)' and clock_gettime 
(CLOCK_REALTIME, ...)' use the same clock.

It sounds you're leaning towards (1) and I'm inclined to agree. However, 
shouldn't the manual say that 'time' does not necessarily agree with 
CLOCK_REALTIME? The current behavior is a trap for the unwary.


To illustrate the problems with naive code, see the attached program. On my 
Fedora 30 x86-64 desktop, './a.out' outputs this:

clock_gettime (CLOCK_REALTIME, ...) yielded a seconds count of 1567026298;
then time (0) yielded a seconds count of 1567026297, which was 1 s earlier.
Time warp!

In contrast, './a.out 1' (which uses CLOCK_REALTIME_COARSE) finds no 
discrepancies in 2**32 attempts.

[-- Attachment #2: time.c --]
[-- Type: text/x-csrc, Size: 710 bytes --]

#include <time.h>
#include <stdio.h>

int
main (int argc, char **argv)
{
  int clock = argc == 1 ? CLOCK_REALTIME : CLOCK_REALTIME_COARSE;
  for (unsigned int i = 1; i; i++)
    {
      struct timespec ts;
      if (clock_gettime (clock, &ts))
	{
	  perror ("clock_gettime");
	  return 1;
	}
      time_t x = time (0);
      if (x < ts.tv_sec)
	{
	  printf ("clock_gettime (%s, ...)"
		  " yielded a seconds count of %ld;\n"
		  "then time (0) yielded a seconds count of %ld,"
		  " which was %ld s earlier.\n"
		  "Time warp!\n",
		  (clock == CLOCK_REALTIME
		   ? "CLOCK_REALTIME"
		   : "CLOCK_REALTIME_COARSE"),
		  (long) ts.tv_sec, (long) x, (long) (ts.tv_sec - x));
	  return 1;
	}
    }
  return 0;
}

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

* Re: [PATCH v2 05/10] Use clock_gettime to implement time.
  2019-08-28 21:12         ` Paul Eggert
@ 2019-08-28 21:39           ` Florian Weimer
  2019-08-29 17:49             ` Zack Weinberg
  0 siblings, 1 reply; 44+ messages in thread
From: Florian Weimer @ 2019-08-28 21:39 UTC (permalink / raw)
  To: Paul Eggert
  Cc: Zack Weinberg, libc-alpha, Joseph Myers, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Adhemerval Zanella, Samuel Thibault

* Paul Eggert:

> Florian Weimer wrote:
>> time can definitely return the
>> value of a variable that is incremented periodically from the timer
>> interrupt.
>
> Is that variable the one that CLOCK_REALTIME_COARSE uses? If so, and
> if we're going to replace calls to 'time' with calls to
> 'clock_realtime', we can do either of the following:
>
> * Use CLOCK_REALTIME_COARSE. This takes less CPU time and its behavior
> better matches what the current glibc does.
>
> * Use CLOCK_REALTIME. This will lessen bugs due to naive code (quite
> possibly some code within glibc!) which assumes that 'time (0)' and
> clock_gettime (CLOCK_REALTIME, ...)' use the same clock.

I think we should keep using the time entry in the vDSO.  This
consolidation is just not possible to do for performance reasons.

> It sounds you're leaning towards (1) and I'm inclined to
> agree. However, shouldn't the manual say that 'time' does not
> necessarily agree with CLOCK_REALTIME? The current behavior is a trap
> for the unwary.

Yes, clarifying the manual would make sense.  I do not know where the
discrepancy comes from.  It could just be that CLOCK_REALTIME performs
rounding, while time performs truncation.

Thanks,
Florian

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

* Re: [PATCH v2 10/10] Revise the documentation of simple calendar time.
  2019-08-28 15:32 ` [PATCH v2 10/10] Revise the documentation of simple calendar time Zack Weinberg
@ 2019-08-29  1:09   ` Paul Eggert
  2019-08-29 17:41     ` Zack Weinberg
  0 siblings, 1 reply; 44+ messages in thread
From: Paul Eggert @ 2019-08-29  1:09 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

Zack Weinberg wrote:

> +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)}}
> +and @code{gettimeofday} (see below).

As we've discussed recently (e.g., 
<https://sourceware.org/ml/libc-alpha/2019-08/msg00755.html>), the 'time' 
function does not necessarily use the same clock as clock_gettime 
(CLOCK_REALTIME). On GNU/Linux it appears to use the CLOCK_REALTIME_COARSE 
clock, though I doubt whether that's guaranteed everywhere. So I suggest 
changing that last sentence to:

This function uses a clock close to the clocks of @w{@samp{clock_gettime 
(CLOCK_REALTIME)}} and of @code{gettimeofday} (see below), but the three clocks 
are not necessarily in lock-step, and precise timestamp comparison is reliable 
only when timestamps come from the same clock.

> +@deftypevr Macro clockid_t CLOCK_REALTIME
> +@standards{POSIX.1, time.h}
> +System-wide clock measuring calendar time.  This clock reports the
> +same time as @code{time} (above) and @code{gettimeofday} (below) and
> +uses the POSIX epoch, 00:00:00 on January 1, 1970, Coordinated
> +Universal Time.

Similarly, change the last sentence to:

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).

> +@code{struct timeval}.  @code{gettimeofday} uses the same clock as
> +@code{time} and @w{@samp{clock_gettime (CLOCK_REALTIME)}}.

Similarly, change this sentence to:

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).

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

* Re: [PATCH v2 10/10] Revise the documentation of simple calendar time.
  2019-08-29  1:09   ` Paul Eggert
@ 2019-08-29 17:41     ` Zack Weinberg
  2019-08-30 19:17       ` Paul Eggert
  0 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-29 17:41 UTC (permalink / raw)
  To: Paul Eggert
  Cc: GNU C Library, Joseph Myers, Florian Weimer, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Adhemerval Zanella, Samuel Thibault

On Wed, Aug 28, 2019 at 9:09 PM Paul Eggert <eggert@cs.ucla.edu> wrote:
> Zack Weinberg wrote:
> > +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)}}
> > +and @code{gettimeofday} (see below).
>
> As we've discussed recently (e.g.,
> <https://sourceware.org/ml/libc-alpha/2019-08/msg00755.html>), the 'time'
> function does not necessarily use the same clock as clock_gettime
> (CLOCK_REALTIME).
...
> This function uses a clock close to the clocks of @w{@samp{clock_gettime
> (CLOCK_REALTIME)}} and of @code{gettimeofday} (see below), but the three clocks
> are not necessarily in lock-step, and precise timestamp comparison is reliable
> only when timestamps come from the same clock.

I think it's good to add a cautionary note *like* this, but I'm
worried that your suggested text might confuse readers into thinking
that these clocks might use different epochs or could be set
independently.  I'll think about how to put it better.

zw

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

* Re: [PATCH v2 05/10] Use clock_gettime to implement time.
  2019-08-28 21:39           ` Florian Weimer
@ 2019-08-29 17:49             ` Zack Weinberg
  2019-09-02 13:32               ` Florian Weimer
  0 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-08-29 17:49 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Paul Eggert, GNU C Library, Joseph Myers, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Adhemerval Zanella, Samuel Thibault

On Wed, Aug 28, 2019 at 5:39 PM Florian Weimer <fweimer@redhat.com> wrote:
> I think we should keep using the time entry in the vDSO.  This
> consolidation is just not possible to do for performance reasons.

To be crystal clear about where I'm coming from, I think this
consolidation is *necessary* to clear the way for the y2038 patches.
And I was under the impression that the kernel people wanted to
withdraw support for the time and gettimeofday entry points (at least
for new architectures going forward).

So I'm only looking for ways to mitigate the performance impact at
this point.  Before I back off on "henceforth we only call the
kernel's clock_gettime" I would need to hear *both* a really
compelling argument for why we need to keep calling the time or
gettimeofday entry points -- a few ns more expense on a call that only
reports the time to the nearest second isn't going to cut it -- *and*
an explanation of why it won't interfere with the y2038 work and/or
why we won't have to stop using them in the future anyway.

zw

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

* Re: [PATCH v2 01/10] Change most internal uses of __gettimeofday to __clock_gettime.
  2019-08-28 15:32 ` [PATCH v2 01/10] Change most internal uses of __gettimeofday to __clock_gettime Zack Weinberg
@ 2019-08-29 20:30   ` Adhemerval Zanella
  2019-08-29 20:42     ` Samuel Thibault
  0 siblings, 1 reply; 44+ messages in thread
From: Adhemerval Zanella @ 2019-08-29 20:30 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Samuel Thibault



On 28/08/2019 12:32, Zack Weinberg wrote:
> 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.

I think memusage.h is candidate for some cleanup, it basically replicate the
same interface hp-timing.h provides while I think GET_SP could just use
__builtin_frame_address (0) instead (and remove all the required arch-specific
implementations).

> 
> 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.
> 
> 	* inet/deadline.c (__deadline_current_time)
> 	* login/logout.c (logout)
> 	* login/logwtmp.c (logwtmp)
> 	* nis/nis_call.c (__nisfind_server)
> 	* nptl/pthread_join_common.c (timedwait_tid)
> 	* nptl/pthread_mutex_timedlock.c (__pthread_mutex_clocklock_common)
> 	* nscd/nscd_helper.c (wait_on_socket, open_socket)
> 	* resolv/gai_misc.c (handle_requests)
> 	* resolv/gai_suspend.c (gai_suspend)
> 	* resolv/res_send.c (evNowTime)
> 	* sunrpc/auth_des.c (authdes_marshal, authdes_destroy)
> 	* sunrpc/auth_unix.c (authunix_create, authunix_refresh)
> 	* sunrpc/create_xid.c (_create_xid)
> 	* sunrpc/svcauth_des.c (_svcauth_des)
> 	* sysdeps/generic/memusage.h (GETTIME)
> 	* sysdeps/mach/nanosleep.c (__libc_nanosleep)
> 	* sysdeps/posix/tempname.c (RANDOM_BITS)
> 	* sysdeps/pthread/aio_misc.c (handle_fildes_io)
> 	* sysdeps/pthread/aio_suspend.c (aio_suspend):
> 	Use __clock_gettime (CLOCK_REALTIME) instead of __gettimeofday.
> 	Assume __clock_gettime (CLOCK_REALTIME) cannot fail.
> 	Include time.h if necessary.
> 
> 	* sysdeps/posix/timespec_get.c (timespec_get):
> 	Assume __clock_gettime (CLOCK_REALTIME) cannot fail.
> 
> 	* sysdeps/mach/hurd/getitimer.c (__getitimer)
> 	* sysdeps/mach/hurd/setitimer.c (setitimer_locked)
> 	* sysdeps/mach/hurd/times.c (__times):
> 	Use __host_get_time instead of __gettimeofday.
> 	Include mach.h if necessary.
> 	Assume __host_get_time (__mach_host_self ()) cannot fail.
> 
> 	* sysdeps/mach/usleep.c (usleep): Remove unnecessary calls to
> 	__gettimeofday.
> 
> 	* support/support_test_main.c (print_timestamp): Take a struct
> 	timespec argument, not a struct timeval.
> 	(signal_handler): Update to match.
> 	Use clock_gettime (CLOCK_REALTIME) instead of gettimeofday.
> 	Assume clock_gettime (CLOCK_REALTIME) cannot fail.
> 
> 	* sysdeps/generic/memusage.h (GETTIME): Correct typo causing
> 	the seconds field of each timestamp to be ignored.
> 
> 	* sysdeps/unix/make-syscall.sh: Change an example in a comment
> 	from referring to gettimeofday, to referring to sigaction.

Looks ok with some adjustments below.

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  |  6 +++---
>  sysdeps/mach/hurd/setitimer.c  |  8 ++------
>  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, 127 insertions(+), 137 deletions(-)
> 
> diff --git a/inet/deadline.c b/inet/deadline.c
> index ab275c266d..082e279bce 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;
>  }

Ok.

> diff --git a/login/logout.c b/login/logout.c
> index 5015c1af0b..f1313ded77 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)

Ok.

> diff --git a/login/logwtmp.c b/login/logwtmp.c
> index 50d14976c7..ec41375383 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);
>  }

Ok.

> diff --git a/nis/nis_call.c b/nis/nis_call.c
> index a48ecc39a8..db81fa3568 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,

Ok.

> diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c
> index 5224ee2110..f1b14266de 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;

Ok.

> diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
> index 52c258e33d..2b194e5bee 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);

This seems to be using space instead of tabs.

>  
>  		    /* 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;

Ok.

> diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
> index 733c2a60cd..a6568d07c8 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)
>  	{

Ok.

> @@ -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));
>  	}
>      }
>  

Ok.

> @@ -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;

ok.

> diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c
> index 69d7086ae6..5d1e310147 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;

Ok.

> diff --git a/resolv/gai_suspend.c b/resolv/gai_suspend.c
> index eee3bcebe9..8f81e5a3dd 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)
>  	    {

Ok.

> diff --git a/resolv/res_send.c b/resolv/res_send.c
> index ed27f3abf8..2b971cf5d2 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);
>  }
>  
>  

Ok.

> diff --git a/sunrpc/auth_des.c b/sunrpc/auth_des.c
> index 5b6f985bc2..9079b30397 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;

Ok.

> @@ -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 myusec;


s/long/long int/ due code convention.

>  
>    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;
>  }

Ok.

> 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;

Ok.

> @@ -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);

Ok.

> diff --git a/sunrpc/create_xid.c b/sunrpc/create_xid.c
> index a44187f07c..8d1e722dad 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;
>      }

Ok.

> 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))
>        {

Ok.

> diff --git a/support/support_test_main.c b/support/support_test_main.c
> index 7e7b9edbb0..d8397a840c 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.  */

Ok.

> @@ -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);

Ok.

> diff --git a/sysdeps/generic/memusage.h b/sysdeps/generic/memusage.h
> index 480bdf79ee..c29feb8edd 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
>  

Although not incorrect, I think we can just use clock_gettime here and avoid
libmemusage.so to use GLIBC_PRIVATE symbols.


> diff --git a/sysdeps/mach/hurd/getitimer.c b/sysdeps/mach/hurd/getitimer.c
> index 69a0751ead..5af723f62a 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,7 @@ __getitimer (enum __itimer_which which, struct itimerval *value)
>      }
>  
>    /* Get the time now.  */
> -  if (__gettimeofday (&elapsed, NULL) < 0)
> -    return -1;
> +  __host_get_time (__mach_host_self (), (time_value_t *) &elapsed);
>  
>    /* Extract the current timer setting; and the time it was set, so we can
>       calculate the time elapsed so far.  */

This is not strickly conformant (casting struct with different types). I would
recommend do do this instead:

  {
     time_value_t tv;
     __host_get_time (__mach_host_self (), &tv);
     elapsed.tv_sec = tv.seconds;
     elapsed.tv_usec = tv.microseconds;
  }

> diff --git a/sysdeps/mach/hurd/setitimer.c b/sysdeps/mach/hurd/setitimer.c
> index 61e37c5f5d..b82582a60f 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.  */
> @@ -239,12 +240,7 @@ 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;
> -	}
> +      __host_get_time (__mach_host_self (), (time_value_t *) &now);
>        elapsed = now;
>        subtract_timeval (&elapsed, &_hurd_itimer_started);
>        remaining = _hurd_itimerval.it_value;

Ditto.

> diff --git a/sysdeps/mach/hurd/times.c b/sysdeps/mach/hurd/times.c
> index 7758311d83..0f48c784a9 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)

Looks ok.

> diff --git a/sysdeps/mach/nanosleep.c b/sysdeps/mach/nanosleep.c
> index b4790aaf31..f9b821a6e2 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)
> +

Not a fan to replicate a funcitonality that we already in libsupport,
but I think we might cleanup this up later.

>  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);

Indentation seems off here.

> +	  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 5d4bd205e1..8428ace6ef 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;
>  }

Not sure why hurd is calling get __gettimeofday here...

> diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
> index 310df3c4ca..c3956498ce 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
>  

Ok.

> diff --git a/sysdeps/posix/timespec_get.c b/sysdeps/posix/timespec_get.c
> index 98d3136287..781a624c7d 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;
>  }

Ok.

> diff --git a/sysdeps/pthread/aio_misc.c b/sysdeps/pthread/aio_misc.c
> index 0180ddb3c3..49ab08de3a 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);

Indentation seems off here.

>  	  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;

Ok.

> diff --git a/sysdeps/pthread/aio_suspend.c b/sysdeps/pthread/aio_suspend.c
> index 06bd914672..fdd4087abb 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)
>  	    {

Ok.

> diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh
> index 6a5c10d54e..2b8c9ea49c 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)
> 

Not sure if this is really required, afaik gettimeofday won't be deprecated anytime
soon.

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

* Re: [PATCH v2 01/10] Change most internal uses of __gettimeofday to __clock_gettime.
  2019-08-29 20:30   ` Adhemerval Zanella
@ 2019-08-29 20:42     ` Samuel Thibault
  0 siblings, 0 replies; 44+ messages in thread
From: Samuel Thibault @ 2019-08-29 20:42 UTC (permalink / raw)
  To: Adhemerval Zanella
  Cc: Zack Weinberg, libc-alpha, Joseph Myers, Florian Weimer,
	Lukasz Majewski, Alistair Francis, Stepan Golosunov,
	Arnd Bergmann

Adhemerval Zanella, le jeu. 29 août 2019 17:30:26 -0300, a ecrit:
> >  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;
> >  }
> 
> Not sure why hurd is calling get __gettimeofday here...

I guess it's a debugging leftover.

Samuel

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

* Re: [PATCH v2 02/10] Finish move of clock_* functions to libc.
  2019-08-28 15:32 ` [PATCH v2 02/10] Finish move of clock_* functions to libc Zack Weinberg
@ 2019-08-30 17:40   ` Adhemerval Zanella
  2019-09-03  7:29   ` Florian Weimer
  1 sibling, 0 replies; 44+ messages in thread
From: Adhemerval Zanella @ 2019-08-30 17:40 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Samuel Thibault



On 28/08/2019 12:32, Zack Weinberg wrote:
> In glibc 2.17, the functions clock_getcpuclockid, clock_getres,
> clock_gettime, clock_nanosleep, and clock_settime were moved from
> librt.so to libc.so, leaving compatibility stubs behind.  Now that the
> dynamic linker no longer insists on finding versioned symbols in the
> same library that originally defined them, we do not need the stubs
> anymore, and this means we don't need GLIBC_PRIVATE __-prefix aliases
> for most of the functions anymore either.  (clock_gettime still needs
> one.)  For ports added before 2.17, libc.so needs to provide two
> symbol versions for each, the default at GLIBC_2.17 plus a compat
> version matching what librt had.
> 
> While I'm at it, move the clock_*.c files and their tests from rt/ to
> time/.
> 
> 	* rt/clock_getcpuclockid.c: Move to time/clock_getcpuclockid.c.
> 	* rt/clock_getres.c: Move to time/clock_getres.c.
> 	* rt/clock_gettime.c: Move to time/clock_gettime.c.
> 	* rt/clock_nanosleep.c: Move to time/clock_nanosleep.c.
> 	* rt/clock_settime.c: Move to time/clock_settime.c.
> 	* rt/tst-clock.c: Move to time/tst-clock.c.
> 	* rt/tst-clock2.c: Move to time/tst-clock2.c.
> 	* rt/tst-clock_nanosleep.c: Move to time/tst-clock_nanosleep.c.
> 	* rt/tst-cpuclock1.c: Move to time/tst-cpuclock1.c.
> 	* rt/clock-compat.c: Delete file.
> 
> 	* time/clock_getcpuclockid.c
> 	* time/clock_getres.c
> 	* time/clock_gettime.c
> 	* time/clock_nanosleep.c
> 	* time/clock_settime.c
> 	* sysdeps/posix/clock_getres.c
> 	* sysdeps/unix/clock_gettime.c
> 	* sysdeps/unix/clock_nanosleep.c
> 	* sysdeps/unix/clock_settime.c
> 	* sysdeps/unix/sysv/linux/clock_getcpuclockid.c
> 	* sysdeps/unix/sysv/linux/clock_getres.c
> 	* sysdeps/unix/sysv/linux/clock_gettime.c
> 	* sysdeps/unix/sysv/linux/clock_nanosleep.c
> 	* sysdeps/unix/sysv/linux/clock_settime.c: Define the function
> 	defined by this file with default symbol version GLIBC_2_17,
> 	and optionally a compatibility alias at symbol version GLIBC_2_2.
> 	* include/time.h: Remove internal prototypes for clock_getres,
> 	clock_nanosleep, and clock_getcpuclockid.
> 
> 	* sysdeps/unix/sysv/linux/clock_gettime.c: Prune includes.
> 	Remove unused function realtime_gettime.
> 
> 	* rt/Makefile (clock-routines, routines): Remove variable.
> 	(librt-routines): Remove clock-compat.
> 	(tests): Remove tst-clock, tst-clock2, tst-clock_nanosleep,
> 	and tst-cpuclock1.
> 	* time/Makefile (routines): Add clock_getres, clock_gettime,
> 	clock_settime, clock_getcpuclockid, and clock_nanosleep.
> 	(tests): Add tst-clock, tst-clock2, tst-clock_nanosleep,
> 	and tst-cpuclock1.
> 
> 	* rt/Versions (libc): Remove entire stanza.
> 	(librt GLIBC_2.2): Remove all clock_* functions.
> 	* time/Versions (libc GLIBC_2.2, libc GLIBC_2.17):
> 	Add clock_getres, clock_gettime, clock_settime,
> 	clock_getcpuclockid, and clock_nanosleep.
> 	(libc GLIBC_PRIVATE): Add __clock_gettime.
> 
> 	* sysdeps/mach/hurd/i386/librt.abilist
> 	* sysdeps/unix/sysv/linux/alpha/librt.abilist
> 	* sysdeps/unix/sysv/linux/arm/librt.abilist
> 	* sysdeps/unix/sysv/linux/hppa/librt.abilist
> 	* sysdeps/unix/sysv/linux/i386/librt.abilist
> 	* sysdeps/unix/sysv/linux/ia64/librt.abilist
> 	* sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist
> 	* sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist
> 	* sysdeps/unix/sysv/linux/microblaze/librt.abilist
> 	* sysdeps/unix/sysv/linux/mips/mips32/librt.abilist
> 	* sysdeps/unix/sysv/linux/mips/mips64/librt.abilist
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/librt.abilist
> 	* sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist
> 	* sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist
> 	* sysdeps/unix/sysv/linux/sh/librt.abilist
> 	* sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist
> 	* sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist
> 	* sysdeps/unix/sysv/linux/x86_64/64/librt.abilist
> 	* sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist:
> 	Remove entries for clock_getres, clock_gettime, clock_settime,
> 	clock_getcpuclockid, and clock_nanosleep.
> 
> 	* sysdeps/mach/hurd/i386/libc.abilist
> 	* sysdeps/unix/sysv/linux/alpha/libc.abilist
> 	* sysdeps/unix/sysv/linux/arm/libc.abilist
> 	* sysdeps/unix/sysv/linux/hppa/libc.abilist
> 	* sysdeps/unix/sysv/linux/i386/libc.abilist
> 	* sysdeps/unix/sysv/linux/ia64/libc.abilist
> 	* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> 	* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> 	* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> 	* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> 	* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> 	* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> 	* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> 	* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> 	* sysdeps/unix/sysv/linux/sh/libc.abilist
> 	* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> 	* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> 	* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> 	* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist:
> 	Add another set of entries for clock_getres, clock_gettime,
> 	clock_settime, clock_getcpuclockid, and clock_nanosleep at
> 	whatever version GLIBC_2.2 maps to.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>


> ---
>  include/time.h                                |  4 +-
>  rt/Makefile                                   | 15 ++---
>  rt/Versions                                   | 16 -----
>  rt/clock-compat.c                             | 63 -------------------
>  sysdeps/mach/hurd/i386/libc.abilist           |  5 ++
>  sysdeps/mach/hurd/i386/librt.abilist          |  5 --
>  sysdeps/posix/clock_getres.c                  | 11 +++-
>  sysdeps/unix/clock_gettime.c                  | 26 +++-----
>  sysdeps/unix/clock_nanosleep.c                | 10 ++-
>  sysdeps/unix/clock_settime.c                  | 13 +++-
>  sysdeps/unix/sysv/linux/alpha/libc.abilist    |  5 ++
>  sysdeps/unix/sysv/linux/alpha/librt.abilist   |  5 --
>  sysdeps/unix/sysv/linux/arm/libc.abilist      |  5 ++
>  sysdeps/unix/sysv/linux/arm/librt.abilist     |  5 --
>  sysdeps/unix/sysv/linux/clock_getcpuclockid.c | 10 ++-
>  sysdeps/unix/sysv/linux/clock_getres.c        | 11 +++-
>  sysdeps/unix/sysv/linux/clock_gettime.c       | 11 +++-
>  sysdeps/unix/sysv/linux/clock_nanosleep.c     | 10 ++-
>  sysdeps/unix/sysv/linux/clock_settime.c       | 11 +++-
>  sysdeps/unix/sysv/linux/hppa/libc.abilist     |  5 ++
>  sysdeps/unix/sysv/linux/hppa/librt.abilist    |  5 --
>  sysdeps/unix/sysv/linux/i386/libc.abilist     |  5 ++
>  sysdeps/unix/sysv/linux/i386/librt.abilist    |  5 --
>  sysdeps/unix/sysv/linux/ia64/libc.abilist     |  5 ++
>  sysdeps/unix/sysv/linux/ia64/librt.abilist    |  5 --
>  .../sysv/linux/m68k/coldfire/libc.abilist     |  5 ++
>  .../sysv/linux/m68k/coldfire/librt.abilist    |  5 --
>  .../unix/sysv/linux/m68k/m680x0/libc.abilist  |  5 ++
>  .../unix/sysv/linux/m68k/m680x0/librt.abilist |  5 --
>  .../unix/sysv/linux/microblaze/librt.abilist  |  5 --
>  .../sysv/linux/mips/mips32/fpu/libc.abilist   |  5 ++
>  .../unix/sysv/linux/mips/mips32/librt.abilist |  5 --
>  .../sysv/linux/mips/mips32/nofpu/libc.abilist |  5 ++
>  .../unix/sysv/linux/mips/mips64/librt.abilist |  5 --
>  .../sysv/linux/mips/mips64/n32/libc.abilist   |  5 ++
>  .../sysv/linux/mips/mips64/n64/libc.abilist   |  5 ++
>  .../linux/powerpc/powerpc32/fpu/libc.abilist  |  5 ++
>  .../linux/powerpc/powerpc32/librt.abilist     |  5 --
>  .../powerpc/powerpc32/nofpu/libc.abilist      |  5 ++
>  .../linux/powerpc/powerpc64/be/libc.abilist   |  5 ++
>  .../linux/powerpc/powerpc64/be/librt.abilist  |  5 --
>  .../unix/sysv/linux/s390/s390-32/libc.abilist |  5 ++
>  .../sysv/linux/s390/s390-32/librt.abilist     |  5 --
>  .../unix/sysv/linux/s390/s390-64/libc.abilist |  5 ++
>  .../sysv/linux/s390/s390-64/librt.abilist     |  5 --
>  sysdeps/unix/sysv/linux/sh/libc.abilist       |  5 ++
>  sysdeps/unix/sysv/linux/sh/librt.abilist      |  5 --
>  .../sysv/linux/sparc/sparc32/libc.abilist     |  5 ++
>  .../sysv/linux/sparc/sparc32/librt.abilist    |  5 --
>  .../sysv/linux/sparc/sparc64/libc.abilist     |  5 ++
>  .../sysv/linux/sparc/sparc64/librt.abilist    |  5 --
>  .../unix/sysv/linux/x86_64/64/libc.abilist    |  5 ++
>  .../unix/sysv/linux/x86_64/64/librt.abilist   |  5 --
>  .../unix/sysv/linux/x86_64/x32/libc.abilist   |  5 ++
>  .../unix/sysv/linux/x86_64/x32/librt.abilist  |  5 --
>  time/Makefile                                 |  8 ++-
>  time/Versions                                 | 13 ++++
>  {rt => time}/clock_getcpuclockid.c            |  9 ++-
>  {rt => time}/clock_getres.c                   | 11 +++-
>  {rt => time}/clock_gettime.c                  | 11 +++-
>  {rt => time}/clock_nanosleep.c                | 11 +++-
>  {rt => time}/clock_settime.c                  | 12 +++-
>  {rt => time}/tst-clock.c                      |  0
>  {rt => time}/tst-clock2.c                     |  0
>  {rt => time}/tst-clock_nanosleep.c            |  0
>  {rt => time}/tst-cpuclock1.c                  |  0
>  66 files changed, 268 insertions(+), 228 deletions(-)
>  delete mode 100644 rt/clock-compat.c
>  rename {rt => time}/clock_getcpuclockid.c (75%)
>  rename {rt => time}/clock_getres.c (73%)
>  rename {rt => time}/clock_gettime.c (74%)
>  rename {rt => time}/clock_nanosleep.c (76%)
>  rename {rt => time}/clock_settime.c (71%)
>  rename {rt => time}/tst-clock.c (100%)
>  rename {rt => time}/tst-clock2.c (100%)
>  rename {rt => time}/tst-clock_nanosleep.c (100%)
>  rename {rt => time}/tst-cpuclock1.c (100%)
> 
> diff --git a/include/time.h b/include/time.h
> index ac3163c2a5..dcf91855ad 100644
> --- a/include/time.h
> +++ b/include/time.h
> @@ -18,12 +18,10 @@ libc_hidden_proto (localtime)
>  libc_hidden_proto (strftime)
>  libc_hidden_proto (strptime)
>  
> -extern __typeof (clock_getres) __clock_getres;
>  extern __typeof (clock_gettime) __clock_gettime;
>  libc_hidden_proto (__clock_gettime)
>  extern __typeof (clock_settime) __clock_settime;
> -extern __typeof (clock_nanosleep) __clock_nanosleep;
> -extern __typeof (clock_getcpuclockid) __clock_getcpuclockid;
> +libc_hidden_proto (__clock_settime)
>  
>  /* Now define the internal interfaces.  */
>  struct tm;

Ok.

> diff --git a/rt/Makefile b/rt/Makefile
> index 9ea8394565..e6fbc32438 100644
> --- a/rt/Makefile
> +++ b/rt/Makefile
> @@ -28,9 +28,6 @@ aio-routines   := aio_cancel aio_error aio_fsync aio_misc aio_read	\
>  		  aio_read64 aio_return aio_suspend aio_write		\
>  		  aio_write64 lio_listio lio_listio64 aio_sigqueue	\
>  		  aio_notify
> -clock-routines := clock_getcpuclockid					\
> -		  clock_getres clock_gettime clock_settime		\
> -		  clock_nanosleep
>  timer-routines := timer_create timer_delete timer_getoverr		\
>  		  timer_gettime timer_settime
>  shm-routines   := shm_open shm_unlink

Ok.

> @@ -38,22 +35,18 @@ mq-routines    := mq_open mq_close mq_unlink mq_getattr mq_setattr	\
>  		  mq_notify mq_send mq_receive mq_timedsend		\
>  		  mq_timedreceive
>  
> -routines = $(clock-routines)
> -
>  librt-routines = $(aio-routines) \
>  		 $(timer-routines) \
> -		 $(shm-routines) $(mq-routines) \
> -		 clock-compat
> +		 $(shm-routines) $(mq-routines)
>  
> -tests := tst-shm tst-clock tst-clock_nanosleep tst-timer tst-timer2 \
> +tests := tst-shm tst-timer tst-timer2 \
>  	 tst-aio tst-aio64 tst-aio2 tst-aio3 tst-aio4 tst-aio5 tst-aio6 \
>  	 tst-aio7 tst-aio8 tst-aio9 tst-aio10 \
>  	 tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \
>  	 tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \
>  	 tst-timer3 tst-timer4 tst-timer5 \
> -	 tst-cpuclock1 tst-cpuclock2 \
> -	 tst-cputimer1 tst-cputimer2 tst-cputimer3 \
> -	 tst-clock2 tst-shm-cancel
> +	 tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \
> +	 tst-shm-cancel
>  
>  extra-libs := librt
>  extra-libs-others := $(extra-libs)

Ok.

> diff --git a/rt/Versions b/rt/Versions
> index 91e3fd2a20..84d1345420 100644
> --- a/rt/Versions
> +++ b/rt/Versions
> @@ -1,15 +1,3 @@
> -libc {
> -  GLIBC_2.17 {
> -    # c*
> -    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
> -    clock_nanosleep;
> -  }
> -  GLIBC_PRIVATE {
> -    __clock_getres; __clock_gettime; __clock_settime; __clock_getcpuclockid;
> -    __clock_nanosleep;
> -  }
> -}
> -
>  librt {
>    GLIBC_2.1 {
>      # AIO functions.
> @@ -18,10 +6,6 @@ librt {
>      aio_suspend64; aio_write; aio_write64; lio_listio; lio_listio64;
>    }
>    GLIBC_2.2 {
> -    # These have moved to libc and are still here only for compatibility.
> -    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
> -    clock_nanosleep;
> -
>      # s*
>      shm_open; shm_unlink;
>  

Ok.

> diff --git a/rt/clock-compat.c b/rt/clock-compat.c
> deleted file mode 100644
> index d8ced3cdc1..0000000000
> --- a/rt/clock-compat.c
> +++ /dev/null
> @@ -1,63 +0,0 @@
> -/* ABI compatibility redirects for clock_* symbols in librt.
> -   Copyright (C) 2012-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>
> -
> -/* The clock_* symbols were originally defined in librt and so
> -   are part of its ABI.  As of 2.17, they have moved to libc.
> -   So we supply definitions for librt that just redirect to
> -   their libc counterparts.  */
> -
> -#if SHLIB_COMPAT (librt, GLIBC_2_2, GLIBC_2_17)
> -
> -#include <time.h>
> -
> -#if HAVE_IFUNC
> -# undef INIT_ARCH
> -# define INIT_ARCH()
> -# define COMPAT_REDIRECT(name, proto, arglist) libc_ifunc (name, &__##name) \
> -    compat_symbol (librt, name, name, GLIBC_2_2);
> -#else
> -# define COMPAT_REDIRECT(name, proto, arglist)				      \
> -  int									      \
> -  name proto								      \
> -  {									      \
> -    return __##name arglist;						      \
> -  }									      \
> -  compat_symbol (librt, name, name, GLIBC_2_2);
> -#endif
> -
> -COMPAT_REDIRECT (clock_getres,
> -		 (clockid_t clock_id, struct timespec *res),
> -		 (clock_id, res))
> -COMPAT_REDIRECT (clock_gettime,
> -		 (clockid_t clock_id, struct timespec *tp),
> -		 (clock_id, tp))
> -COMPAT_REDIRECT (clock_settime,
> -		 (clockid_t clock_id, const struct timespec *tp),
> -		 (clock_id, tp))
> -COMPAT_REDIRECT (clock_getcpuclockid,
> -		 (pid_t pid, clockid_t *clock_id),
> -		 (pid, clock_id))
> -COMPAT_REDIRECT (clock_nanosleep,
> -		 (clockid_t clock_id, int flags,
> -		  const struct timespec *req,
> -		  struct timespec *rem),
> -		 (clock_id, flags, req, rem))
> -
> -#endif

Ok.

> diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
> index 1fc7ab2433..7c2cb2b05a 100644
> --- a/sysdeps/mach/hurd/i386/libc.abilist
> +++ b/sysdeps/mach/hurd/i386/libc.abilist
> @@ -711,6 +711,11 @@ GLIBC_2.2.6 clntudp_bufcreate F
>  GLIBC_2.2.6 clntudp_create F
>  GLIBC_2.2.6 clntunix_create F
>  GLIBC_2.2.6 clock F
> +GLIBC_2.2.6 clock_getcpuclockid F
> +GLIBC_2.2.6 clock_getres F
> +GLIBC_2.2.6 clock_gettime F
> +GLIBC_2.2.6 clock_nanosleep F
> +GLIBC_2.2.6 clock_settime F
>  GLIBC_2.2.6 close F
>  GLIBC_2.2.6 closedir F
>  GLIBC_2.2.6 closelog F

Ok.

> diff --git a/sysdeps/mach/hurd/i386/librt.abilist b/sysdeps/mach/hurd/i386/librt.abilist
> index d5fe32b3a9..3726e41f06 100644
> --- a/sysdeps/mach/hurd/i386/librt.abilist
> +++ b/sysdeps/mach/hurd/i386/librt.abilist
> @@ -13,11 +13,6 @@ GLIBC_2.2.6 aio_suspend F
>  GLIBC_2.2.6 aio_suspend64 F
>  GLIBC_2.2.6 aio_write F
>  GLIBC_2.2.6 aio_write64 F
> -GLIBC_2.2.6 clock_getcpuclockid F
> -GLIBC_2.2.6 clock_getres F
> -GLIBC_2.2.6 clock_gettime F
> -GLIBC_2.2.6 clock_nanosleep F
> -GLIBC_2.2.6 clock_settime F
>  GLIBC_2.2.6 lio_listio F
>  GLIBC_2.2.6 lio_listio64 F
>  GLIBC_2.2.6 shm_open F

Ok.

> diff --git a/sysdeps/posix/clock_getres.c b/sysdeps/posix/clock_getres.c
> index 01024a3f55..e529cadb1f 100644
> --- a/sysdeps/posix/clock_getres.c
> +++ b/sysdeps/posix/clock_getres.c
> @@ -22,7 +22,7 @@
>  #include <unistd.h>
>  #include <sys/param.h>
>  #include <libc-internal.h>
> -
> +#include <shlib-compat.h>
>  
>  static inline int
>  realtime_getres (struct timespec *res)
> @@ -62,4 +62,11 @@ __clock_getres (clockid_t clock_id, struct timespec *res)
>  
>    return retval;
>  }
> -weak_alias (__clock_getres, clock_getres)
> +
> +versioned_symbol (libc, __clock_getres, clock_getres, GLIBC_2_17);
> +/* clock_getres moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_getres, __clock_getres_2);
> +compat_symbol (libc, __clock_getres_2, clock_getres, GLIBC_2_2);
> +#endif

Ok.

> diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/unix/clock_gettime.c
> index 10a6c96d9d..2a82fc1066 100644
> --- a/sysdeps/unix/clock_gettime.c
> +++ b/sysdeps/unix/clock_gettime.c
> @@ -17,24 +17,9 @@
>     <http://www.gnu.org/licenses/>.  */
>  
>  #include <errno.h>
> -#include <stdint.h>
>  #include <time.h>
>  #include <sys/time.h>
> -#include <libc-internal.h>
> -#include <ldsodefs.h>
> -
> -
> -static inline int
> -realtime_gettime (struct timespec *tp)
> -{
> -  struct timeval tv;
> -  int retval = __gettimeofday (&tv, NULL);
> -  if (retval == 0)
> -    /* Convert into `timespec'.  */
> -    TIMEVAL_TO_TIMESPEC (&tv, tp);
> -  return retval;
> -}
> -
> +#include <shlib-compat.h>
>  
>  /* Get current value of CLOCK and store it in TP.  */
>  int
> @@ -60,5 +45,12 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp)
>  
>    return retval;
>  }
> -weak_alias (__clock_gettime, clock_gettime)
>  libc_hidden_def (__clock_gettime)
> +
> +versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17);
> +/* clock_gettime moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_gettime, __clock_gettime_2);
> +compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2);
> +#endif

Ok.

> diff --git a/sysdeps/unix/clock_nanosleep.c b/sysdeps/unix/clock_nanosleep.c
> index b27608570c..6a477520d1 100644
> --- a/sysdeps/unix/clock_nanosleep.c
> +++ b/sysdeps/unix/clock_nanosleep.c
> @@ -20,6 +20,7 @@
>  #include <errno.h>
>  #include <time.h>
>  #include <sysdep-cancel.h>
> +#include <shlib-compat.h>
>  
>  /* This implementation assumes that these is only a `nanosleep' system
>     call.  So we have to remap all other activities.  */
> @@ -76,4 +77,11 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
>  
>    return __nanosleep (req, rem), 0 ? errno : 0;
>  }
> -weak_alias (__clock_nanosleep, clock_nanosleep)
> +
> +versioned_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_17);
> +/* clock_nanosleep moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_nanosleep, __clock_nanosleep_2);
> +compat_symbol (libc, __clock_nanosleep_2, clock_nanosleep, GLIBC_2_2);
> +#endif

Ok.

> diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/unix/clock_settime.c
> index 109a1ad872..5b398491ab 100644
> --- a/sysdeps/unix/clock_settime.c
> +++ b/sysdeps/unix/clock_settime.c
> @@ -18,8 +18,7 @@
>  #include <errno.h>
>  #include <time.h>
>  #include <sys/time.h>
> -#include <ldsodefs.h>
> -
> +#include <shlib-compat.h>
>  
>  /* Set CLOCK to value TP.  */
>  int
> @@ -51,4 +50,12 @@ __clock_settime (clockid_t clock_id, const struct timespec *tp)
>  
>    return retval;
>  }
> -weak_alias (__clock_settime, clock_settime)
> +libc_hidden_def (__clock_settime)
> +
> +versioned_symbol (libc, __clock_settime, clock_settime, GLIBC_2_17);
> +/* clock_settime moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_settime, __clock_settime_2);
> +compat_symbol (libc, __clock_settime_2, clock_settime, GLIBC_2_2);
> +#endif

Ok.

> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index fe85a35620..e7f2174ac2 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -1863,6 +1863,11 @@ GLIBC_2.2 __xpg_sigpause F
>  GLIBC_2.2 _flushlbf F
>  GLIBC_2.2 _res_hconf D 0x48
>  GLIBC_2.2 bind_textdomain_codeset F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 dcngettext F
>  GLIBC_2.2 dngettext F
>  GLIBC_2.2 fgetpos F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/alpha/librt.abilist b/sysdeps/unix/sysv/linux/alpha/librt.abilist
> index d7a049cf60..71f86e03ce 100644
> --- a/sysdeps/unix/sysv/linux/alpha/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/librt.abilist
> @@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
>  GLIBC_2.1 aio_write64 F
>  GLIBC_2.1 lio_listio F
>  GLIBC_2.1 lio_listio64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 shm_open F
>  GLIBC_2.2 shm_unlink F
>  GLIBC_2.2 timer_create F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
> index bc3df8dcea..9371927927 100644
> --- a/sysdeps/unix/sysv/linux/arm/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
> @@ -766,6 +766,11 @@ GLIBC_2.4 clntudp_bufcreate F
>  GLIBC_2.4 clntudp_create F
>  GLIBC_2.4 clntunix_create F
>  GLIBC_2.4 clock F
> +GLIBC_2.4 clock_getcpuclockid F
> +GLIBC_2.4 clock_getres F
> +GLIBC_2.4 clock_gettime F
> +GLIBC_2.4 clock_nanosleep F
> +GLIBC_2.4 clock_settime F
>  GLIBC_2.4 clone F
>  GLIBC_2.4 close F
>  GLIBC_2.4 closedir F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/arm/librt.abilist b/sysdeps/unix/sysv/linux/arm/librt.abilist
> index cfbbd27557..3c0647b251 100644
> --- a/sysdeps/unix/sysv/linux/arm/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/librt.abilist
> @@ -13,11 +13,6 @@ GLIBC_2.4 aio_suspend F
>  GLIBC_2.4 aio_suspend64 F
>  GLIBC_2.4 aio_write F
>  GLIBC_2.4 aio_write64 F
> -GLIBC_2.4 clock_getcpuclockid F
> -GLIBC_2.4 clock_getres F
> -GLIBC_2.4 clock_gettime F
> -GLIBC_2.4 clock_nanosleep F
> -GLIBC_2.4 clock_settime F
>  GLIBC_2.4 lio_listio F
>  GLIBC_2.4 lio_listio64 F
>  GLIBC_2.4 mq_close F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
> index f4a652966f..f2d8b916cb 100644
> --- a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
> +++ b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
> @@ -20,6 +20,7 @@
>  #include <time.h>
>  #include <unistd.h>
>  #include "kernel-posix-cpu-timers.h"
> +#include <shlib-compat.h>
>  
>  int
>  __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
> @@ -45,4 +46,11 @@ __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
>    else
>      return INTERNAL_SYSCALL_ERRNO (r, err);
>  }
> -weak_alias (__clock_getcpuclockid, clock_getcpuclockid)
> +
> +versioned_symbol (libc, __clock_getcpuclockid, clock_getcpuclockid, GLIBC_2_17);
> +/* clock_getcpuclockid moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_getcpuclockid, __clock_getcpuclockid_2);
> +compat_symbol (libc, __clock_getcpuclockid_2, clock_getcpuclockid, GLIBC_2_2);
> +#endif

Ok.

> diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
> index 24b2299938..18a7ce53c0 100644
> --- a/sysdeps/unix/sysv/linux/clock_getres.c
> +++ b/sysdeps/unix/sysv/linux/clock_getres.c
> @@ -26,10 +26,19 @@
>  #endif
>  #include <sysdep-vdso.h>
>  
> +#include <shlib-compat.h>
> +
>  /* Get resolution of clock.  */
>  int
>  __clock_getres (clockid_t clock_id, struct timespec *res)
>  {
>    return INLINE_VSYSCALL (clock_getres, 2, clock_id, res);
>  }
> -weak_alias (__clock_getres, clock_getres)
> +
> +versioned_symbol (libc, __clock_getres, clock_getres, GLIBC_2_17);
> +/* clock_getres moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_getres, __clock_getres_2);
> +compat_symbol (libc, __clock_getres_2, clock_getres, GLIBC_2_2);
> +#endif

Ok.

> diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
> index 5fc47fb7dc..7ad1c91be6 100644
> --- a/sysdeps/unix/sysv/linux/clock_gettime.c
> +++ b/sysdeps/unix/sysv/linux/clock_gettime.c
> @@ -26,11 +26,20 @@
>  #endif
>  #include <sysdep-vdso.h>
>  
> +#include <shlib-compat.h>
> +
>  /* Get current value of CLOCK and store it in TP.  */
>  int
>  __clock_gettime (clockid_t clock_id, struct timespec *tp)
>  {
>    return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp);
>  }
> -weak_alias (__clock_gettime, clock_gettime)
>  libc_hidden_def (__clock_gettime)
> +
> +versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17);
> +/* clock_gettime moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_gettime, __clock_gettime_2);
> +compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2);
> +#endif

Ok.

> diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c
> index 0cb6614dc9..e19e09d197 100644
> --- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
> +++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
> @@ -21,6 +21,7 @@
>  #include <sysdep-cancel.h>
>  #include "kernel-posix-cpu-timers.h"
>  
> +#include <shlib-compat.h>
>  
>  /* We can simply use the syscall.  The CPU clocks are not supported
>     with this function.  */
> @@ -41,4 +42,11 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
>    return (INTERNAL_SYSCALL_ERROR_P (r, err)
>  	  ? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
>  }
> -weak_alias (__clock_nanosleep, clock_nanosleep)
> +
> +versioned_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_17);
> +/* clock_nanosleep moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_nanosleep, __clock_nanosleep_2);
> +compat_symbol (libc, __clock_nanosleep_2, clock_nanosleep, GLIBC_2_2);
> +#endif
Ok.

> diff --git a/sysdeps/unix/sysv/linux/clock_settime.c b/sysdeps/unix/sysv/linux/clock_settime.c
> index d837e3019c..0586d15722 100644
> --- a/sysdeps/unix/sysv/linux/clock_settime.c
> +++ b/sysdeps/unix/sysv/linux/clock_settime.c
> @@ -18,6 +18,7 @@
>  #include <errno.h>
>  #include <sysdep.h>
>  #include <time.h>
> +#include <shlib-compat.h>
>  
>  #include "kernel-posix-cpu-timers.h"
>  
> @@ -34,4 +35,12 @@ __clock_settime (clockid_t clock_id, const struct timespec *tp)
>  
>    return INLINE_SYSCALL_CALL (clock_settime, clock_id, tp);
>  }
> -weak_alias (__clock_settime, clock_settime)
> +libc_hidden_def (__clock_settime)
> +
> +versioned_symbol (libc, __clock_settime, clock_settime, GLIBC_2_17);
> +/* clock_settime moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_settime, __clock_settime_2);
> +compat_symbol (libc, __clock_settime_2, clock_settime, GLIBC_2_2);
> +#endif

Ok.

> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index 75edece94a..df6d96fbae 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -615,6 +615,11 @@ GLIBC_2.2 clntudp_bufcreate F
>  GLIBC_2.2 clntudp_create F
>  GLIBC_2.2 clntunix_create F
>  GLIBC_2.2 clock F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 clone F
>  GLIBC_2.2 close F
>  GLIBC_2.2 closedir F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/hppa/librt.abilist b/sysdeps/unix/sysv/linux/hppa/librt.abilist
> index 595f1b712a..bb03781dcc 100644
> --- a/sysdeps/unix/sysv/linux/hppa/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/librt.abilist
> @@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
>  GLIBC_2.1 aio_write64 F
>  GLIBC_2.1 lio_listio F
>  GLIBC_2.1 lio_listio64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 shm_open F
>  GLIBC_2.2 shm_unlink F
>  GLIBC_2.2 timer_create F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index edeaf8e722..fcb625b6bf 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -1869,6 +1869,11 @@ GLIBC_2.2 _flushlbf F
>  GLIBC_2.2 _res_hconf D 0x30
>  GLIBC_2.2 alphasort64 F
>  GLIBC_2.2 bind_textdomain_codeset F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 dcngettext F
>  GLIBC_2.2 dngettext F
>  GLIBC_2.2 fgetpos F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/i386/librt.abilist b/sysdeps/unix/sysv/linux/i386/librt.abilist
> index 595f1b712a..bb03781dcc 100644
> --- a/sysdeps/unix/sysv/linux/i386/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/librt.abilist
> @@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
>  GLIBC_2.1 aio_write64 F
>  GLIBC_2.1 lio_listio F
>  GLIBC_2.1 lio_listio64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 shm_open F
>  GLIBC_2.2 shm_unlink F
>  GLIBC_2.2 timer_create F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> index b5d460eeb2..cb556c5998 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> @@ -627,6 +627,11 @@ GLIBC_2.2 clntudp_bufcreate F
>  GLIBC_2.2 clntudp_create F
>  GLIBC_2.2 clntunix_create F
>  GLIBC_2.2 clock F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 close F
>  GLIBC_2.2 closedir F
>  GLIBC_2.2 closelog F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/ia64/librt.abilist b/sysdeps/unix/sysv/linux/ia64/librt.abilist
> index 804622a14a..08384c9065 100644
> --- a/sysdeps/unix/sysv/linux/ia64/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/librt.abilist
> @@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
>  GLIBC_2.1 aio_write64 F
>  GLIBC_2.1 lio_listio F
>  GLIBC_2.1 lio_listio64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 shm_open F
>  GLIBC_2.2 shm_unlink F
>  GLIBC_2.2 timer_create F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index 05633b3cb8..f3aa47d090 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -755,6 +755,11 @@ GLIBC_2.4 clntudp_bufcreate F
>  GLIBC_2.4 clntudp_create F
>  GLIBC_2.4 clntunix_create F
>  GLIBC_2.4 clock F
> +GLIBC_2.4 clock_getcpuclockid F
> +GLIBC_2.4 clock_getres F
> +GLIBC_2.4 clock_gettime F
> +GLIBC_2.4 clock_nanosleep F
> +GLIBC_2.4 clock_settime F
>  GLIBC_2.4 clone F
>  GLIBC_2.4 close F
>  GLIBC_2.4 closedir F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist
> index cfbbd27557..3c0647b251 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/librt.abilist
> @@ -13,11 +13,6 @@ GLIBC_2.4 aio_suspend F
>  GLIBC_2.4 aio_suspend64 F
>  GLIBC_2.4 aio_write F
>  GLIBC_2.4 aio_write64 F
> -GLIBC_2.4 clock_getcpuclockid F
> -GLIBC_2.4 clock_getres F
> -GLIBC_2.4 clock_gettime F
> -GLIBC_2.4 clock_nanosleep F
> -GLIBC_2.4 clock_settime F
>  GLIBC_2.4 lio_listio F
>  GLIBC_2.4 lio_listio64 F
>  GLIBC_2.4 mq_close F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index 47eb7b4608..64d4623b6b 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -1825,6 +1825,11 @@ GLIBC_2.2 _flushlbf F
>  GLIBC_2.2 _res_hconf D 0x30
>  GLIBC_2.2 alphasort64 F
>  GLIBC_2.2 bind_textdomain_codeset F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 dcngettext F
>  GLIBC_2.2 dngettext F
>  GLIBC_2.2 fgetpos F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist
> index 595f1b712a..bb03781dcc 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/librt.abilist
> @@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
>  GLIBC_2.1 aio_write64 F
>  GLIBC_2.1 lio_listio F
>  GLIBC_2.1 lio_listio64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 shm_open F
>  GLIBC_2.2 shm_unlink F
>  GLIBC_2.2 timer_create F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/microblaze/librt.abilist b/sysdeps/unix/sysv/linux/microblaze/librt.abilist
> index fb85d8729e..889dfbc0ee 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/librt.abilist
> @@ -14,11 +14,6 @@ GLIBC_2.18 aio_suspend F
>  GLIBC_2.18 aio_suspend64 F
>  GLIBC_2.18 aio_write F
>  GLIBC_2.18 aio_write64 F
> -GLIBC_2.18 clock_getcpuclockid F
> -GLIBC_2.18 clock_getres F
> -GLIBC_2.18 clock_gettime F
> -GLIBC_2.18 clock_nanosleep F
> -GLIBC_2.18 clock_settime F
>  GLIBC_2.18 lio_listio F
>  GLIBC_2.18 lio_listio64 F
>  GLIBC_2.18 mq_close F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index e49dc4272e..06c2e64edd 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -1612,6 +1612,11 @@ GLIBC_2.2 capget F
>  GLIBC_2.2 capset F
>  GLIBC_2.2 cbc_crypt F
>  GLIBC_2.2 clntunix_create F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 creat64 F
>  GLIBC_2.2 dcngettext F
>  GLIBC_2.2 des_setparity F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist b/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist
> index 84837c8a2e..1539c1cef9 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/librt.abilist
> @@ -13,11 +13,6 @@ GLIBC_2.2 aio_suspend F
>  GLIBC_2.2 aio_suspend64 F
>  GLIBC_2.2 aio_write F
>  GLIBC_2.2 aio_write64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 lio_listio F
>  GLIBC_2.2 lio_listio64 F
>  GLIBC_2.2 shm_open F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index daa3b60c5b..bdfd073b86 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -1610,6 +1610,11 @@ GLIBC_2.2 capget F
>  GLIBC_2.2 capset F
>  GLIBC_2.2 cbc_crypt F
>  GLIBC_2.2 clntunix_create F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 creat64 F
>  GLIBC_2.2 dcngettext F
>  GLIBC_2.2 des_setparity F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist b/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist
> index 84837c8a2e..1539c1cef9 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/librt.abilist
> @@ -13,11 +13,6 @@ GLIBC_2.2 aio_suspend F
>  GLIBC_2.2 aio_suspend64 F
>  GLIBC_2.2 aio_write F
>  GLIBC_2.2 aio_write64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 lio_listio F
>  GLIBC_2.2 lio_listio64 F
>  GLIBC_2.2 shm_open F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index 457ce0b6f2..3d61d4974a 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -1611,6 +1611,11 @@ GLIBC_2.2 capget F
>  GLIBC_2.2 capset F
>  GLIBC_2.2 cbc_crypt F
>  GLIBC_2.2 clntunix_create F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 creat64 F
>  GLIBC_2.2 dcngettext F
>  GLIBC_2.2 des_setparity F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index 63d5c03bfb..675acca5db 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -1607,6 +1607,11 @@ GLIBC_2.2 capget F
>  GLIBC_2.2 capset F
>  GLIBC_2.2 cbc_crypt F
>  GLIBC_2.2 clntunix_create F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 creat64 F
>  GLIBC_2.2 dcngettext F
>  GLIBC_2.2 des_setparity F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index 9200a54309..1e8ff6f83e 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -1830,6 +1830,11 @@ GLIBC_2.2 __xstat64 F
>  GLIBC_2.2 _flushlbf F
>  GLIBC_2.2 _res_hconf D 0x30
>  GLIBC_2.2 bind_textdomain_codeset F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 dcngettext F
>  GLIBC_2.2 dngettext F
>  GLIBC_2.2 fgetpos F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
> index 595f1b712a..bb03781dcc 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
> @@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
>  GLIBC_2.1 aio_write64 F
>  GLIBC_2.1 lio_listio F
>  GLIBC_2.1 lio_listio64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 shm_open F
>  GLIBC_2.2 shm_unlink F
>  GLIBC_2.2 timer_create F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index ef7779905f..b5a0751d90 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -1834,6 +1834,11 @@ GLIBC_2.2 __xstat64 F
>  GLIBC_2.2 _flushlbf F
>  GLIBC_2.2 _res_hconf D 0x30
>  GLIBC_2.2 bind_textdomain_codeset F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 dcngettext F
>  GLIBC_2.2 dngettext F
>  GLIBC_2.2 fgetpos F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> index 2860df8ebc..0c86217fc6 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> @@ -673,6 +673,11 @@ GLIBC_2.3 clntudp_bufcreate F
>  GLIBC_2.3 clntudp_create F
>  GLIBC_2.3 clntunix_create F
>  GLIBC_2.3 clock F
> +GLIBC_2.3 clock_getcpuclockid F
> +GLIBC_2.3 clock_getres F
> +GLIBC_2.3 clock_gettime F
> +GLIBC_2.3 clock_nanosleep F
> +GLIBC_2.3 clock_settime F
>  GLIBC_2.3 clone F
>  GLIBC_2.3 close F
>  GLIBC_2.3 closedir F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/librt.abilist
> index e76b7eb495..6a5bd96963 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/librt.abilist
> @@ -13,11 +13,6 @@ GLIBC_2.3 aio_suspend F
>  GLIBC_2.3 aio_suspend64 F
>  GLIBC_2.3 aio_write F
>  GLIBC_2.3 aio_write64 F
> -GLIBC_2.3 clock_getcpuclockid F
> -GLIBC_2.3 clock_getres F
> -GLIBC_2.3 clock_gettime F
> -GLIBC_2.3 clock_nanosleep F
> -GLIBC_2.3 clock_settime F
>  GLIBC_2.3 lio_listio F
>  GLIBC_2.3 lio_listio64 F
>  GLIBC_2.3 shm_open F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index 576295deff..122d0fb65a 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -1829,6 +1829,11 @@ GLIBC_2.2 _flushlbf F
>  GLIBC_2.2 _res_hconf D 0x30
>  GLIBC_2.2 alphasort64 F
>  GLIBC_2.2 bind_textdomain_codeset F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 dcngettext F
>  GLIBC_2.2 dngettext F
>  GLIBC_2.2 fgetpos F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist
> index 595f1b712a..bb03781dcc 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/librt.abilist
> @@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
>  GLIBC_2.1 aio_write64 F
>  GLIBC_2.1 lio_listio F
>  GLIBC_2.1 lio_listio64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 shm_open F
>  GLIBC_2.2 shm_unlink F
>  GLIBC_2.2 timer_create F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index abf0473683..efe588a072 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -632,6 +632,11 @@ GLIBC_2.2 clntudp_bufcreate F
>  GLIBC_2.2 clntudp_create F
>  GLIBC_2.2 clntunix_create F
>  GLIBC_2.2 clock F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 clone F
>  GLIBC_2.2 close F
>  GLIBC_2.2 closedir F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist
> index 41be3bb84b..5905498a48 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/librt.abilist
> @@ -13,11 +13,6 @@ GLIBC_2.2 aio_suspend F
>  GLIBC_2.2 aio_suspend64 F
>  GLIBC_2.2 aio_write F
>  GLIBC_2.2 aio_write64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 lio_listio F
>  GLIBC_2.2 lio_listio64 F
>  GLIBC_2.2 shm_open F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
> index 41977f6e9c..4b057bf4a2 100644
> --- a/sysdeps/unix/sysv/linux/sh/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
> @@ -618,6 +618,11 @@ GLIBC_2.2 clntudp_bufcreate F
>  GLIBC_2.2 clntudp_create F
>  GLIBC_2.2 clntunix_create F
>  GLIBC_2.2 clock F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 clone F
>  GLIBC_2.2 close F
>  GLIBC_2.2 closedir F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sh/librt.abilist b/sysdeps/unix/sysv/linux/sh/librt.abilist
> index 595f1b712a..bb03781dcc 100644
> --- a/sysdeps/unix/sysv/linux/sh/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/librt.abilist
> @@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
>  GLIBC_2.1 aio_write64 F
>  GLIBC_2.1 lio_listio F
>  GLIBC_2.1 lio_listio64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 shm_open F
>  GLIBC_2.2 shm_unlink F
>  GLIBC_2.2 timer_create F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index 3d2f00ca52..49cd597fd6 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -1826,6 +1826,11 @@ GLIBC_2.2 __xstat64 F
>  GLIBC_2.2 _flushlbf F
>  GLIBC_2.2 _res_hconf D 0x30
>  GLIBC_2.2 bind_textdomain_codeset F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 dcngettext F
>  GLIBC_2.2 dngettext F
>  GLIBC_2.2 fgetpos F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist
> index cb874f4147..38f0aad791 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/librt.abilist
> @@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
>  GLIBC_2.1 aio_write64 F
>  GLIBC_2.1 lio_listio F
>  GLIBC_2.1 lio_listio64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 shm_open F
>  GLIBC_2.2 shm_unlink F
>  GLIBC_2.2 timer_create F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index 2f20643e8e..95e68e0ba1 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -660,6 +660,11 @@ GLIBC_2.2 clntudp_bufcreate F
>  GLIBC_2.2 clntudp_create F
>  GLIBC_2.2 clntunix_create F
>  GLIBC_2.2 clock F
> +GLIBC_2.2 clock_getcpuclockid F
> +GLIBC_2.2 clock_getres F
> +GLIBC_2.2 clock_gettime F
> +GLIBC_2.2 clock_nanosleep F
> +GLIBC_2.2 clock_settime F
>  GLIBC_2.2 clone F
>  GLIBC_2.2 close F
>  GLIBC_2.2 closedir F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist
> index d7a049cf60..71f86e03ce 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/librt.abilist
> @@ -15,11 +15,6 @@ GLIBC_2.1 aio_write F
>  GLIBC_2.1 aio_write64 F
>  GLIBC_2.1 lio_listio F
>  GLIBC_2.1 lio_listio64 F
> -GLIBC_2.2 clock_getcpuclockid F
> -GLIBC_2.2 clock_getres F
> -GLIBC_2.2 clock_gettime F
> -GLIBC_2.2 clock_nanosleep F
> -GLIBC_2.2 clock_settime F
>  GLIBC_2.2 shm_open F
>  GLIBC_2.2 shm_unlink F
>  GLIBC_2.2 timer_create F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index 59f85d9373..1f2dbd1451 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -621,6 +621,11 @@ GLIBC_2.2.5 clntudp_bufcreate F
>  GLIBC_2.2.5 clntudp_create F
>  GLIBC_2.2.5 clntunix_create F
>  GLIBC_2.2.5 clock F
> +GLIBC_2.2.5 clock_getcpuclockid F
> +GLIBC_2.2.5 clock_getres F
> +GLIBC_2.2.5 clock_gettime F
> +GLIBC_2.2.5 clock_nanosleep F
> +GLIBC_2.2.5 clock_settime F
>  GLIBC_2.2.5 clone F
>  GLIBC_2.2.5 close F
>  GLIBC_2.2.5 closedir F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist b/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist
> index e2e8b60bf8..95e3f22daa 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/librt.abilist
> @@ -13,11 +13,6 @@ GLIBC_2.2.5 aio_suspend F
>  GLIBC_2.2.5 aio_suspend64 F
>  GLIBC_2.2.5 aio_write F
>  GLIBC_2.2.5 aio_write64 F
> -GLIBC_2.2.5 clock_getcpuclockid F
> -GLIBC_2.2.5 clock_getres F
> -GLIBC_2.2.5 clock_gettime F
> -GLIBC_2.2.5 clock_nanosleep F
> -GLIBC_2.2.5 clock_settime F
>  GLIBC_2.2.5 lio_listio F
>  GLIBC_2.2.5 lio_listio64 F
>  GLIBC_2.2.5 shm_open F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index 67a4e238d6..59da85a5d8 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -660,6 +660,11 @@ GLIBC_2.16 clntudp_create F
>  GLIBC_2.16 clntunix_create F
>  GLIBC_2.16 clock F
>  GLIBC_2.16 clock_adjtime F
> +GLIBC_2.16 clock_getcpuclockid F
> +GLIBC_2.16 clock_getres F
> +GLIBC_2.16 clock_gettime F
> +GLIBC_2.16 clock_nanosleep F
> +GLIBC_2.16 clock_settime F
>  GLIBC_2.16 clone F
>  GLIBC_2.16 close F
>  GLIBC_2.16 closedir F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist
> index 94e84e4dcf..66969fb9ab 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/librt.abilist
> @@ -14,11 +14,6 @@ GLIBC_2.16 aio_suspend F
>  GLIBC_2.16 aio_suspend64 F
>  GLIBC_2.16 aio_write F
>  GLIBC_2.16 aio_write64 F
> -GLIBC_2.16 clock_getcpuclockid F
> -GLIBC_2.16 clock_getres F
> -GLIBC_2.16 clock_gettime F
> -GLIBC_2.16 clock_nanosleep F
> -GLIBC_2.16 clock_settime F
>  GLIBC_2.16 lio_listio F
>  GLIBC_2.16 lio_listio64 F
>  GLIBC_2.16 mq_close F

Ok.

> diff --git a/time/Makefile b/time/Makefile
> index a428f55245..85a62c0376 100644
> --- a/time/Makefile
> +++ b/time/Makefile
> @@ -36,14 +36,18 @@ routines := offtime asctime clock ctime ctime_r difftime \
>  	    stime dysize timegm ftime			 \
>  	    getdate strptime strptime_l			 \
>  	    strftime wcsftime strftime_l wcsftime_l	 \
> -	    timespec_get
> +	    timespec_get 	 			 \
> +	    clock_getcpuclockid clock_getres 		 \
> +	    clock_gettime clock_settime clock_nanosleep
> +
>  aux :=	    era alt_digit lc-time-cleanup
>  
>  tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
>  	   tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
>  	   tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
>  	   tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime \
> -	   tst-tzname tst-y2039 bug-mktime4 tst-strftime2 tst-strftime3
> +	   tst-tzname tst-y2039 bug-mktime4 tst-strftime2 tst-strftime3 \
> +	   tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1
>  
>  include ../Rules
>  

Ok.

> diff --git a/time/Versions b/time/Versions
> index fd838181e4..8788e192ce 100644
> --- a/time/Versions
> +++ b/time/Versions
> @@ -49,6 +49,10 @@ libc {
>    GLIBC_2.2 {
>      # w*
>      wcsftime;
> +
> +    # c*; actually in librt in version 2.2, moved to libc in 2.17
> +    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
> +    clock_nanosleep;
>    }
>    GLIBC_2.3 {
>      # these internal names are used by libstdc++

Ok.

> @@ -65,4 +69,13 @@ libc {
>    GLIBC_2.16 {
>      timespec_get;
>    }
> +  GLIBC_2.17 {
> +    # c*
> +    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
> +    clock_nanosleep;
> +  }
> +  GLIBC_PRIVATE {
> +    # same as clock_gettime; used in other libraries
> +    __clock_gettime;
> +  }
>  }

Ok.

> diff --git a/rt/clock_getcpuclockid.c b/time/clock_getcpuclockid.c
> similarity index 75%
> rename from rt/clock_getcpuclockid.c
> rename to time/clock_getcpuclockid.c
> index 22b9f1383c..8d205abfa9 100644
> --- a/rt/clock_getcpuclockid.c
> +++ b/time/clock_getcpuclockid.c
> @@ -19,6 +19,7 @@
>  #include <errno.h>
>  #include <time.h>
>  #include <unistd.h>
> +#include <shlib-compat.h>
>  
>  int
>  __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
> @@ -37,4 +38,10 @@ __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
>    return ENOENT;
>  #endif
>  }
> -weak_alias (__clock_getcpuclockid, clock_getcpuclockid)
> +versioned_symbol (libc, __clock_getcpuclockid, clock_getcpuclockid, GLIBC_2_17);
> +/* clock_getcpuclockid moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_getcpuclockid, __clock_getcpuclockid_2);
> +compat_symbol (libc, __clock_getcpuclockid_2, clock_getcpuclockid, GLIBC_2_2);
> +#endif

Ok.

> diff --git a/rt/clock_getres.c b/time/clock_getres.c
> similarity index 73%
> rename from rt/clock_getres.c
> rename to time/clock_getres.c
> index b990bf0af0..412f80fbec 100644
> --- a/rt/clock_getres.c
> +++ b/time/clock_getres.c
> @@ -18,6 +18,7 @@
>  
>  #include <errno.h>
>  #include <time.h>
> +#include <shlib-compat.h>
>  
>  /* Get resolution of clock.  */
>  int
> @@ -26,5 +27,13 @@ __clock_getres (clockid_t clock_id, struct timespec *res)
>    __set_errno (ENOSYS);
>    return -1;
>  }
> -weak_alias (__clock_getres, clock_getres)
> +
> +versioned_symbol (libc, __clock_getres, clock_getres, GLIBC_2_17);
> +/* clock_getres moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_getres, __clock_getres_2);
> +compat_symbol (libc, __clock_getres_2, clock_getres, GLIBC_2_2);
> +#endif
> +
>  stub_warning (clock_getres)

Ok.

> diff --git a/rt/clock_gettime.c b/time/clock_gettime.c
> similarity index 74%
> rename from rt/clock_gettime.c
> rename to time/clock_gettime.c
> index 0426dd2c76..92c6081dcb 100644
> --- a/rt/clock_gettime.c
> +++ b/time/clock_gettime.c
> @@ -18,6 +18,7 @@
>  
>  #include <errno.h>
>  #include <time.h>
> +#include <shlib-compat.h>
>  
>  /* Get current value of CLOCK and store it in TP.  */
>  int
> @@ -26,6 +27,14 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp)
>    __set_errno (ENOSYS);
>    return -1;
>  }
> -weak_alias (__clock_gettime, clock_gettime)
>  libc_hidden_def (__clock_gettime)
> +
> +versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17);
> +/* clock_gettime moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_gettime, __clock_gettime_2);
> +compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2);
> +#endif
> +
>  stub_warning (clock_gettime)

Ok.

> diff --git a/rt/clock_nanosleep.c b/time/clock_nanosleep.c
> similarity index 76%
> rename from rt/clock_nanosleep.c
> rename to time/clock_nanosleep.c
> index 5b724e593b..c53c820880 100644
> --- a/rt/clock_nanosleep.c
> +++ b/time/clock_nanosleep.c
> @@ -18,6 +18,7 @@
>  
>  #include <errno.h>
>  #include <time.h>
> +#include <shlib-compat.h>
>  
>  int
>  __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
> @@ -33,5 +34,13 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
>    /* Not implemented.  */
>    return ENOSYS;
>  }
> -weak_alias (__clock_nanosleep, clock_nanosleep)
> +
> +versioned_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_17);
> +/* clock_nanosleep moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_nanosleep, __clock_nanosleep_2);
> +compat_symbol (libc, __clock_nanosleep_2, clock_nanosleep, GLIBC_2_2);
> +#endif
> +
>  stub_warning (clock_nanosleep)

Ok.

> diff --git a/rt/clock_settime.c b/time/clock_settime.c
> similarity index 71%
> rename from rt/clock_settime.c
> rename to time/clock_settime.c
> index 891925ab2c..dd86a1c189 100644
> --- a/rt/clock_settime.c
> +++ b/time/clock_settime.c
> @@ -18,6 +18,7 @@
>  
>  #include <errno.h>
>  #include <time.h>
> +#include <shlib-compat.h>
>  
>  /* Set CLOCK to value TP.  */
>  int
> @@ -26,5 +27,14 @@ __clock_settime (clockid_t clock_id, const struct timespec *tp)
>    __set_errno (ENOSYS);
>    return -1;
>  }
> -weak_alias (__clock_settime, clock_settime)
> +libc_hidden_def (__clock_settime)
> +
> +versioned_symbol (libc, __clock_settime, clock_settime, GLIBC_2_17);
> +/* clock_settime moved to libc in version 2.17;
> +   old binaries may expect the symbol version it had in librt.  */
> +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (__clock_settime, __clock_settime_2);
> +compat_symbol (libc, __clock_settime_2, clock_settime, GLIBC_2_2);
> +#endif
> +
>  stub_warning (clock_settime)

Ok.

> diff --git a/rt/tst-clock.c b/time/tst-clock.c
> similarity index 100%
> rename from rt/tst-clock.c
> rename to time/tst-clock.c

Ok.

> diff --git a/rt/tst-clock2.c b/time/tst-clock2.c
> similarity index 100%
> rename from rt/tst-clock2.c
> rename to time/tst-clock2.c

Ok.

> diff --git a/rt/tst-clock_nanosleep.c b/time/tst-clock_nanosleep.c
> similarity index 100%
> rename from rt/tst-clock_nanosleep.c
> rename to time/tst-clock_nanosleep.c

Ok.

> diff --git a/rt/tst-cpuclock1.c b/time/tst-cpuclock1.c
> similarity index 100%
> rename from rt/tst-cpuclock1.c
> rename to time/tst-cpuclock1.c
> 

Ok.


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

* Re: [PATCH v2 03/10] Use clock_settime to implement stime; withdraw stime.
  2019-08-28 15:32 ` [PATCH v2 03/10] Use clock_settime to implement stime; withdraw stime Zack Weinberg
@ 2019-08-30 17:54   ` Adhemerval Zanella
  0 siblings, 0 replies; 44+ messages in thread
From: Adhemerval Zanella @ 2019-08-30 17:54 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Samuel Thibault



On 28/08/2019 12:32, Zack Weinberg wrote:
> 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.
> 
> 	* time/stime.c (stime): No longer a stub implementation.
> 	Call __clock_settime.  Demote to a compatibility symbol.
> 
> 	* sysdeps/unix/stime.c: Delete file.
> 	* sysdeps/unix/sysv/linux/syscalls.list: Remove entry for stime.
> 
> 	* time/time.h: Remove prototype for stime.

Should we add a NEW entry for this?

LGTM, thanks.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

> ---
>  sysdeps/unix/stime.c                  | 39 ---------------------------
>  sysdeps/unix/sysv/linux/syscalls.list |  1 -
>  time/stime.c                          | 25 ++++++++---------
>  time/time.h                           |  6 -----
>  4 files changed, 13 insertions(+), 58 deletions(-)
>  delete mode 100644 sysdeps/unix/stime.c
> 
> diff --git a/sysdeps/unix/stime.c b/sysdeps/unix/stime.c
> deleted file mode 100644
> index b0809be400..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
> -   <http://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);
> -}

Ok.

> 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

Ok.

> diff --git a/time/stime.c b/time/stime.c
> index de58c49562..754e2da0b0 100644
> --- a/time/stime.c
> +++ b/time/stime.c
> @@ -15,23 +15,24 @@
>     License along with the GNU C Library; if not, see
>     <http://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

Ok.

> diff --git a/time/time.h b/time/time.h
> index cba6d15260..57cfd4d330 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).  */
> 

Ok.

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

* Re: [PATCH v2 10/10] Revise the documentation of simple calendar time.
  2019-08-29 17:41     ` Zack Weinberg
@ 2019-08-30 19:17       ` Paul Eggert
  0 siblings, 0 replies; 44+ messages in thread
From: Paul Eggert @ 2019-08-30 19:17 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: GNU C Library, Joseph Myers, Florian Weimer, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Adhemerval Zanella, Samuel Thibault

>> This function uses a clock close to the clocks of @w{@samp{clock_gettime
>> (CLOCK_REALTIME)}} and of @code{gettimeofday} (see below), but the three clocks
>> are not necessarily in lock-step, and precise timestamp comparison is reliable
>> only when timestamps come from the same clock.

> I think it's good to add a cautionary note *like  this, but I'm
> worried that your suggested text might confuse readers into thinking
> that these clocks might use different epochs or could be set
> independently.  I'll think about how to put it better.

Yes, the wording "close to" was my attempt to prevent that conclusion. 
The wording could be expanded -- though when I tried to expand it 
myself, I found that the expansion was not clearer enough to be worth 
the extra words.

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

* Re: [PATCH v2 04/10] Use clock_settime to implement settimeofday.
  2019-08-28 15:32 ` [PATCH v2 04/10] Use clock_settime to implement settimeofday Zack Weinberg
@ 2019-09-02 13:22   ` Adhemerval Zanella
  2019-09-03 14:44     ` Zack Weinberg
  0 siblings, 1 reply; 44+ messages in thread
From: Adhemerval Zanella @ 2019-09-02 13:22 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Samuel Thibault



On 28/08/2019 12:32, Zack Weinberg wrote:
> 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.

I think it is a fair requirement.

> 
> 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.

We definitely need a NEWS entry for this change. 

> 
> 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.

It is worth to mention that 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).

So the idea is to future 64-bit time_t only ABIs 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.
> 
> 	* time/settimeofday.c (settimeofday): No longer a stub
> 	implementation.  Call __clock_settime or __settimezone depending
> 	on arguments.  Optionally override the default symbol version for
> 	settimeofday.
> 	* include/sys/time.h: Remove prototype for __settimeofday.
> 	Add prototype for __settimezone.
> 	* sysdeps/unix/syscalls.list: Remove entry for settimeofday.
> 
> 	* time/settimezone.c: New file.
> 	(__settimezone): New stub implementation.
> 	* sysdeps/unix/sysv/linux/settimezone.c: New file.
> 	(__settimezone): Implement using settimeofday system call,
> 	if available.
> 	* time/Makefile (routines): Add settimezone.
> 
> 	* sysdeps/unix/sysv/linux/alpha/syscalls.list:
> 	Remove entries for settimeofday and osf_settimeofday.
> 	* sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
> 	New file, defines settimeofday@GLIBC_2.0.
> 	* sysdeps/unix/sysv/linux/alpha/settimeofday.c:
> 	New file, defines settimeofday@@GLIBC_2.1.
> 
> 	* sysdeps/unix/clock_gettime.c: Delete file.
> 	* sysdeps/mach/hurd/settimeofday.c: Rename to
> 	sysdeps/mach/hurd/clock_settime.c and convert into an
> 	implementation of clock_settime.
> ---
>  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         | 39 ++++++++++++++
>  time/Makefile                                 |  8 +--
>  time/settimeofday.c                           | 24 +++++++--
>  .../hurd/settimeofday.c => time/settimezone.c | 34 ++-----------
>  10 files changed, 126 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/include/sys/time.h b/include/sys/time.h
> index 7ba0ca7c2d..a57752e8c7 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);

Ok.

> 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 5b398491ab..0a32f8d1a0 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)
>  

Looks ok, although I can't voucher for Hurd modifications.

> 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

Ok.

> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
> index 475e0fd656..9221deb80f 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);

Ok.

> 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>

Ok.

> 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

Ok.

> diff --git a/sysdeps/unix/sysv/linux/settimezone.c b/sysdeps/unix/sysv/linux/settimezone.c
> new file mode 100644
> index 0000000000..823f4fe42f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/settimezone.c
> @@ -0,0 +1,39 @@

One line comment.

> +/* 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.  */
> +
> +#ifdef __NR_settimeofday
> +
> +int
> +__settimezone (const struct timezone *tz)
> +{
> +  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
> +}
> +
> +#else
> +
> +#include <time/settimezone.c>
> +
> +#endif

I think it would be simpler to just add the expected behaviour instead of
include the default implementation to make it more clearly:

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 85a62c0376..791db1c8e3 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

Ok.

> diff --git a/time/settimeofday.c b/time/settimeofday.c
> index 4620559652..78f666e352 100644
> --- a/time/settimeofday.c
> +++ b/time/settimeofday.c
> @@ -16,6 +16,7 @@
>     <http://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

Ok.

> 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 bd0ffd64ac..eb005da213 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)
> 

Ok.

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

* Re: [PATCH v2 05/10] Use clock_gettime to implement time.
  2019-08-29 17:49             ` Zack Weinberg
@ 2019-09-02 13:32               ` Florian Weimer
  2019-09-02 18:35                 ` Adhemerval Zanella
  0 siblings, 1 reply; 44+ messages in thread
From: Florian Weimer @ 2019-09-02 13:32 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: Paul Eggert, GNU C Library, Joseph Myers, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Adhemerval Zanella, Samuel Thibault

* Zack Weinberg:

> On Wed, Aug 28, 2019 at 5:39 PM Florian Weimer <fweimer@redhat.com> wrote:
>> I think we should keep using the time entry in the vDSO.  This
>> consolidation is just not possible to do for performance reasons.
>
> To be crystal clear about where I'm coming from, I think this
> consolidation is *necessary* to clear the way for the y2038 patches.

But it's not an absolute technical requirement, right?

I mean, if we wanted, we could still add a file like
sysdeps/unix/sysv/linux/x86_64/time.c and do things differently there?
(Although we'd also have to change the vDSO setup code for an efficient
implementation.)

> And I was under the impression that the kernel people wanted to
> withdraw support for the time and gettimeofday entry points (at least
> for new architectures going forward).

Yes, but that doesn't mean they want performance regressions on x86-64.
I think.

> So I'm only looking for ways to mitigate the performance impact at
> this point.  Before I back off on "henceforth we only call the
> kernel's clock_gettime" I would need to hear *both* a really
> compelling argument for why we need to keep calling the time or
> gettimeofday entry points -- a few ns more expense on a call that only
> reports the time to the nearest second isn't going to cut it -- *and*
> an explanation of why it won't interfere with the y2038 work and/or
> why we won't have to stop using them in the future anyway.

I expect that people have time calls in (binary) logging code where this
is visible.  I think EXPLAIN ANALYZE in PostgreSQL also rather sensitive
to timing performance, but fortunately it already uses
clock_gettimeofday.

I'm not too concerned here (assuming that we *can* still optimize the
time function on select architectures if that proves necessary in a
couple of years).  It's just that I really dislike the idea of
performance regressions on 64-bit architectures as a side effect of
Y2038 support on 32-bit architectures.

Thanks,
Florian

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

* Re: [PATCH v2 05/10] Use clock_gettime to implement time.
  2019-09-02 13:32               ` Florian Weimer
@ 2019-09-02 18:35                 ` Adhemerval Zanella
  0 siblings, 0 replies; 44+ messages in thread
From: Adhemerval Zanella @ 2019-09-02 18:35 UTC (permalink / raw)
  To: Florian Weimer, Zack Weinberg
  Cc: Paul Eggert, GNU C Library, Joseph Myers, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Samuel Thibault



On 02/09/2019 10:32, Florian Weimer wrote:
> * Zack Weinberg:
> 
>> On Wed, Aug 28, 2019 at 5:39 PM Florian Weimer <fweimer@redhat.com> wrote:
>>> I think we should keep using the time entry in the vDSO.  This
>>> consolidation is just not possible to do for performance reasons.
>>
>> To be crystal clear about where I'm coming from, I think this
>> consolidation is *necessary* to clear the way for the y2038 patches.
> 
> But it's not an absolute technical requirement, right?
> 
> I mean, if we wanted, we could still add a file like
> sysdeps/unix/sysv/linux/x86_64/time.c and do things differently there?
> (Although we'd also have to change the vDSO setup code for an efficient
> implementation.)
> 
>> And I was under the impression that the kernel people wanted to
>> withdraw support for the time and gettimeofday entry points (at least
>> for new architectures going forward).
> 
> Yes, but that doesn't mean they want performance regressions on x86-64.
> I think.
> 
>> So I'm only looking for ways to mitigate the performance impact at
>> this point.  Before I back off on "henceforth we only call the
>> kernel's clock_gettime" I would need to hear *both* a really
>> compelling argument for why we need to keep calling the time or
>> gettimeofday entry points -- a few ns more expense on a call that only
>> reports the time to the nearest second isn't going to cut it -- *and*
>> an explanation of why it won't interfere with the y2038 work and/or
>> why we won't have to stop using them in the future anyway.
> 
> I expect that people have time calls in (binary) logging code where this
> is visible.  I think EXPLAIN ANALYZE in PostgreSQL also rather sensitive
> to timing performance, but fortunately it already uses
> clock_gettimeofday.
> 
> I'm not too concerned here (assuming that we *can* still optimize the
> time function on select architectures if that proves necessary in a
> couple of years).  It's just that I really dislike the idea of
> performance regressions on 64-bit architectures as a side effect of
> Y2038 support on 32-bit architectures.

I think the *default* implementation for time should indeed be done through
clock_gettime, as this patch intends, however I also think it is possible to
keep arch-specific code in place so the optimized vDSO implementation are
used. It will also allow each arch maintainer to do the switch if the
consensus would to use the default one.

My view is we can use my proposed patch to refactor time [1], and change
the fallback syscall path to call clock_gettime instead.  I can work
towards the modification.

[1] https://sourceware.org/ml/libc-alpha/2019-07/msg00157.html

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

* Re: [PATCH v2 06/10] Use clock_gettime to implement ftime; withdraw ftime.
  2019-08-28 15:32 ` [PATCH v2 06/10] Use clock_gettime to implement ftime; withdraw ftime Zack Weinberg
@ 2019-09-02 18:42   ` Adhemerval Zanella
  0 siblings, 0 replies; 44+ messages in thread
From: Adhemerval Zanella @ 2019-09-02 18:42 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Samuel Thibault



On 28/08/2019 12:32, Zack Weinberg wrote:
> 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 made a compatibility symbol.  The public
> header file that declared it, its result structure, and nothing else,
> is removed.
> 
> 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.

Sound reasonable.

> 
> 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.

Ok.

> 
> 	* time/tst-ftime.c
> 	* time/sys/timeb.h
> 	* sysdeps/unix/bsd/ftime.c
> 	* sysdeps/unix/sysv/linux/ftime.c: Delete file.
> 	* time/tst-ftime_l.c: Rename to tst-strftime_l.c.
> 
> 	* time/ftime.c (ftime): Make a compatibility-only symbol.
> 	Replace implementation with the code formerly in
> 	sysdeps/unix/bsd/ftime.c, then change that code to use
> 	__clock_gettime instead of __gettimeofday and to truncate
> 	rather than rounding.  Always set the timezone and dstflag
> 	fields of the timebuf argument to zero.
> 
> 	* time/Makefile (headers): Remove sys/timeb.h.
> 	(tests): Remove tst-ftime, change tst-ftime_l to
> 	tst-strftime_l.
> 
> 	* conform/Makefile: XFAIL all tests related to sys/timeb.h.
> ---
>  conform/Makefile                         |  9 ++++
>  sysdeps/unix/bsd/ftime.c                 | 40 ----------------
>  sysdeps/unix/sysv/linux/ftime.c          |  3 --
>  time/Makefile                            |  8 ++--
>  time/ftime.c                             | 40 +++++++++-------
>  time/sys/timeb.h                         | 43 ------------------
>  time/tst-ftime.c                         | 58 ------------------------
>  time/{tst-ftime_l.c => tst-strftime_l.c} |  0
>  8 files changed, 36 insertions(+), 165 deletions(-)
>  delete mode 100644 sysdeps/unix/bsd/ftime.c
>  delete mode 100644 sysdeps/unix/sysv/linux/ftime.c
>  delete mode 100644 time/sys/timeb.h
>  delete mode 100644 time/tst-ftime.c
>  rename time/{tst-ftime_l.c => tst-strftime_l.c} (100%)
> 
> diff --git a/conform/Makefile b/conform/Makefile
> index 59d569c4c5..8671c695e8 100644
> --- a/conform/Makefile
> +++ b/conform/Makefile
> @@ -241,3 +241,12 @@ test-xfail-XPG42/ndbm.h/linknamespace = yes
>  test-xfail-UNIX98/ndbm.h/linknamespace = yes
>  test-xfail-XOPEN2K/ndbm.h/linknamespace = yes
>  test-xfail-XOPEN2K8/ndbm.h/linknamespace = yes
> +
> +# Header no longer provided by glibc (obsoleted in newer POSIX
> +# standards).
> +test-xfail-UNIX98/sys/timeb.h/conform = yes
> +test-xfail-UNIX98/sys/timeb.h/linknamespace = yes
> +test-xfail-XOPEN2K/sys/timeb.h/conform = yes
> +test-xfail-XOPEN2K/sys/timeb.h/linknamespace = yes
> +test-xfail-XPG42/sys/timeb.h/conform = yes
> +test-xfail-XPG42/sys/timeb.h/linknamespace = yes

I think we will need to keep this header, at least one release, and mark is
as deprecated (maybe with a pragma warning) because some projects include
without configure checks (libsanitizer for instance).

> diff --git a/sysdeps/unix/bsd/ftime.c b/sysdeps/unix/bsd/ftime.c
> deleted file mode 100644
> index 3a1c6e9b01..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
> -   <http://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;
> -}

Ok.

> 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/Makefile b/time/Makefile
> index 791db1c8e3..93c7cc28d4 100644
> --- a/time/Makefile
> +++ b/time/Makefile
> @@ -22,7 +22,7 @@ subdir	:= time
>  
>  include ../Makeconfig
>  
> -headers := time.h sys/time.h sys/timeb.h bits/time.h			\
> +headers := time.h sys/time.h bits/time.h				\
>  	   bits/types/clockid_t.h bits/types/clock_t.h			\
>  	   bits/types/struct_itimerspec.h				\
>  	   bits/types/struct_timespec.h bits/types/struct_timeval.h	\

As before.

> @@ -43,9 +43,9 @@ routines := offtime asctime clock ctime ctime_r difftime \
>  aux :=	    era alt_digit lc-time-cleanup
>  
>  tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
> -	   tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
> +	   tst-getdate tst-mktime tst-mktime2 tst-strftime tst-strftime_l \
>  	   tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
> -	   tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime \
> +	   tst-strptime3 bug-getdate1 tst-strptime-whitespace \
>  	   tst-tzname tst-y2039 bug-mktime4 tst-strftime2 tst-strftime3 \
>  	   tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1
>  
> @@ -59,7 +59,7 @@ LOCALES := de_DE.ISO-8859-1 en_US.ISO-8859-1 ja_JP.EUC-JP fr_FR.UTF-8 \
>  	   nan_TW.UTF-8 lzh_TW.UTF-8
>  include ../gen-locales.mk
>  
> -$(objpfx)tst-ftime_l.out: $(gen-locales)
> +$(objpfx)tst-strftime_l.out: $(gen-locales)
>  $(objpfx)tst-strptime.out: $(gen-locales)
>  endif
>  
> diff --git a/time/ftime.c b/time/ftime.c
> index 6c2a256048..0db6b70adf 100644
> --- a/time/ftime.c
> +++ b/time/ftime.c
> @@ -15,27 +15,33 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> -#include <errno.h>
> -#include <time.h>
> -#include <sys/timeb.h>
> +#include <shlib-compat.h>
>  
> -int
> -ftime (struct timeb *timebuf)
> -{
> -  int save = errno;
> -  struct tm tp;
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_31)
>  
> -  __set_errno (0);
> -  if (time (&timebuf->time) == (time_t) -1 && errno != 0)
> -    return -1;
> -  timebuf->millitm = 0;
> +#include <time.h>
>  
> -  if (__localtime_r (&timebuf->time, &tp) == NULL)
> -    return -1;
> +struct timeb
> +{
> +  time_t time;			/* Seconds since epoch, as from `time'.  */
> +  unsigned short int millitm;	/* Additional milliseconds.  */
> +  short int timezone;		/* Minutes west of GMT.  */
> +  short int dstflag;		/* Nonzero if Daylight Savings Time used.  */
> +};
>  
> -  timebuf->timezone = tp.tm_gmtoff / 60;
> -  timebuf->dstflag = tp.tm_isdst;
> +int
> +attribute_compat_text_section
> +__ftime (struct timeb *timebuf)
> +{
> +  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;
>  }
> +compat_symbol (libc, __ftime, ftime, GLIBC_2_0);
> +
> +#endif

Ok.

> diff --git a/time/sys/timeb.h b/time/sys/timeb.h
> deleted file mode 100644
> index 6333e8074d..0000000000
> --- a/time/sys/timeb.h
> +++ /dev/null
> @@ -1,43 +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
> -   <http://www.gnu.org/licenses/>.  */
> -
> -#ifndef _SYS_TIMEB_H
> -#define _SYS_TIMEB_H	1
> -
> -#include <features.h>
> -
> -#include <bits/types/time_t.h>
> -
> -__BEGIN_DECLS
> -
> -/* Structure returned by the `ftime' function.  */
> -
> -struct timeb
> -  {
> -    time_t time;		/* Seconds since epoch, as from `time'.  */
> -    unsigned short int millitm;	/* Additional milliseconds.  */
> -    short int timezone;		/* Minutes west of GMT.  */
> -    short int dstflag;		/* Nonzero if Daylight Savings Time used.  */
> -  };
> -
> -/* Fill in TIMEBUF with information about the current time.  */
> -
> -extern int ftime (struct timeb *__timebuf);
> -
> -__END_DECLS
> -
> -#endif	/* sys/timeb.h */
> diff --git a/time/tst-ftime.c b/time/tst-ftime.c
> deleted file mode 100644
> index 65b753dec8..0000000000
> --- a/time/tst-ftime.c
> +++ /dev/null
> @@ -1,58 +0,0 @@
> -/* Verify that ftime is sane.
> -   Copyright (C) 2014-2019 Free Software Foundation, Inc.
> -   This file is part of the GNU C Library.
> -
> -   The GNU C Library is free software; you can redistribute it and/or
> -   modify it under the terms of the GNU Lesser General Public
> -   License as published by the Free Software Foundation; either
> -   version 2.1 of the License, or (at your option) any later version.
> -
> -   The GNU C Library is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -   Lesser General Public License for more details.
> -
> -   You should have received a copy of the GNU Lesser General Public
> -   License along with the GNU C Library; if not, see
> -   <http://www.gnu.org/licenses/>.  */
> -
> -#include <sys/timeb.h>
> -#include <stdio.h>
> -
> -static int
> -do_test (void)
> -{
> -  struct timeb prev, curr = {.time = 0, .millitm = 0};
> -  int sec = 0;
> -
> -  while (sec != 3)
> -    {
> -      prev = curr;
> -
> -      if (ftime (&curr))
> -        {
> -          printf ("ftime returned an error\n");
> -          return 1;
> -        }
> -
> -      if (curr.time < prev.time)
> -        {
> -          printf ("ftime's time flowed backwards\n");
> -          return 1;
> -        }
> -
> -      if (curr.time == prev.time
> -          && curr.millitm < prev.millitm)
> -        {
> -          printf ("ftime's millitm flowed backwards\n");
> -          return 1;
> -        }
> -
> -      if (curr.time > prev.time)
> -        sec ++;
> -    }
> -  return 0;
> -}
> -
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"

We can make it a internal test using TEST_COMPAT instead.

> diff --git a/time/tst-ftime_l.c b/time/tst-strftime_l.c
> similarity index 100%
> rename from time/tst-ftime_l.c
> rename to time/tst-strftime_l.c
> 

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

* Re: [PATCH v2 07/10] Use clock_gettime to implement timespec_get.
  2019-08-28 15:32 ` [PATCH v2 07/10] Use clock_gettime to implement timespec_get Zack Weinberg
@ 2019-09-02 19:25   ` Adhemerval Zanella
  0 siblings, 0 replies; 44+ messages in thread
From: Adhemerval Zanella @ 2019-09-02 19:25 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Samuel Thibault



On 28/08/2019 12:32, Zack Weinberg wrote:
> 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.
> 
> As such I think the most sensible GNUish policy for this function is
> that we will provide it, but we will not recommend its use, we will
> not go out of our way to make it efficient, and we will not attempt to
> extend the set of TIME_* constants beyond the ones defined in ISO
> C (and in POSIX, if it ever appears in POSIX).

I don't fully agree we should not optimize because of the mentioned reasons.
Like or not, it is the C11 standard function to get the timer in a system
independent way and I would expect that once more systems implement it
portable programs will rely on it (it seems that even Windows now support
it).

And I think we can still optimize it without adding much complexity on the
code base. One idea is to simple provide a system specific internal
header that on Linux will issue the INTERNAL_VSYSCAL as an inline
function. Something like:

--
#ifdef HAVE_CLOCK_GETTIME_VSYSCALL
# define HAVE_VSYSCALL
#endif
#include <sysdep-vdso.h>

static inline int
internal_clock_gettime (clockid_t clk_id, struct timespec *tp)
{
  return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp);
}
--

I think for timer function *specifically*, some users expects it has a low
latency for some usage patterns and I think we should provide if it is
feasible.

> 
> 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.  Oh well.
> 
> 	* sysdeps/posix/timespec_get.c
> 	* sysdeps/unix/sysv/linux/timespec_get.c: Delete file.
> 	* time/timespec_get.c: No longer a stub.  Replace implementation
> 	with the code formerly in sysdeps/posix/timespec_get.c.
> ---
>  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 781a624c7d..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
> -   <http://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;
> -}

Ok.

> diff --git a/sysdeps/unix/sysv/linux/timespec_get.c b/sysdeps/unix/sysv/linux/timespec_get.c
> deleted file mode 100644
> index 52080ddf08..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
> -   <http://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;
> -}

As before.

> diff --git a/time/timespec_get.c b/time/timespec_get.c
> index c9e58be5d8..5ac765add1 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)
> 

Ok.

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

* Re: [PATCH v2 08/10] Use clock_gettime to implement gettimeofday.
  2019-08-28 18:27   ` Florian Weimer
@ 2019-09-02 19:31     ` Adhemerval Zanella
  0 siblings, 0 replies; 44+ messages in thread
From: Adhemerval Zanella @ 2019-09-02 19:31 UTC (permalink / raw)
  To: Florian Weimer, Zack Weinberg
  Cc: libc-alpha, Joseph Myers, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Samuel Thibault



On 28/08/2019 15:27, Florian Weimer wrote:
> * Zack Weinberg:
> 
>> Remove sysdeps/unix/clock_gettime.c, which implemented clock_gettime
>> using gettimeofday; new OS ports must provide a real implementation of
>> clock_gettime.
> 
> This comes at a performance cost.  On a Xeon Gold 6126 with Fedora 31's
> 5.3.0-0.rc5.git0.1.fc31 kernel, I see 17.6 ns per gettimeofday call
> before this change, and 19.6 ns afterwards.
> 
> Part of that is the additional overhead of the functional call and the
> clock check.  I think gettimeofday should call directly into the vDSO.
> 
> Another part according to profiles is the downscaling of the nanoseconds
> value.  TIMESPEC_TO_TIMEVAL does not tell GCC that tv_nsec member does
> not use the full long range, so GCC emits a full 64-bit division (with a
> multiplication and shift).
> 
> Both changes will hopefully recover the performance loss.

As for time patch from this set, I think we can still make the *default*
gettimeofday implementation use the clock_gettime if the architecture
does not have a faster way to accomplish it (through vDSO or the ifunc
trick to reduce latency). It would allow each arch-mantainer to set if
or when the architecture will move generic implementation and cleanup
the optimized glue.

My view is we can use my proposed patch to refactor gettimeofdat [1], and 
change the fallback syscall path to call clock_gettime instead.  I can work
towards the modification.

[1] https://sourceware.org/ml/libc-alpha/2019-07/msg00158.html

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

* Re: [PATCH v2 02/10] Finish move of clock_* functions to libc.
  2019-08-28 15:32 ` [PATCH v2 02/10] Finish move of clock_* functions to libc Zack Weinberg
  2019-08-30 17:40   ` Adhemerval Zanella
@ 2019-09-03  7:29   ` Florian Weimer
  2019-09-03 13:25     ` Adhemerval Zanella
  1 sibling, 1 reply; 44+ messages in thread
From: Florian Weimer @ 2019-09-03  7:29 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: libc-alpha, Joseph Myers, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

* Zack Weinberg:

> diff --git a/rt/Versions b/rt/Versions
> index 91e3fd2a20..84d1345420 100644
> --- a/rt/Versions
> +++ b/rt/Versions
> @@ -1,15 +1,3 @@
> -libc {
> -  GLIBC_2.17 {
> -    # c*
> -    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
> -    clock_nanosleep;
> -  }
> -  GLIBC_PRIVATE {
> -    __clock_getres; __clock_gettime; __clock_settime; __clock_getcpuclockid;
> -    __clock_nanosleep;
> -  }
> -}

Sorry, you cannot remove the GLIBC_2.17 symbol version in this way,
otherwise old binaries will fail to load.  You need to leave behind a
dummy function definition.  See __libpthread_version_placeholder for how
I handled this in the libpthread/vfork case.

I think we need to bring back the file version information in the ABI
lists because it is part of the ABI, after all.

We have received a bug report that the librt IFUNC resolvers actually
cause programs not to start:

  <https://sourceware.org/bugzilla/show_bug.cgi?id=24959>

I would appreciate if you could mention this bug number in your fix.

Thanks,
Florian

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

* Re: [PATCH v2 02/10] Finish move of clock_* functions to libc.
  2019-09-03  7:29   ` Florian Weimer
@ 2019-09-03 13:25     ` Adhemerval Zanella
  2019-09-03 13:31       ` Florian Weimer
  0 siblings, 1 reply; 44+ messages in thread
From: Adhemerval Zanella @ 2019-09-03 13:25 UTC (permalink / raw)
  To: Florian Weimer, Zack Weinberg
  Cc: libc-alpha, Joseph Myers, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Samuel Thibault



On 03/09/2019 04:29, Florian Weimer wrote:
> * Zack Weinberg:
> 
>> diff --git a/rt/Versions b/rt/Versions
>> index 91e3fd2a20..84d1345420 100644
>> --- a/rt/Versions
>> +++ b/rt/Versions
>> @@ -1,15 +1,3 @@
>> -libc {
>> -  GLIBC_2.17 {
>> -    # c*
>> -    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
>> -    clock_nanosleep;
>> -  }
>> -  GLIBC_PRIVATE {
>> -    __clock_getres; __clock_gettime; __clock_settime; __clock_getcpuclockid;
>> -    __clock_nanosleep;
>> -  }
>> -}
> 
> Sorry, you cannot remove the GLIBC_2.17 symbol version in this way,
> otherwise old binaries will fail to load.  You need to leave behind a
> dummy function definition.  See __libpthread_version_placeholder for how
> I handled this in the libpthread/vfork case.

Are you sure about it? on x86_64 I am trying to force this issue:

--
$ cat test.c
include <time.h>

#define symbol_version_reference(real, name, version) \
  __asm__ (".symver " #real "," #name "@" #version)

symbol_version_reference (clock_gettime, clock_gettime, GLIBC_2.2.5);

int main ()
{
  struct timespec ts;
  clock_gettime (CLOCK_REALTIME, &ts);
  return ts.tv_sec;
}
$ gcc -Wall test.c -o test -lrt
# Check if this indeed links against old librt version
$ readelf -s test | grep clock_gettime
     5: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND clock_gettime@GLIBC_2.2.5 (4)
    56: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND clock_gettime@@GLIBC_2.2.

# Check if master branch does not fail to load the binary
$ ./x86_64-linux-gnu-master/testrun.sh ./test
# Chec

# librt.so does not have the clock_gettime symbols
$ readelf -s x86_64-linux-gnu-patched/rt/librt.so | grep clock_gettime@
    37: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __clock_gettime@GLIBC_PRIVATE (7)
   232: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __clock_gettime@@GLIBC_PR
# There are now provided solely by libc.so
$ readelf -s x86_64-linux-gnu-patched/libc.so | grep clock_gettime@
   837: 00000000000c0be0   109 FUNC    GLOBAL DEFAULT   12 __clock_gettime@@GLIBC_PRIVATE
  1744: 00000000000c0be0   109 FUNC    GLOBAL DEFAULT   12 clock_gettime@GLIBC_2.2.5
  1747: 00000000000c0be0   109 FUNC    GLOBAL DEFAULT   12 clock_gettime@@GLIBC_2.17
  7580: 00000000000c0be0   109 FUNC    GLOBAL DEFAULT   12 clock_gettime@GLIBC_2.2.5
  8291: 00000000000c0be0   109 FUNC    GLOBAL DEFAULT   12 clock_gettime@@GLIBC_2.17
# And it does not fail
$ ./x86_64-linux-gnu-patched/testrun.sh ./test
--

LD_DEBUG=all indeed shows us the symbol resolution is done as expected:

      9832:     symbol=clock_gettime;  lookup in file=./test [0]
      9832:     symbol=clock_gettime;  lookup in file=./x86_64-linux-gnu-patched/rt/librt.so.1 [0]
      9832:     symbol=clock_gettime;  lookup in file=./x86_64-linux-gnu-patched/libc.so.6 [0]
      9832:     binding file ./test [0] to ./x86_64-linux-gnu-patched/libc.so.6 [0]: normal symbol `clock_gettime' [GLIBC_2.2.5]
      9832:     

Do you know how exactly this issue might happen?

> 
> I think we need to bring back the file version information in the ABI
> lists because it is part of the ABI, after all.
> 
> We have received a bug report that the librt IFUNC resolvers actually
> cause programs not to start:
> 
>   <https://sourceware.org/bugzilla/show_bug.cgi?id=24959>
> 
> I would appreciate if you could mention this bug number in your fix.

Yeah, we need to remove these ifunc redirection hacks.

> 
> Thanks,
> Florian
> 

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

* Re: [PATCH v2 02/10] Finish move of clock_* functions to libc.
  2019-09-03 13:25     ` Adhemerval Zanella
@ 2019-09-03 13:31       ` Florian Weimer
  2019-09-03 13:44         ` Adhemerval Zanella
  0 siblings, 1 reply; 44+ messages in thread
From: Florian Weimer @ 2019-09-03 13:31 UTC (permalink / raw)
  To: Adhemerval Zanella
  Cc: Zack Weinberg, libc-alpha, Joseph Myers, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Samuel Thibault

* Adhemerval Zanella:

> On 03/09/2019 04:29, Florian Weimer wrote:
>> * Zack Weinberg:
>> 
>>> diff --git a/rt/Versions b/rt/Versions
>>> index 91e3fd2a20..84d1345420 100644
>>> --- a/rt/Versions
>>> +++ b/rt/Versions
>>> @@ -1,15 +1,3 @@
>>> -libc {
>>> -  GLIBC_2.17 {
>>> -    # c*
>>> -    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
>>> -    clock_nanosleep;
>>> -  }
>>> -  GLIBC_PRIVATE {
>>> -    __clock_getres; __clock_gettime; __clock_settime; __clock_getcpuclockid;
>>> -    __clock_nanosleep;
>>> -  }
>>> -}
>> 
>> Sorry, you cannot remove the GLIBC_2.17 symbol version in this way,
>> otherwise old binaries will fail to load.  You need to leave behind a
>> dummy function definition.  See __libpthread_version_placeholder for how
>> I handled this in the libpthread/vfork case.
>
> Are you sure about it?

Yes. 8-)  But I missed that this block was just moved to time/Versions.
Either place will work and generate the same symbol versions.

For librt proper, the problem does not arise because sem_open is still
present at the same symbol version, keeping the version present and
alive.

Zack, please disregard my comment about rt/Versions.

Thanks,
Florian

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

* Re: [PATCH v2 02/10] Finish move of clock_* functions to libc.
  2019-09-03 13:31       ` Florian Weimer
@ 2019-09-03 13:44         ` Adhemerval Zanella
  2019-09-03 14:34           ` Zack Weinberg
  0 siblings, 1 reply; 44+ messages in thread
From: Adhemerval Zanella @ 2019-09-03 13:44 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Zack Weinberg, libc-alpha, Joseph Myers, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Samuel Thibault



On 03/09/2019 10:31, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> On 03/09/2019 04:29, Florian Weimer wrote:
>>> * Zack Weinberg:
>>>
>>>> diff --git a/rt/Versions b/rt/Versions
>>>> index 91e3fd2a20..84d1345420 100644
>>>> --- a/rt/Versions
>>>> +++ b/rt/Versions
>>>> @@ -1,15 +1,3 @@
>>>> -libc {
>>>> -  GLIBC_2.17 {
>>>> -    # c*
>>>> -    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
>>>> -    clock_nanosleep;
>>>> -  }
>>>> -  GLIBC_PRIVATE {
>>>> -    __clock_getres; __clock_gettime; __clock_settime; __clock_getcpuclockid;
>>>> -    __clock_nanosleep;
>>>> -  }
>>>> -}
>>>
>>> Sorry, you cannot remove the GLIBC_2.17 symbol version in this way,
>>> otherwise old binaries will fail to load.  You need to leave behind a
>>> dummy function definition.  See __libpthread_version_placeholder for how
>>> I handled this in the libpthread/vfork case.
>>
>> Are you sure about it?
> 
> Yes. 8-)  But I missed that this block was just moved to time/Versions.
> Either place will work and generate the same symbol versions.

Right, because that was my understanding (the symbol versions will still
be generated correctly on libc).

> 
> For librt proper, the problem does not arise because sem_open is still
> present at the same symbol version, keeping the version present and
> alive.
> 
> Zack, please disregard my comment about rt/Versions.
> 
> Thanks,
> Florian
> 

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

* Re: [PATCH v2 02/10] Finish move of clock_* functions to libc.
  2019-09-03 13:44         ` Adhemerval Zanella
@ 2019-09-03 14:34           ` Zack Weinberg
  2019-09-03 18:50             ` Adhemerval Zanella
  0 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-09-03 14:34 UTC (permalink / raw)
  To: Adhemerval Zanella
  Cc: Florian Weimer, GNU C Library, Joseph Myers, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Samuel Thibault

On Tue, Sep 3, 2019 at 9:44 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
> On 03/09/2019 10:31, Florian Weimer wrote:
> > * Adhemerval Zanella:
> >> On 03/09/2019 04:29, Florian Weimer wrote:
> >>> * Zack Weinberg:
> >>>> diff --git a/rt/Versions b/rt/Versions
> >>>> index 91e3fd2a20..84d1345420 100644
> >>>> --- a/rt/Versions
> >>>> +++ b/rt/Versions
> >>>> @@ -1,15 +1,3 @@
> >>>> -libc {
> >>>> -  GLIBC_2.17 {
> >>>> -    # c*
> >>>> -    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
> >>>> -    clock_nanosleep;
> >>>> -  }
> >>>> -  GLIBC_PRIVATE {
> >>>> -    __clock_getres; __clock_gettime; __clock_settime; __clock_getcpuclockid;
> >>>> -    __clock_nanosleep;
> >>>> -  }
> >>>> -}
> >>>
> >>> Sorry, you cannot remove the GLIBC_2.17 symbol version in this way,
> >>> otherwise old binaries will fail to load.  You need to leave behind a
> >>> dummy function definition.  See __libpthread_version_placeholder for how
> >>> I handled this in the libpthread/vfork case.
> >>
> >> Are you sure about it?
> >
> > Yes. 8-)  But I missed that this block was just moved to time/Versions.
> > Either place will work and generate the same symbol versions.
>
> Right, because that was my understanding (the symbol versions will still
> be generated correctly on libc).

Yes, I moved the GLIBC_2.17 versions from rt/Versions to time/Versions
to keep them together with their .c files.

Adhemerval, Florian, I suspect I won't have very much time to work on
glibc for the next two weeks.  If either or both of you would like to
take over the branch for these patches (zack/y2038-preliminaries) and
keep working on it, please feel free.

Incidentally, regarding the cost of converting from a struct timespec
to a struct timeval on systems where 'long' is 64 bits, I'm getting
what looks like decent code generation out of this definition of
TIMESPEC_TO_TIMEVAL:

#define TIMESPEC_TO_TIMEVAL(tv, ts) do {        \
    uint32_t __nsec = (ts)->tv_nsec;            \
    (tv)->tv_sec = (ts)->tv_sec;                \
    (tv)->tv_usec = __nsec / 1000;              \
} while (0)

e.g.

    movq    8(%rsi), %rax
    movq    (%rsi), %rdx
    movl    %eax, %eax
    movq    %rdx, (%rdi)
    imulq    $274877907, %rax, %rax
    shrq    $38, %rax
    movl    %eax, %eax
    movq    %rax, 8(%rdi)
    ret

(Not sure why the 'movl %eax, %eax', though - clearing the upper 32
bits maybe?  I might throw this at a superoptimizer and see what it
comes up with.)

zw

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

* Re: [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions.
  2019-08-28 17:15 ` [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Joseph Myers
@ 2019-09-03 14:43   ` Zack Weinberg
  2019-09-10 17:32     ` Adhemerval Zanella
  0 siblings, 1 reply; 44+ messages in thread
From: Zack Weinberg @ 2019-09-03 14:43 UTC (permalink / raw)
  To: Joseph Myers
  Cc: GNU C Library, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Adhemerval Zanella,
	Samuel Thibault

On Wed, Aug 28, 2019 at 1:15 PM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Wed, 28 Aug 2019, Zack Weinberg wrote:
>
> >  - The obsolete functions ftime and stime are no longer available to
> >    new binaries.  The header <sys/timeb.h> is no longer installed.
>
> It might be advisable to see if this affects the build of libsanitizer,
> and alert sanitizer maintainers if so.  (There appear to be sanitizer
> interceptors for ftime and stime, and an include of <sys/timeb.h>.)

I may not have time to do anything about this for at least a couple
weeks, but I can confirm that the absence of sys/timeb.h does break
the build of libsanitizer.  Adhemerval's suggestion of keeping ftime
and <sys/timeb.h> around for at least another release, but issuing
warnings if ftime is actually used (attribute((deprecated)) maybe?)
seems reasonable to me.

zw

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

* Re: [PATCH v2 04/10] Use clock_settime to implement settimeofday.
  2019-09-02 13:22   ` Adhemerval Zanella
@ 2019-09-03 14:44     ` Zack Weinberg
  0 siblings, 0 replies; 44+ messages in thread
From: Zack Weinberg @ 2019-09-03 14:44 UTC (permalink / raw)
  To: Adhemerval Zanella
  Cc: GNU C Library, Joseph Myers, Florian Weimer, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Samuel Thibault

On Mon, Sep 2, 2019 at 9:22 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
> > 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.
>
> We definitely need a NEWS entry for this change.

NEWS entries for the complete patchset are in the final patch of the
series (with the manual changes).

zw

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

* Re: [PATCH v2 02/10] Finish move of clock_* functions to libc.
  2019-09-03 14:34           ` Zack Weinberg
@ 2019-09-03 18:50             ` Adhemerval Zanella
  0 siblings, 0 replies; 44+ messages in thread
From: Adhemerval Zanella @ 2019-09-03 18:50 UTC (permalink / raw)
  To: Zack Weinberg
  Cc: Florian Weimer, GNU C Library, Joseph Myers, Lukasz Majewski,
	Alistair Francis, Stepan Golosunov, Arnd Bergmann,
	Samuel Thibault



On 03/09/2019 11:34, Zack Weinberg wrote:
> On Tue, Sep 3, 2019 at 9:44 AM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>> On 03/09/2019 10:31, Florian Weimer wrote:
>>> * Adhemerval Zanella:
>>>> On 03/09/2019 04:29, Florian Weimer wrote:
>>>>> * Zack Weinberg:
>>>>>> diff --git a/rt/Versions b/rt/Versions
>>>>>> index 91e3fd2a20..84d1345420 100644
>>>>>> --- a/rt/Versions
>>>>>> +++ b/rt/Versions
>>>>>> @@ -1,15 +1,3 @@
>>>>>> -libc {
>>>>>> -  GLIBC_2.17 {
>>>>>> -    # c*
>>>>>> -    clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
>>>>>> -    clock_nanosleep;
>>>>>> -  }
>>>>>> -  GLIBC_PRIVATE {
>>>>>> -    __clock_getres; __clock_gettime; __clock_settime; __clock_getcpuclockid;
>>>>>> -    __clock_nanosleep;
>>>>>> -  }
>>>>>> -}
>>>>>
>>>>> Sorry, you cannot remove the GLIBC_2.17 symbol version in this way,
>>>>> otherwise old binaries will fail to load.  You need to leave behind a
>>>>> dummy function definition.  See __libpthread_version_placeholder for how
>>>>> I handled this in the libpthread/vfork case.
>>>>
>>>> Are you sure about it?
>>>
>>> Yes. 8-)  But I missed that this block was just moved to time/Versions.
>>> Either place will work and generate the same symbol versions.
>>
>> Right, because that was my understanding (the symbol versions will still
>> be generated correctly on libc).
> 
> Yes, I moved the GLIBC_2.17 versions from rt/Versions to time/Versions
> to keep them together with their .c files.
> 
> Adhemerval, Florian, I suspect I won't have very much time to work on
> glibc for the next two weeks.  If either or both of you would like to
> take over the branch for these patches (zack/y2038-preliminaries) and
> keep working on it, please feel free.

I will try to spare some time to create a personal branch based on yours
with my reviewed remarks fixed.

> 
> Incidentally, regarding the cost of converting from a struct timespec
> to a struct timeval on systems where 'long' is 64 bits, I'm getting
> what looks like decent code generation out of this definition of
> TIMESPEC_TO_TIMEVAL:
> 
> #define TIMESPEC_TO_TIMEVAL(tv, ts) do {        \
>     uint32_t __nsec = (ts)->tv_nsec;            \
>     (tv)->tv_sec = (ts)->tv_sec;                \
>     (tv)->tv_usec = __nsec / 1000;              \
> } while (0)
> 
> e.g.
> 
>     movq    8(%rsi), %rax
>     movq    (%rsi), %rdx
>     movl    %eax, %eax
>     movq    %rdx, (%rdi)
>     imulq    $274877907, %rax, %rax
>     shrq    $38, %rax
>     movl    %eax, %eax
>     movq    %rax, 8(%rdi)
>     ret
> 
> (Not sure why the 'movl %eax, %eax', though - clearing the upper 32
> bits maybe?  I might throw this at a superoptimizer and see what it
> comes up with.)
> 
> zw
> 

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

* Re: [PATCH v2 09/10] Warn when gettimeofday is called with non-null tzp argument.
  2019-08-28 15:32 ` [PATCH v2 09/10] Warn when gettimeofday is called with non-null tzp argument Zack Weinberg
@ 2019-09-03 19:56   ` Adhemerval Zanella
  0 siblings, 0 replies; 44+ messages in thread
From: Adhemerval Zanella @ 2019-09-03 19:56 UTC (permalink / raw)
  To: Zack Weinberg, libc-alpha
  Cc: Joseph Myers, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Samuel Thibault



On 28/08/2019 12:32, Zack Weinberg wrote:
> Since there are no known uses of gettimeofday's vestigial "get time
> zone" feature that are not bugs, add a fortify-style wrapper inline to
> sys/time.h that issues a warning whenever gettimeofday is called with
> a second argument that is not a compile-time null pointer
> constant.
> 
> At present this is only possible with GCC; clang does not implement
> attribute((warning)).  The wrapper is only activated when __OPTIMIZE__
> is defined because it throws false positives when optimization is off,
> even though it's an always-inline function.
> 
> An oversight in the implementation of __builtin_constant_p causes it
> to fail to detect compile-time *pointer* constants unless they are
> cast to an integer of a different size.  (Loss of data in this cast is
> harmless; the overall expression is still constant if and only if the
> original pointer was.)  This is GCC bug 95514.  Thanks to
> Kamil Cukrowski <kamilcukrowski@gmail.com> for the workaround.
> As a precaution, I added a static assertion to debug/warning-nop.c to
> make sure that the cast _is_ casting to an integer of a different
> size; this is too unlikely a scenario to be worth checking in the
> public header, but if someone ever adds a port where short is the
> same size as intptr_t, we'll still catch it.

The conditionals of making this work without false-positive seems quite 
specific and fragile (gcc-only, optimized build) and the cast hack make
even more suspicious it won't break in some arcane build environment 
(since it is an exported header, not internally used).

I would prefer to just wait gcc to correctly fix it and set its minimum 
version to enable it with the expected semantic.

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

This is ok though.

> 
> 	* time/sys/time.h (__timezone_ptr_t): Delete.
> 	(gettimeofday): Always declare second argument with type "void *".
> 	When possible, wrap with a fortify-style inline function that
> 	detects non-null or non-constant second argument and issues a
> 	warning.  Improve commentary.
> 	(settimeofday): Improve commentary.
> 
> 	* time/gettimeofday.c (gettimeofday): Declare second argument with
> 	type "void *".
> 	* debug/warning-nop.c: Include sys/time.h and stdint.h.
> 	Add static_assert to verify the requirements of the workaround
> 	for GCC bug 95514.
> ---
>  debug/warning-nop.c |  9 +++++++++
>  time/gettimeofday.c |  4 ++--
>  time/sys/time.h     | 47 ++++++++++++++++++++++++++++++++++-----------
>  3 files changed, 47 insertions(+), 13 deletions(-)
> 
> diff --git a/debug/warning-nop.c b/debug/warning-nop.c
> index 8eeea396c3..3eab53b78f 100644
> --- a/debug/warning-nop.c
> +++ b/debug/warning-nop.c
> @@ -67,4 +67,13 @@ nop (void)
>  #define __builtin___strncpy_chk(dest, src, len, bos) NULL
>  #define __builtin_object_size(bos, level) 0
>  
> +/* The code in sys/time.h that uses __warndecl has to work around GCC
> +    bug 91554.  The work-around is only effective if intptr_t is not
> +    the same size as short.  */
> +#include <stdint.h>
> +_Static_assert (sizeof (intptr_t) != sizeof (short),
> +                "workaround for GCC bug 91554 in sys/time.h"
> +                " is only effective when short is smaller than a pointer");
> +
>  #include <string.h>
> +#include <sys/time.h>
> diff --git a/time/gettimeofday.c b/time/gettimeofday.c
> index c4f642631f..5bc91fc214 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 5dbc7fc627..a4e7fd20d1 100644
> --- a/time/sys/time.h
> +++ b/time/sys/time.h
> @@ -54,23 +54,48 @@ 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));
> +
> +#if __GNUC_PREREQ (4,3) && defined __REDIRECT && defined __OPTIMIZE__
> +/* Issue a warning for use of gettimeofday with a non-null __tz argument.  */
> +__warndecl (__warn_gettimeofday_nonnull_timezone,
> +            "gettimeofday with non-null or non-constant timezone parameter;"
> +            " this is obsolete and inaccurate, use localtime instead");
> +
> +extern int __REDIRECT_NTH (__gettimeofday_alias,
> +                           (struct timeval *__restrict __tv,
> +                            void *__restrict __tz), gettimeofday)
> +  __nonnull ((1));
> +
> +/* The double cast below works around a limitation in __builtin_constant_p
> +   in all released versions of GCC (as of August 2019).
> +   See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91554>.  */
> +__fortify_function int
> +__NTH (gettimeofday (struct timeval *__restrict __tv, void *__restrict __tz))
> +{
> +  if (! (__builtin_constant_p ((short) (__intptr_t) __tz) && __tz == 0))
> +    __warn_gettimeofday_nonnull_timezone ();
> +
> +  return __gettimeofday_alias (__tv, __tz);
> +}
> +#endif
>  
>  #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;
> 

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

* Re: [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions.
  2019-09-03 14:43   ` Zack Weinberg
@ 2019-09-10 17:32     ` Adhemerval Zanella
  0 siblings, 0 replies; 44+ messages in thread
From: Adhemerval Zanella @ 2019-09-10 17:32 UTC (permalink / raw)
  To: Zack Weinberg, Joseph Myers
  Cc: GNU C Library, Florian Weimer, Lukasz Majewski, Alistair Francis,
	Stepan Golosunov, Arnd Bergmann, Samuel Thibault



On 03/09/2019 11:43, Zack Weinberg wrote:
> On Wed, Aug 28, 2019 at 1:15 PM Joseph Myers <joseph@codesourcery.com> wrote:
>>
>> On Wed, 28 Aug 2019, Zack Weinberg wrote:
>>
>>>  - The obsolete functions ftime and stime are no longer available to
>>>    new binaries.  The header <sys/timeb.h> is no longer installed.
>>
>> It might be advisable to see if this affects the build of libsanitizer,
>> and alert sanitizer maintainers if so.  (There appear to be sanitizer
>> interceptors for ftime and stime, and an include of <sys/timeb.h>.)
> 
> I may not have time to do anything about this for at least a couple
> weeks, but I can confirm that the absence of sys/timeb.h does break
> the build of libsanitizer.  Adhemerval's suggestion of keeping ftime
> and <sys/timeb.h> around for at least another release, but issuing
> warnings if ftime is actually used (attribute((deprecated)) maybe?)
> seems reasonable to me.
> 
> zw
> 

Hi Zack,

I just pushed a personal branch [1] based on your y2038-preliminaries
with the changes I have proposed in the review:

  * Change most internal uses of __gettimeofday to __clock_gettime.
    - Some tab/whitespace issues.
    - Hurd time_value_t to timespec strict issues.

  * Use clock_settime to implement settimeofday.
    - Simplify sysdeps/unix/sysv/linux/settimezone.c

  * Use clock_gettime to implement time.
    - Do not remove arch-specific time implementations.
    - Adjust powerpc time to use the new generic implementation.

  * Use clock_gettime to implement ftime; withdraw ftime.
    - Keep the sys/timeb.h header and deprecate ftime.

  * Use clock_gettime to implement gettimeofday.
    - Do not remove arch-specific gettimeofday implementations.

  * Warn when gettimeofday is called with non-null tzp argument.
    - Remove the __warndecl hack.
    - Change to "Make second argument of gettimeofday as 'void *'"
      and adjust the required implementations.

I don't like to clash with you proposal, since some changes remove
some suggestion from your first patchset.
  
[1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/y2038-preliminaries

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

end of thread, other threads:[~2019-09-10 17:32 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-28 15:32 [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Zack Weinberg
2019-08-28 15:32 ` [PATCH v2 01/10] Change most internal uses of __gettimeofday to __clock_gettime Zack Weinberg
2019-08-29 20:30   ` Adhemerval Zanella
2019-08-29 20:42     ` Samuel Thibault
2019-08-28 15:32 ` [PATCH v2 02/10] Finish move of clock_* functions to libc Zack Weinberg
2019-08-30 17:40   ` Adhemerval Zanella
2019-09-03  7:29   ` Florian Weimer
2019-09-03 13:25     ` Adhemerval Zanella
2019-09-03 13:31       ` Florian Weimer
2019-09-03 13:44         ` Adhemerval Zanella
2019-09-03 14:34           ` Zack Weinberg
2019-09-03 18:50             ` Adhemerval Zanella
2019-08-28 15:32 ` [PATCH v2 03/10] Use clock_settime to implement stime; withdraw stime Zack Weinberg
2019-08-30 17:54   ` Adhemerval Zanella
2019-08-28 15:32 ` [PATCH v2 04/10] Use clock_settime to implement settimeofday Zack Weinberg
2019-09-02 13:22   ` Adhemerval Zanella
2019-09-03 14:44     ` Zack Weinberg
2019-08-28 15:32 ` [PATCH v2 05/10] Use clock_gettime to implement time Zack Weinberg
2019-08-28 18:16   ` Florian Weimer
2019-08-28 18:36     ` Zack Weinberg
2019-08-28 18:49       ` Florian Weimer
2019-08-28 20:01     ` Paul Eggert
2019-08-28 20:21       ` Florian Weimer
2019-08-28 21:12         ` Paul Eggert
2019-08-28 21:39           ` Florian Weimer
2019-08-29 17:49             ` Zack Weinberg
2019-09-02 13:32               ` Florian Weimer
2019-09-02 18:35                 ` Adhemerval Zanella
2019-08-28 15:32 ` [PATCH v2 06/10] Use clock_gettime to implement ftime; withdraw ftime Zack Weinberg
2019-09-02 18:42   ` Adhemerval Zanella
2019-08-28 15:32 ` [PATCH v2 07/10] Use clock_gettime to implement timespec_get Zack Weinberg
2019-09-02 19:25   ` Adhemerval Zanella
2019-08-28 15:32 ` [PATCH v2 08/10] Use clock_gettime to implement gettimeofday Zack Weinberg
2019-08-28 18:27   ` Florian Weimer
2019-09-02 19:31     ` Adhemerval Zanella
2019-08-28 15:32 ` [PATCH v2 09/10] Warn when gettimeofday is called with non-null tzp argument Zack Weinberg
2019-09-03 19:56   ` Adhemerval Zanella
2019-08-28 15:32 ` [PATCH v2 10/10] Revise the documentation of simple calendar time Zack Weinberg
2019-08-29  1:09   ` Paul Eggert
2019-08-29 17:41     ` Zack Weinberg
2019-08-30 19:17       ` Paul Eggert
2019-08-28 17:15 ` [PATCH v2 00/10] Y2038 preparation: use clock_[gs]ettime to implement the other time-getting and -setting functions Joseph Myers
2019-09-03 14:43   ` Zack Weinberg
2019-09-10 17:32     ` Adhemerval Zanella

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).