about summary refs log tree commit diff
path: root/rt
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2019-09-04 08:18:57 +0200
committerFlorian Weimer <fweimer@redhat.com>2019-09-04 14:39:38 +0200
commit7b5af2d8f2a2b858319a792678b15a0db08764c7 (patch)
tree014a27968a65aaadedc097d9fe9bd1fb62c45896 /rt
parentb5367a08ae810e3c648fb036f2e5766204f9d83f (diff)
downloadglibc-7b5af2d8f2a2b858319a792678b15a0db08764c7.tar.gz
glibc-7b5af2d8f2a2b858319a792678b15a0db08764c7.tar.xz
glibc-7b5af2d8f2a2b858319a792678b15a0db08764c7.zip
Finish move of clock_* functions to libc. [BZ #24959]
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/.
Diffstat (limited to 'rt')
-rw-r--r--rt/Makefile15
-rw-r--r--rt/Versions16
-rw-r--r--rt/clock-compat.c63
-rw-r--r--rt/clock_getcpuclockid.c40
-rw-r--r--rt/clock_getres.c30
-rw-r--r--rt/clock_gettime.c31
-rw-r--r--rt/clock_nanosleep.c37
-rw-r--r--rt/clock_settime.c30
-rw-r--r--rt/tst-clock.c121
-rw-r--r--rt/tst-clock2.c43
-rw-r--r--rt/tst-clock_nanosleep.c57
-rw-r--r--rt/tst-cpuclock1.c320
12 files changed, 4 insertions, 799 deletions
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/rt/clock_getcpuclockid.c b/rt/clock_getcpuclockid.c
deleted file mode 100644
index 22b9f1383c..0000000000
--- a/rt/clock_getcpuclockid.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Get a clockid_t for the process CPU clock of a given process.  Generic.
-   Copyright (C) 2000-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 <unistd.h>
-
-int
-__clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
-{
-  /* We don't allow any process ID but our own.  */
-  if (pid != 0 && pid != getpid ())
-    return EPERM;
-
-#ifdef CLOCK_PROCESS_CPUTIME_ID
-  /* Store the number.  */
-  *clock_id = CLOCK_PROCESS_CPUTIME_ID;
-
-  return 0;
-#else
-  /* We don't have a timer for that.  */
-  return ENOENT;
-#endif
-}
-weak_alias (__clock_getcpuclockid, clock_getcpuclockid)
diff --git a/rt/clock_getres.c b/rt/clock_getres.c
deleted file mode 100644
index b990bf0af0..0000000000
--- a/rt/clock_getres.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Get the resolution of a clock.  Stub version.
-   Copyright (C) 1999-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>
-
-/* Get resolution of clock.  */
-int
-__clock_getres (clockid_t clock_id, struct timespec *res)
-{
-  __set_errno (ENOSYS);
-  return -1;
-}
-weak_alias (__clock_getres, clock_getres)
-stub_warning (clock_getres)
diff --git a/rt/clock_gettime.c b/rt/clock_gettime.c
deleted file mode 100644
index 0426dd2c76..0000000000
--- a/rt/clock_gettime.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Get the current value of a clock.  Stub version.
-   Copyright (C) 1999-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>
-
-/* Get current value of CLOCK and store it in TP.  */
-int
-__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)
-stub_warning (clock_gettime)
diff --git a/rt/clock_nanosleep.c b/rt/clock_nanosleep.c
deleted file mode 100644
index 5b724e593b..0000000000
--- a/rt/clock_nanosleep.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* High-resolution sleep with the specified clock.  Stub version.
-   Copyright (C) 2000-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>
-
-int
-__clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
-		   struct timespec *rem)
-{
-  if (__builtin_expect (req->tv_nsec, 0) < 0
-      || __builtin_expect (req->tv_nsec, 0) >= 1000000000)
-    return EINVAL;
-
-  if (flags != TIMER_ABSTIME && flags != 0)
-    return EINVAL;
-
-  /* Not implemented.  */
-  return ENOSYS;
-}
-weak_alias (__clock_nanosleep, clock_nanosleep)
-stub_warning (clock_nanosleep)
diff --git a/rt/clock_settime.c b/rt/clock_settime.c
deleted file mode 100644
index 891925ab2c..0000000000
--- a/rt/clock_settime.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Set a clock to a given value.  Stub version.
-   Copyright (C) 1999-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>
-
-/* Set CLOCK to value TP.  */
-int
-__clock_settime (clockid_t clock_id, const struct timespec *tp)
-{
-  __set_errno (ENOSYS);
-  return -1;
-}
-weak_alias (__clock_settime, clock_settime)
-stub_warning (clock_settime)
diff --git a/rt/tst-clock.c b/rt/tst-clock.c
deleted file mode 100644
index 2e19bb1a43..0000000000
--- a/rt/tst-clock.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Test program for POSIX clock_* functions.
-   Copyright (C) 2000-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.
-
-   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 <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <stdint.h>
-
-
-/* We want to see output immediately.  */
-#define STDOUT_UNBUFFERED
-
-static int
-clock_test (clockid_t cl)
-{
-  struct timespec old_ts;
-  struct timespec ts;
-  struct timespec waitit;
-  int result = 0;
-  int i;
-
-  memset (&ts, '\0', sizeof ts);
-
-  waitit.tv_sec = 0;
-  waitit.tv_nsec = 500000000;
-
-  /* Get and print resolution of the clock.  */
-  if (clock_getres (cl, &ts) == 0)
-    {
-      if (ts.tv_nsec < 0 || ts.tv_nsec >= 1000000000)
-	{
-	  printf ("clock %d: nanosecond value of resolution wrong\n", cl);
-	  result = 1;
-	}
-      else
-	printf ("clock %d: resolution = %jd.%09jd secs\n",
-		cl, (intmax_t) ts.tv_sec, (intmax_t) ts.tv_nsec);
-    }
-  else
-    {
-      printf ("clock %d: cannot get resolution\n", cl);
-      result = 1;
-    }
-
-  memset (&ts, '\0', sizeof ts);
-  memset (&old_ts, '\0', sizeof old_ts);
-
-  /* Next get the current time value a few times.  */
-  for (i = 0; i < 10; ++i)
-    {
-      if (clock_gettime (cl, &ts) == 0)
-	{
-	  if (ts.tv_nsec < 0 || ts.tv_nsec >= 1000000000)
-	    {
-	      printf ("clock %d: nanosecond value of time wrong (try %d)\n",
-		      cl, i);
-	      result = 1;
-	    }
-	  else
-	    {
-	      printf ("clock %d: time = %jd.%09jd secs\n",
-		      cl, (intmax_t) ts.tv_sec, (intmax_t) ts.tv_nsec);
-
-	      if (memcmp (&ts, &old_ts, sizeof ts) == 0)
-		{
-		  printf ("clock %d: time hasn't changed (try %d)\n", cl, i);
-		  result = 1;
-
-		  old_ts = ts;
-		}
-	    }
-	}
-      else
-	{
-	  printf ("clock %d: cannot get time (try %d)\n", cl, i);
-	  result = 1;
-	}
-
-      /* Wait a bit before the next iteration.  */
-      nanosleep (&waitit, NULL);
-    }
-
-  return result;
-}
-
-static int
-do_test (void)
-{
-  clockid_t cl;
-  int result;
-
-  result = clock_test (CLOCK_REALTIME);
-
-  if (clock_getcpuclockid (0, &cl) == 0)
-    /* XXX It's not yet a bug when this fails.  */
-    clock_test (cl);
-  else
-	  printf("CPU clock unavailble, skipping test\n");
-
-  return result;
-}
-#define TEST_FUNCTION do_test ()
-
-
-#include "../test-skeleton.c"
diff --git a/rt/tst-clock2.c b/rt/tst-clock2.c
deleted file mode 100644
index 4c8fb9f247..0000000000
--- a/rt/tst-clock2.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Test setting the monotonic clock.  */
-
-#include <time.h>
-#include <unistd.h>
-
-#if defined CLOCK_MONOTONIC && defined _POSIX_MONOTONIC_CLOCK
-
-# include <errno.h>
-# include <stdio.h>
-
-static int
-do_test (void)
-{
-  if (sysconf (_SC_MONOTONIC_CLOCK) <= 0)
-    return 0;
-
-  struct timespec ts;
-  if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0)
-    {
-      puts ("clock_gettime(CLOCK_MONOTONIC) failed");
-      return 1;
-    }
-
-  /* Setting the monotonic clock must fail.  */
-  if (clock_settime (CLOCK_MONOTONIC, &ts) != -1)
-    {
-      puts ("clock_settime(CLOCK_MONOTONIC) did not fail");
-      return 1;
-    }
-  if (errno != EINVAL)
-    {
-      printf ("clock_settime(CLOCK_MONOTONIC) set errno to %d, expected %d\n",
-	      errno, EINVAL);
-      return 1;
-    }
-  return 0;
-}
-# define TEST_FUNCTION do_test ()
-
-#else
-# define TEST_FUNCTION	0
-#endif
-#include "../test-skeleton.c"
diff --git a/rt/tst-clock_nanosleep.c b/rt/tst-clock_nanosleep.c
deleted file mode 100644
index f5df327e2f..0000000000
--- a/rt/tst-clock_nanosleep.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright (C) 2003-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 <stdio.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <time.h>
-
-
-/* Test that clock_nanosleep() does sleep.  */
-static int
-do_test (void)
-{
-  /* Current time.  */
-  struct timeval tv1;
-  (void) gettimeofday (&tv1, NULL);
-
-  struct timespec ts;
-  ts.tv_sec = 1;
-  ts.tv_nsec = 0;
-  TEMP_FAILURE_RETRY (clock_nanosleep (CLOCK_REALTIME, 0, &ts, &ts));
-
-  /* At least one second must have passed.  */
-  struct timeval tv2;
-  (void) gettimeofday (&tv2, NULL);
-
-  tv2.tv_sec -= tv1.tv_sec;
-  tv2.tv_usec -= tv1.tv_usec;
-  if (tv2.tv_usec < 0)
-    --tv2.tv_sec;
-
-  if (tv2.tv_sec < 1)
-    {
-      puts ("clock_nanosleep didn't sleep long enough");
-      return 1;
-    }
-
-  return 0;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/rt/tst-cpuclock1.c b/rt/tst-cpuclock1.c
deleted file mode 100644
index e3f23aa307..0000000000
--- a/rt/tst-cpuclock1.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/* Test program for process CPU clocks.
-   Copyright (C) 2004-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 <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdint.h>
-#include <sys/wait.h>
-
-/* This function is intended to rack up both user and system time.  */
-static void
-chew_cpu (void)
-{
-  while (1)
-    {
-      static volatile char buf[4096];
-      for (int i = 0; i < 100; ++i)
-	for (size_t j = 0; j < sizeof buf; ++j)
-	  buf[j] = 0xaa;
-      int nullfd = open ("/dev/null", O_WRONLY);
-      for (int i = 0; i < 100; ++i)
-	for (size_t j = 0; j < sizeof buf; ++j)
-	  buf[j] = 0xbb;
-      write (nullfd, (char *) buf, sizeof buf);
-      close (nullfd);
-      if (getppid () == 1)
-	_exit (2);
-    }
-}
-
-static int
-do_test (void)
-{
-  int result = 0;
-  clockid_t cl;
-  int e;
-  pid_t dead_child, child;
-
-  /* Fork a child and let it die, to give us a PID known not be valid
-     (assuming PIDs don't wrap around during the test).  */
-  {
-    dead_child = fork ();
-    if (dead_child == 0)
-      _exit (0);
-    if (dead_child < 0)
-      {
-	perror ("fork");
-	return 1;
-      }
-    int x;
-    if (wait (&x) != dead_child)
-      {
-	perror ("wait");
-	return 2;
-      }
-  }
-
-  /* POSIX says we should get ESRCH for this.  */
-  e = clock_getcpuclockid (dead_child, &cl);
-  if (e != ENOSYS && e != ESRCH && e != EPERM)
-    {
-      printf ("clock_getcpuclockid on dead PID %d => %s\n",
-	      dead_child, strerror (e));
-      result = 1;
-    }
-
-  /* Now give us a live child eating up CPU time.  */
-  child = fork ();
-  if (child == 0)
-    {
-      chew_cpu ();
-      _exit (1);
-    }
-  if (child < 0)
-    {
-      perror ("fork");
-      return 1;
-    }
-
-  e = clock_getcpuclockid (child, &cl);
-  if (e == EPERM)
-    {
-      puts ("clock_getcpuclockid does not support other processes");
-      goto done;
-    }
-  if (e != 0)
-    {
-      printf ("clock_getcpuclockid on live PID %d => %s\n",
-	      child, strerror (e));
-      result = 1;
-      goto done;
-    }
-
-  const clockid_t child_clock = cl;
-  struct timespec res;
-  if (clock_getres (child_clock, &res) < 0)
-    {
-      printf ("clock_getres on live PID %d clock %lx => %s\n",
-	      child, (unsigned long int) child_clock, strerror (errno));
-      result = 1;
-      goto done;
-    }
-  printf ("live PID %d clock %lx resolution %ju.%.9ju\n",
-	  child, (unsigned long int) child_clock,
-	  (uintmax_t) res.tv_sec, (uintmax_t) res.tv_nsec);
-
-  struct timespec before, after;
-  if (clock_gettime (child_clock, &before) < 0)
-    {
-      printf ("clock_gettime on live PID %d clock %lx => %s\n",
-	      child, (unsigned long int) child_clock, strerror (errno));
-      result = 1;
-      goto done;
-    }
-  /* Should be close to 0.0.  */
-  printf ("live PID %d before sleep => %ju.%.9ju\n",
-	  child, (uintmax_t) before.tv_sec, (uintmax_t) before.tv_nsec);
-
-  struct timespec sleeptime = { .tv_nsec = 500000000 };
-  if (nanosleep (&sleeptime, NULL) != 0)
-    {
-      perror ("nanosleep");
-      result = 1;
-      goto done;
-    }
-
-  if (clock_gettime (child_clock, &after) < 0)
-    {
-      printf ("clock_gettime on live PID %d clock %lx => %s\n",
-	      child, (unsigned long int) child_clock, strerror (errno));
-      result = 1;
-      goto done;
-    }
-  /* Should be close to 0.5.  */
-  printf ("live PID %d after sleep => %ju.%.9ju\n",
-	  child, (uintmax_t) after.tv_sec, (uintmax_t) after.tv_nsec);
-
-  struct timespec diff = { .tv_sec = after.tv_sec - before.tv_sec,
-			   .tv_nsec = after.tv_nsec - before.tv_nsec };
-  if (diff.tv_nsec < 0)
-    {
-      --diff.tv_sec;
-      diff.tv_nsec += 1000000000;
-    }
-  if (diff.tv_sec != 0
-      || diff.tv_nsec > 600000000
-      || diff.tv_nsec < 100000000)
-    {
-      printf ("before - after %ju.%.9ju outside reasonable range\n",
-	      (uintmax_t) diff.tv_sec, (uintmax_t) diff.tv_nsec);
-      result = 1;
-    }
-
-  sleeptime.tv_nsec = 100000000;
-  e = clock_nanosleep (child_clock, 0, &sleeptime, NULL);
-  if (e == EINVAL || e == ENOTSUP || e == ENOSYS)
-    {
-      printf ("clock_nanosleep not supported for other process clock: %s\n",
-	      strerror (e));
-    }
-  else if (e != 0)
-    {
-      printf ("clock_nanosleep on other process clock: %s\n", strerror (e));
-      result = 1;
-    }
-  else
-    {
-      struct timespec afterns;
-      if (clock_gettime (child_clock, &afterns) < 0)
-	{
-	  printf ("clock_gettime on live PID %d clock %lx => %s\n",
-		  child, (unsigned long int) child_clock, strerror (errno));
-	  result = 1;
-	}
-      else
-	{
-	  struct timespec d = { .tv_sec = afterns.tv_sec - after.tv_sec,
-				.tv_nsec = afterns.tv_nsec - after.tv_nsec };
-	  if (d.tv_nsec < 0)
-	    {
-	      --d.tv_sec;
-	      d.tv_nsec += 1000000000;
-	    }
-	  if (d.tv_sec > 0
-	      || d.tv_nsec < sleeptime.tv_nsec
-	      || d.tv_nsec > sleeptime.tv_nsec * 2)
-	    {
-	      printf ("nanosleep time %ju.%.9ju outside reasonable range\n",
-		      (uintmax_t) d.tv_sec, (uintmax_t) d.tv_nsec);
-	      result = 1;
-	    }
-	}
-    }
-
-  if (kill (child, SIGKILL) != 0)
-    {
-      perror ("kill");
-      result = 2;
-      goto done;
-    }
-
-  /* Wait long enough to let the child finish dying.  */
-
-  sleeptime.tv_nsec = 200000000;
-  if (nanosleep (&sleeptime, NULL) != 0)
-    {
-      perror ("nanosleep");
-      result = 1;
-      goto done;
-    }
-
-  struct timespec dead;
-  if (clock_gettime (child_clock, &dead) < 0)
-    {
-      printf ("clock_gettime on dead PID %d clock %lx => %s\n",
-	      child, (unsigned long int) child_clock, strerror (errno));
-      result = 1;
-      goto done;
-    }
-  /* Should be close to 0.6.  */
-  printf ("dead PID %d => %ju.%.9ju\n",
-	  child, (uintmax_t) dead.tv_sec, (uintmax_t) dead.tv_nsec);
-
-  diff.tv_sec = dead.tv_sec - after.tv_sec;
-  diff.tv_nsec = dead.tv_nsec - after.tv_nsec;
-  if (diff.tv_nsec < 0)
-    {
-      --diff.tv_sec;
-      diff.tv_nsec += 1000000000;
-    }
-  if (diff.tv_sec != 0 || diff.tv_nsec > 200000000)
-    {
-      printf ("dead - after %ju.%.9ju outside reasonable range\n",
-	      (uintmax_t) diff.tv_sec, (uintmax_t) diff.tv_nsec);
-      result = 1;
-    }
-
-  /* Now reap the child and verify that its clock is no longer valid.  */
-  {
-    int x;
-    if (waitpid (child, &x, 0) != child)
-      {
-	perror ("waitpid");
-	result = 1;
-      }
-  }
-
-  if (clock_gettime (child_clock, &dead) == 0)
-    {
-      printf ("clock_gettime on reaped PID %d clock %lx => %ju%.9ju\n",
-	      child, (unsigned long int) child_clock,
-	      (uintmax_t) dead.tv_sec, (uintmax_t) dead.tv_nsec);
-      result = 1;
-    }
-  else
-    {
-      if (errno != EINVAL)
-	result = 1;
-      printf ("clock_gettime on reaped PID %d clock %lx => %s\n",
-	      child, (unsigned long int) child_clock, strerror (errno));
-    }
-
-  if (clock_getres (child_clock, &dead) == 0)
-    {
-      printf ("clock_getres on reaped PID %d clock %lx => %ju%.9ju\n",
-	      child, (unsigned long int) child_clock,
-	      (uintmax_t) dead.tv_sec, (uintmax_t) dead.tv_nsec);
-      result = 1;
-    }
-  else
-    {
-      if (errno != EINVAL)
-	result = 1;
-      printf ("clock_getres on reaped PID %d clock %lx => %s\n",
-	      child, (unsigned long int) child_clock, strerror (errno));
-    }
-
-  return result;
-
- done:
-  {
-    if (kill (child, SIGKILL) != 0 && errno != ESRCH)
-      {
-	perror ("kill");
-	return 2;
-      }
-    int x;
-    if (waitpid (child, &x, 0) != child && errno != ECHILD)
-      {
-	perror ("waitpid");
-	return 2;
-      }
-  }
-
-  return result;
-}
-
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"