unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime
@ 2019-02-18 21:11 Adhemerval Zanella
  2019-02-18 21:11 ` [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID Adhemerval Zanella
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Adhemerval Zanella @ 2019-02-18 21:11 UTC (permalink / raw)
  To: libc-alpha

This patch removes CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID support
from clock_gettime and clock_settime generic implementation.  For Linux, kernel
already provides supports through the syscall and Hurd HTL lacks
__pthread_clock_gettime and __pthread_clock_settime internal implementation.

As described in clock_gettime man-page [1] on 'Historical note for SMP
system', implementing CLOCK_{THREAD,PROCESS}_CPUTIME_ID with timer registers
is error-prone and susceptible to timing and accurary issues that the libc
can not deal without kernel support.

This allows removes unused code which, however, still incur in some runtime
overhead in thread creation (the struct pthread cpuclock_offset
initialization).

If hurd eventually wants to support them it should either either implement as
a kernel facility (or something related due its architecture) or in system
specific implementation.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. I also
checked on a i686-gnu build.

	* nptl/Makefile (libpthread-routines): Remove pthread_clock_gettime and
	pthread_clock_settime.
	* nptl/pthreadP.h (__find_thread_by_id): Remove prototype.
	* elf/dl-support.c [!HP_TIMING_NOAVAIL] (_dl_cpuclock_offset): Remove.
	(_dl_non_dynamic_init): Remove _dl_cpuclock_offset setting.
	* elf/rtld.c (_dl_start_final): Likewise.
	* nptl/allocatestack.c (__find_thread_by_id): Remove function.
	* sysdeps/generic/ldsodefs.h [!HP_TIMING_NOAVAIL] (_dl_cpuclock_offset):
	Remove.
	* sysdeps/mach/hurd/dl-sysdep.c [!HP_TIMING_NOAVAIL]
	(_dl_cpuclock_offset): Remove.
	* nptl/descr.h (struct pthread): Rename cpuclock_offset to
	cpuclock_offset_ununsed.
	* nptl/nptl-init.c (__pthread_initialize_minimal_internal): Remove
	cpuclock_offset set.
	* nptl/pthread_create.c (START_THREAD_DEFN): Likewise.
	* sysdeps/nptl/fork.c (__libc_fork): Likewise.
	* nptl/pthread_clock_gettime.c: Remove file.
	* nptl/pthread_clock_settime.c: Likewise.
	* sysdeps/unix/clock_gettime.c (hp_timing_gettime): Remove function.
	[HP_TIMING_AVAIL] (realtime_gettime): Remove CLOCK_THREAD_CPUTIME_ID
	and CLOCK_PROCESS_CPUTIME_ID support.
	* sysdeps/unix/clock_settime.c (hp_timing_gettime): Likewise.
	[HP_TIMING_AVAIL] (realtime_gettime): Likewise.
	* sysdeps/posix/clock_getres.c (hp_timing_getres): Likewise.
	[HP_TIMING_AVAIL] (__clock_getres): Likewise.
	* sysdeps/unix/clock_nanosleep.c (CPUCLOCK_P, INVALID_CLOCK_P):
	Likewise.
	(__clock_nanosleep): Remove CPUCLOCK_P and INVALID_CLOCK_P usage.

[1] http://man7.org/linux/man-pages/man2/clock_gettime.2.html
---
 elf/dl-support.c               |  8 ----
 elf/rtld.c                     |  2 -
 nptl/Makefile                  |  1 -
 nptl/allocatestack.c           | 48 ------------------------
 nptl/descr.h                   |  3 +-
 nptl/nptl-init.c               |  3 --
 nptl/pthreadP.h                | 10 -----
 nptl/pthread_clock_gettime.c   | 67 ----------------------------------
 nptl/pthread_clock_settime.c   | 54 ---------------------------
 nptl/pthread_create.c          |  7 ----
 sysdeps/generic/ldsodefs.h     |  5 ---
 sysdeps/mach/hurd/dl-sysdep.c  |  8 ----
 sysdeps/nptl/fork.c            |  8 ----
 sysdeps/posix/clock_getres.c   | 46 +----------------------
 sysdeps/unix/clock_gettime.c   | 65 +--------------------------------
 sysdeps/unix/clock_nanosleep.c | 30 ++-------------
 sysdeps/unix/clock_settime.c   | 61 +------------------------------
 17 files changed, 9 insertions(+), 417 deletions(-)
 delete mode 100644 nptl/pthread_clock_gettime.c
 delete mode 100644 nptl/pthread_clock_settime.c

diff --git a/elf/dl-support.c b/elf/dl-support.c
index 42c350c75d..0a8b636d02 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -129,11 +129,6 @@ void *_dl_random;
 #include <dl-procruntime.c>
 #include <dl-procinfo.c>
 
-/* Initial value of the CPU clock.  */
-#ifndef HP_TIMING_NONAVAIL
-hp_timing_t _dl_cpuclock_offset;
-#endif
-
 void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
 
 size_t _dl_pagesize = EXEC_PAGESIZE;
@@ -314,9 +309,6 @@ _dl_non_dynamic_init (void)
   _dl_main_map.l_phdr = GL(dl_phdr);
   _dl_main_map.l_phnum = GL(dl_phnum);
 
-  if (HP_SMALL_TIMING_AVAIL)
-    HP_TIMING_NOW (_dl_cpuclock_offset);
-
   _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
 
   /* Set up the data structures for the system-supplied DSO early,
diff --git a/elf/rtld.c b/elf/rtld.c
index c1cc1b01f2..1f124b31fc 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -403,8 +403,6 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
 # endif
 #endif
 
-  HP_TIMING_NOW (GL(dl_cpuclock_offset));
-
   /* Initialize the stack end variable.  */
   __libc_stack_end = __builtin_frame_address (0);
 
diff --git a/nptl/Makefile b/nptl/Makefile
index 5acfdcceff..f9bc5cc887 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -109,7 +109,6 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
 		      pthread_once \
 		      old_pthread_atfork \
 		      pthread_getcpuclockid \
-		      pthread_clock_gettime pthread_clock_settime \
 		      shm-directory \
 		      sem_init sem_destroy \
 		      sem_open sem_close sem_unlink \
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index d8e8570a7d..fcbc46f0d7 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -963,54 +963,6 @@ __reclaim_stacks (void)
 }
 
 
-#if HP_TIMING_AVAIL
-# undef __find_thread_by_id
-/* Find a thread given the thread ID.  */
-attribute_hidden
-struct pthread *
-__find_thread_by_id (pid_t tid)
-{
-  struct pthread *result = NULL;
-
-  lll_lock (stack_cache_lock, LLL_PRIVATE);
-
-  /* Iterate over the list with system-allocated threads first.  */
-  list_t *runp;
-  list_for_each (runp, &stack_used)
-    {
-      struct pthread *curp;
-
-      curp = list_entry (runp, struct pthread, list);
-
-      if (curp->tid == tid)
-	{
-	  result = curp;
-	  goto out;
-	}
-    }
-
-  /* Now the list with threads using user-allocated stacks.  */
-  list_for_each (runp, &__stack_user)
-    {
-      struct pthread *curp;
-
-      curp = list_entry (runp, struct pthread, list);
-
-      if (curp->tid == tid)
-	{
-	  result = curp;
-	  goto out;
-	}
-    }
-
- out:
-  lll_unlock (stack_cache_lock, LLL_PRIVATE);
-
-  return result;
-}
-#endif
-
-
 #ifdef SIGSETXID
 static void
 setxid_mark_thread (struct xid_command *cmdp, struct pthread *t)
diff --git a/nptl/descr.h b/nptl/descr.h
index 4ef33ae465..cb7d4c2282 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -343,8 +343,7 @@ struct pthread
   unsigned int setxid_futex;
 
 #if HP_TIMING_AVAIL
-  /* Offset of the CPU clock at start thread start time.  */
-  hp_timing_t cpuclock_offset;
+  hp_timing_t cpuclock_offset_ununsed;
 #endif
 
   /* If the thread waits to join another one the ID of the latter is
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index b5895fabf3..6691211e4e 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -276,9 +276,6 @@ __pthread_initialize_minimal_internal (void)
   THREAD_SETMEM (pd, user_stack, true);
   if (LLL_LOCK_INITIALIZER != 0)
     THREAD_SETMEM (pd, lock, LLL_LOCK_INITIALIZER);
-#if HP_TIMING_AVAIL
-  THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset));
-#endif
 
   /* Initialize the robust mutex data.  */
   {
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 626bd4b096..f0facfdb7d 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -401,16 +401,6 @@ extern int __pthread_multiple_threads attribute_hidden;
 extern int *__libc_multiple_threads_ptr attribute_hidden;
 #endif
 
-/* Find a thread given its TID.  */
-extern struct pthread *__find_thread_by_id (pid_t tid) attribute_hidden
-#ifdef SHARED
-;
-#else
-weak_function;
-#define __find_thread_by_id(tid) \
-  (__find_thread_by_id ? (__find_thread_by_id) (tid) : (struct pthread *) NULL)
-#endif
-
 extern void __pthread_init_static_tls (struct link_map *) attribute_hidden;
 
 extern size_t __pthread_get_minstack (const pthread_attr_t *attr);
diff --git a/nptl/pthread_clock_gettime.c b/nptl/pthread_clock_gettime.c
deleted file mode 100644
index f1d9104b24..0000000000
--- a/nptl/pthread_clock_gettime.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright (C) 2001-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; see the file COPYING.LIB.  If
-   not, see <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <time.h>
-#include "pthreadP.h"
-
-
-#if HP_TIMING_AVAIL
-int
-__pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
-			 struct timespec *tp)
-{
-  hp_timing_t tsc;
-
-  /* Get the current counter.  */
-  HP_TIMING_NOW (tsc);
-
-  /* This is the ID of the thread we are looking for.  */
-  pid_t tid = ((unsigned int) clock_id) >> CLOCK_IDFIELD_SIZE;
-
-  /* Compute the offset since the start time of the process.  */
-  if (tid == 0 || tid == THREAD_GETMEM (THREAD_SELF, tid))
-    /* Our own clock.  */
-    tsc -= THREAD_GETMEM (THREAD_SELF, cpuclock_offset);
-  else
-    {
-      /* This is more complicated.  We have to locate the thread based
-	 on the ID.  This means walking the list of existing
-	 threads.  */
-      struct pthread *thread = __find_thread_by_id (tid);
-      if (thread == NULL)
-	{
-	  __set_errno (EINVAL);
-	  return -1;
-	}
-
-      /* There is a race here.  The thread might terminate and the stack
-	 become unusable.  But this is the user's problem.  */
-      tsc -= thread->cpuclock_offset;
-    }
-
-  /* Compute the seconds.  */
-  tp->tv_sec = tsc / freq;
-
-  /* And the nanoseconds.  This computation should be stable until
-     we get machines with about 16GHz frequency.  */
-  tp->tv_nsec = ((tsc % freq) * 1000000000ull) / freq;
-
-  return 0;
-}
-#endif
diff --git a/nptl/pthread_clock_settime.c b/nptl/pthread_clock_settime.c
deleted file mode 100644
index 0fe6482f78..0000000000
--- a/nptl/pthread_clock_settime.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (C) 2001-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; see the file COPYING.LIB.  If
-   not, see <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <time.h>
-#include "pthreadP.h"
-
-
-#if HP_TIMING_AVAIL
-int
-__pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
-{
-  /* This is the ID of the thread we are looking for.  */
-  pid_t tid = ((unsigned int) clock_id) >> CLOCK_IDFIELD_SIZE;
-
-  /* Compute the offset since the start time of the process.  */
-  if (tid == 0 || tid == THREAD_GETMEM (THREAD_SELF, tid))
-    /* Our own clock.  */
-    THREAD_SETMEM (THREAD_SELF, cpuclock_offset, offset);
-  else
-    {
-      /* This is more complicated.  We have to locate the thread based
-	 on the ID.  This means walking the list of existing
-	 threads.  */
-      struct pthread *thread = __find_thread_by_id (tid);
-      if (thread == NULL)
-	{
-	  __set_errno (EINVAL);
-	  return -1;
-	}
-
-      /* There is a race here.  The thread might terminate and the stack
-	 become unusable.  But this is the user's problem.  */
-      thread->cpuclock_offset = offset;
-    }
-
-  return 0;
-}
-#endif
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 2bd2b10727..18b7bbe765 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -379,13 +379,6 @@ START_THREAD_DEFN
 {
   struct pthread *pd = START_THREAD_SELF;
 
-#if HP_TIMING_AVAIL
-  /* Remember the time when the thread was started.  */
-  hp_timing_t now;
-  HP_TIMING_NOW (now);
-  THREAD_SETMEM (pd, cpuclock_offset, now);
-#endif
-
   /* Initialize resolver state pointer.  */
   __resp = &pd->res;
 
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 37cab6f06b..346bbb812d 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -352,11 +352,6 @@ struct rtld_global
   /* The object to be initialized first.  */
   EXTERN struct link_map *_dl_initfirst;
 
-#if HP_SMALL_TIMING_AVAIL
-  /* Start time on CPU clock.  */
-  EXTERN hp_timing_t _dl_cpuclock_offset;
-#endif
-
   /* Map of shared object to be profiled.  */
   EXTERN struct link_map *_dl_profile_map;
 
diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c
index a58338c930..72c80a8a46 100644
--- a/sysdeps/mach/hurd/dl-sysdep.c
+++ b/sysdeps/mach/hurd/dl-sysdep.c
@@ -62,10 +62,6 @@ int __libc_multiple_libcs = 0;	/* Defining this here avoids the inclusion
 void *__libc_stack_end = NULL;
 rtld_hidden_data_def(__libc_stack_end)
 
-#if HP_TIMING_AVAIL
-hp_timing_t _dl_cpuclock_offset;
-#endif
-
 /* TODO: Initialize.  */
 void *_dl_random attribute_relro = NULL;
 
@@ -246,10 +242,6 @@ unfmh();			/* XXX */
   /* Initialize frequently used global variable.  */
   GLRO(dl_pagesize) = __getpagesize ();
 
-#if HP_TIMING_AVAIL
-  HP_TIMING_NOW (_dl_cpuclock_offset);
-#endif
-
 fmh();				/* XXX */
 
   /* See hurd/hurdstartup.c; this deals with getting information
diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
index 14b69a6f89..3f357665bd 100644
--- a/sysdeps/nptl/fork.c
+++ b/sysdeps/nptl/fork.c
@@ -83,14 +83,6 @@ __libc_fork (void)
       if (__fork_generation_pointer != NULL)
 	*__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR;
 
-#if HP_TIMING_AVAIL
-      /* The CPU clock of the thread and process have to be set to zero.  */
-      hp_timing_t now;
-      HP_TIMING_NOW (now);
-      THREAD_SETMEM (self, cpuclock_offset, now);
-      GL(dl_cpuclock_offset) = now;
-#endif
-
 #ifdef __NR_set_robust_list
       /* Initialize the robust mutex list setting in the kernel which has
 	 been reset during the fork.  We do not check for errors because if
diff --git a/sysdeps/posix/clock_getres.c b/sysdeps/posix/clock_getres.c
index dac4761fcc..01024a3f55 100644
--- a/sysdeps/posix/clock_getres.c
+++ b/sysdeps/posix/clock_getres.c
@@ -24,37 +24,6 @@
 #include <libc-internal.h>
 
 
-#if HP_TIMING_AVAIL
-static long int nsec;		/* Clock frequency of the processor.  */
-
-static int
-hp_timing_getres (struct timespec *res)
-{
-  if (__glibc_unlikely (nsec == 0))
-    {
-      hp_timing_t freq;
-
-      /* This can only happen if we haven't initialized the `nsec'
-	 variable yet.  Do this now.  We don't have to protect this
-	 code against multiple execution since all of them should
-	 lead to the same result.  */
-      freq = __get_clockfreq ();
-      if (__glibc_unlikely (freq == 0))
-	/* Something went wrong.  */
-	return -1;
-
-      nsec = MAX (UINT64_C (1000000000) / freq, 1);
-    }
-
-  /* Fill in the values.
-     The seconds are always zero (unless we have a 1Hz machine).  */
-  res->tv_sec = 0;
-  res->tv_nsec = nsec;
-
-  return 0;
-}
-#endif
-
 static inline int
 realtime_getres (struct timespec *res)
 {
@@ -87,21 +56,8 @@ __clock_getres (clockid_t clock_id, struct timespec *res)
       break;
 
     default:
-#if HP_TIMING_AVAIL
-      if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
-	  == CLOCK_THREAD_CPUTIME_ID)
-	retval = hp_timing_getres (res);
-      else
-#endif
-	__set_errno (EINVAL);
-      break;
-
-#if HP_TIMING_AVAIL
-    case CLOCK_PROCESS_CPUTIME_ID:
-    case CLOCK_THREAD_CPUTIME_ID:
-      retval = hp_timing_getres (res);
+      __set_errno (EINVAL);
       break;
-#endif
     }
 
   return retval;
diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/unix/clock_gettime.c
index 33a1f3335c..10a6c96d9d 100644
--- a/sysdeps/unix/clock_gettime.c
+++ b/sysdeps/unix/clock_gettime.c
@@ -24,57 +24,6 @@
 #include <ldsodefs.h>
 
 
-#if HP_TIMING_AVAIL
-/* Clock frequency of the processor.  We make it a 64-bit variable
-   because some jokers are already playing with processors with more
-   than 4GHz.  */
-static hp_timing_t freq;
-
-
-/* This function is defined in the thread library.  */
-extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
-				    struct timespec *tp)
-     __attribute__ ((__weak__));
-
-static int
-hp_timing_gettime (clockid_t clock_id, struct timespec *tp)
-{
-  hp_timing_t tsc;
-
-  if (__glibc_unlikely (freq == 0))
-    {
-      /* This can only happen if we haven't initialized the `freq'
-	 variable yet.  Do this now. We don't have to protect this
-	 code against multiple execution since all of them should
-	 lead to the same result.  */
-      freq = __get_clockfreq ();
-      if (__glibc_unlikely (freq == 0))
-	/* Something went wrong.  */
-	return -1;
-    }
-
-  if (clock_id != CLOCK_PROCESS_CPUTIME_ID
-      && __pthread_clock_gettime != NULL)
-    return __pthread_clock_gettime (clock_id, freq, tp);
-
-  /* Get the current counter.  */
-  HP_TIMING_NOW (tsc);
-
-  /* Compute the offset since the start time of the process.  */
-  tsc -= GL(dl_cpuclock_offset);
-
-  /* Compute the seconds.  */
-  tp->tv_sec = tsc / freq;
-
-  /* And the nanoseconds.  This computation should be stable until
-     we get machines with about 16GHz frequency.  */
-  tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq;
-
-  return 0;
-}
-#endif
-
-
 static inline int
 realtime_gettime (struct timespec *tp)
 {
@@ -105,20 +54,8 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp)
       break;
 
     default:
-#if HP_TIMING_AVAIL
-      if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
-	  == CLOCK_THREAD_CPUTIME_ID)
-	retval = hp_timing_gettime (clock_id, tp);
-      else
-#endif
-	__set_errno (EINVAL);
-      break;
-
-#if HP_TIMING_AVAIL
-    case CLOCK_PROCESS_CPUTIME_ID:
-      retval = hp_timing_gettime (clock_id, tp);
+      __set_errno (EINVAL);
       break;
-#endif
     }
 
   return retval;
diff --git a/sysdeps/unix/clock_nanosleep.c b/sysdeps/unix/clock_nanosleep.c
index 7722d1111c..b27608570c 100644
--- a/sysdeps/unix/clock_nanosleep.c
+++ b/sysdeps/unix/clock_nanosleep.c
@@ -19,23 +19,8 @@
 #include <assert.h>
 #include <errno.h>
 #include <time.h>
-#include <hp-timing.h>
 #include <sysdep-cancel.h>
 
-#if HP_TIMING_AVAIL
-# define CPUCLOCK_P(clock) \
-  ((clock) == CLOCK_PROCESS_CPUTIME_ID					      \
-   || ((clock) & ((1 << CLOCK_IDFIELD_SIZE) - 1)) == CLOCK_THREAD_CPUTIME_ID)
-#else
-# define CPUCLOCK_P(clock) 0
-#endif
-
-#ifndef INVALID_CLOCK_P
-# define INVALID_CLOCK_P(cl) \
-  ((cl) < CLOCK_REALTIME || (cl) > CLOCK_THREAD_CPUTIME_ID)
-#endif
-
-
 /* This implementation assumes that these is only a `nanosleep' system
    call.  So we have to remap all other activities.  */
 int
@@ -51,14 +36,7 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
   if (clock_id == CLOCK_THREAD_CPUTIME_ID)
     return EINVAL;		/* POSIX specifies EINVAL for this case.  */
 
-#ifdef SYSDEP_NANOSLEEP
-  SYSDEP_NANOSLEEP;
-#endif
-
-  if (CPUCLOCK_P (clock_id))
-    return ENOTSUP;
-
-  if (INVALID_CLOCK_P (clock_id))
+  if (clock_id < CLOCK_REALTIME || clock_id > CLOCK_THREAD_CPUTIME_ID)
     return EINVAL;
 
   /* If we got an absolute time, remap it.  */
@@ -71,7 +49,7 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
       assert (sizeof (sec) >= sizeof (now.tv_sec));
 
       /* Get the current time for this clock.  */
-      if (__builtin_expect (__clock_gettime (clock_id, &now), 0) != 0)
+      if (__clock_gettime (clock_id, &now) != 0)
 	return errno;
 
       /* Compute the difference.  */
@@ -90,12 +68,12 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
       /* Make sure we are not modifying the struct pointed to by REM.  */
       rem = NULL;
     }
-  else if (__builtin_expect (flags, 0) != 0)
+  else if (flags != 0)
     return EINVAL;
   else if (clock_id != CLOCK_REALTIME)
     /* Not supported.  */
     return ENOTSUP;
 
-  return __builtin_expect (__nanosleep (req, rem), 0) ? errno : 0;
+  return __nanosleep (req, rem), 0 ? errno : 0;
 }
 weak_alias (__clock_nanosleep, clock_nanosleep)
diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/unix/clock_settime.c
index dcf9ff660a..109a1ad872 100644
--- a/sysdeps/unix/clock_settime.c
+++ b/sysdeps/unix/clock_settime.c
@@ -21,59 +21,11 @@
 #include <ldsodefs.h>
 
 
-#if HP_TIMING_AVAIL
-/* Clock frequency of the processor.  We make it a 64-bit variable
-   because some jokers are already playing with processors with more
-   than 4GHz.  */
-static hp_timing_t freq;
-
-
-/* This function is defined in the thread library.  */
-extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
-     __attribute__ ((__weak__));
-
-
-static int
-hp_timing_settime (clockid_t clock_id, const struct timespec *tp)
-{
-  hp_timing_t tsc;
-  hp_timing_t usertime;
-
-  /* First thing is to get the current time.  */
-  HP_TIMING_NOW (tsc);
-
-  if (__glibc_unlikely (freq == 0))
-    {
-      /* This can only happen if we haven't initialized the `freq'
-	 variable yet.  Do this now. We don't have to protect this
-	 code against multiple execution since all of them should lead
-	 to the same result.  */
-      freq = __get_clockfreq ();
-      if (__glibc_unlikely (freq == 0))
-	/* Something went wrong.  */
-	return -1;
-    }
-
-  /* Convert the user-provided time into CPU ticks.  */
-  usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull;
-
-  /* Determine the offset and use it as the new base value.  */
-  if (clock_id == CLOCK_PROCESS_CPUTIME_ID
-      || __pthread_clock_settime == NULL)
-    GL(dl_cpuclock_offset) = tsc - usertime;
-  else
-    __pthread_clock_settime (clock_id, tsc - usertime);
-
-  return 0;
-}
-#endif
-
-
 /* Set CLOCK to value TP.  */
 int
 __clock_settime (clockid_t clock_id, const struct timespec *tp)
 {
-  int retval;
+  int retval = -1;
 
   /* Make sure the time cvalue is OK.  */
   if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000)
@@ -93,16 +45,7 @@ __clock_settime (clockid_t clock_id, const struct timespec *tp)
       break;
 
     default:
-# if HP_TIMING_AVAIL
-      if (CPUCLOCK_WHICH (clock_id) == CLOCK_PROCESS_CPUTIME_ID
-	  || CPUCLOCK_WHICH (clock_id) == CLOCK_THREAD_CPUTIME_ID)
-	retval = hp_timing_settime (clock_id, tp);
-      else
-# endif
-	{
-	  __set_errno (EINVAL);
-	  retval = -1;
-	}
+      __set_errno (EINVAL);
       break;
     }
 
-- 
2.17.1


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

* [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID
  2019-02-18 21:11 [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
@ 2019-02-18 21:11 ` Adhemerval Zanella
  2019-03-19 17:24   ` Adhemerval Zanella
  2019-03-20 11:49   ` Andreas Schwab
  2019-02-18 21:11 ` [PATCH v2 3/6] Remove __get_clockfreq Adhemerval Zanella
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 14+ messages in thread
From: Adhemerval Zanella @ 2019-02-18 21:11 UTC (permalink / raw)
  To: libc-alpha

Changes from previous version:

  - Remove ia64 itc drift check and assume kernel handles it correctly.

---

This patch assumes that clock_getres syscall always support
CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID, so there is no need
to fallback to hp-timing support for _SC_MONOTONIC_CLOCK.  This allows
simplify the sysconf support to always use the syscall.

The ia64 implementation is also simplified and consolidate in one file.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.

	* sysdeps/unix/sysv/linux/ia64/has_cpuclock.c: Remove file.
	* sysdeps/unix/sysv/linux/ia64/sysconf.c: Likewise.
	* sysdeps/unix/sysv/linux/sysconf.c (has_cpuclock): Remove function.
	(check_clock_getres): New function.
	(__sysconf): Use check_clock_getres instead of has_cpuclock.
---
 sysdeps/unix/sysv/linux/ia64/has_cpuclock.c | 51 ---------------------
 sysdeps/unix/sysv/linux/ia64/sysconf.c      | 30 ------------
 sysdeps/unix/sysv/linux/sysconf.c           | 48 ++++++-------------
 3 files changed, 13 insertions(+), 116 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/ia64/has_cpuclock.c
 delete mode 100644 sysdeps/unix/sysv/linux/ia64/sysconf.c

diff --git a/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c b/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c
deleted file mode 100644
index b3afb37f8b..0000000000
--- a/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 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 <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <not-cancel.h>
-
-static int itc_usable;
-
-static int
-has_cpuclock (void)
-{
-  if (__builtin_expect (itc_usable == 0, 0))
-    {
-      int newval = 1;
-      int fd = __open_nocancel ("/proc/sal/itc_drift", O_RDONLY);
-      if (__builtin_expect (fd != -1, 1))
-	{
-	  char buf[16];
-	  /* We expect the file to contain a single digit followed by
-	     a newline.  If the format changes we better not rely on
-	     the file content.  */
-	  if (__read_nocancel (fd, buf, sizeof buf) != 2
-	      || buf[0] != '0' || buf[1] != '\n')
-	    newval = -1;
-
-	  __close_nocancel_nostatus (fd);
-	}
-
-      itc_usable = newval;
-    }
-
-  return itc_usable;
-}
diff --git a/sysdeps/unix/sysv/linux/ia64/sysconf.c b/sysdeps/unix/sysv/linux/ia64/sysconf.c
deleted file mode 100644
index ef75322f1f..0000000000
--- a/sysdeps/unix/sysv/linux/ia64/sysconf.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Get file-specific information about a file.  Linux/ia64 version.
-   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 <assert.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-
-#include "has_cpuclock.c"
-#define HAS_CPUCLOCK(name) (has_cpuclock () ? _POSIX_VERSION : -1)
-
-
-/* Now the generic Linux version.  */
-#include <sysdeps/unix/sysv/linux/sysconf.c>
diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
index 4b297ba35f..2027444488 100644
--- a/sysdeps/unix/sysv/linux/sysconf.c
+++ b/sysdeps/unix/sysv/linux/sysconf.c
@@ -35,33 +35,18 @@
 static long int posix_sysconf (int name);
 
 
-#ifndef HAS_CPUCLOCK
 static long int
-has_cpuclock (int name)
+check_clock_getres (clockid_t clk_id)
 {
-# if defined __NR_clock_getres || HP_TIMING_AVAIL
-  /* If we have HP_TIMING, we will fall back on that if the system
-     call does not work, so we support it either way.  */
-#  if !HP_TIMING_AVAIL
-  /* Check using the clock_getres system call.  */
   struct timespec ts;
   INTERNAL_SYSCALL_DECL (err);
-  int r = INTERNAL_SYSCALL (clock_getres, err, 2,
-			    (name == _SC_CPUTIME
-			     ? CLOCK_PROCESS_CPUTIME_ID
-			     : CLOCK_THREAD_CPUTIME_ID),
-			    &ts);
+  /* Avoid setting errno to we can check whether the kernel supports
+     the CLK_ID.  */
+  int r = INTERNAL_SYSCALL_CALL (clock_getres, err, clk_id, &ts);
   if (INTERNAL_SYSCALL_ERROR_P (r, err))
     return -1;
-#  endif
   return _POSIX_VERSION;
-# else
-  return -1;
-# endif
 }
-# define HAS_CPUCLOCK(name) has_cpuclock (name)
-#endif
-
 
 /* Get the value of the system variable NAME.  */
 long int
@@ -71,29 +56,21 @@ __sysconf (int name)
 
   switch (name)
     {
-      struct rlimit rlimit;
-#ifdef __NR_clock_getres
     case _SC_MONOTONIC_CLOCK:
-      /* Check using the clock_getres system call.  */
-      {
-	struct timespec ts;
-	INTERNAL_SYSCALL_DECL (err);
-	int r;
-	r = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
-	return INTERNAL_SYSCALL_ERROR_P (r, err) ? -1 : _POSIX_VERSION;
-      }
-#endif
-
+      return check_clock_getres (CLOCK_MONOTONIC);
     case _SC_CPUTIME:
+      return check_clock_getres (CLOCK_PROCESS_CPUTIME_ID);
     case _SC_THREAD_CPUTIME:
-      return HAS_CPUCLOCK (name);
+      return check_clock_getres (CLOCK_THREAD_CPUTIME_ID);
 
-    case _SC_ARG_MAX:
+    case _SC_ARG_MAX: {
+      struct rlimit rlimit;
       /* Use getrlimit to get the stack limit.  */
       if (__getrlimit (RLIMIT_STACK, &rlimit) == 0)
 	return MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4);
 
       return legacy_ARG_MAX;
+    } break;
 
     case _SC_NGROUPS_MAX:
       /* Try to read the information from the /proc/sys/kernel/ngroups_max
@@ -101,13 +78,14 @@ __sysconf (int name)
       procfname = "/proc/sys/kernel/ngroups_max";
       break;
 
-    case _SC_SIGQUEUE_MAX:
+    case _SC_SIGQUEUE_MAX: {
+      struct rlimit rlimit;
       if (__getrlimit (RLIMIT_SIGPENDING, &rlimit) == 0)
 	return rlimit.rlim_cur;
 
       /* The /proc/sys/kernel/rtsig-max file contains the answer.  */
       procfname = "/proc/sys/kernel/rtsig-max";
-      break;
+    } break;
 
     default:
       break;
-- 
2.17.1


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

* [PATCH v2 3/6] Remove __get_clockfreq
  2019-02-18 21:11 [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
  2019-02-18 21:11 ` [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID Adhemerval Zanella
@ 2019-02-18 21:11 ` Adhemerval Zanella
  2019-03-19 17:24   ` Adhemerval Zanella
  2019-02-18 21:11 ` [PATCH v2 4/6] Do not use HP_TIMING_NOW for random bits Adhemerval Zanella
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Adhemerval Zanella @ 2019-02-18 21:11 UTC (permalink / raw)
  To: libc-alpha

With clock_getres, clock_gettime, and clock_settime refactor to remove the
generic CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID support through
hp-timing, there is no usage of internal __get_clockfreq.  This patch removes
both generic and Linux implementation..

Checked with a build against aarch64-linux-gnu, i686-linux-gnu, ia64-linux-gnu,
sparc64-linux-gnu, powerpc-linux-gnu-power4.

	* include/libc-internal.h (__get_clockfreq): Remove prototype.
	* rt/Makefile (clock-routines): Remove get_clockfreq.
	* rt/get_clockfreq.c: Remove file.
	* sysdeps/unix/sysv/linux/i386/get_clockfreq.c: Likewise.
	* sysdeps/unix/sysv/linux/ia64/get_clockfreq.c: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c: Move code to ...
	* sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c: ... here.
---
 include/libc-internal.h                       |   3 -
 rt/Makefile                                   |   2 +-
 rt/get_clockfreq.c                            |  27 --
 sysdeps/unix/sysv/linux/i386/get_clockfreq.c  |  88 ------
 sysdeps/unix/sysv/linux/ia64/get_clockfreq.c  |  87 ------
 .../unix/sysv/linux/powerpc/get_clockfreq.c   | 107 --------
 .../sysv/linux/powerpc/get_timebase_freq.c    |  81 +++++-
 .../sysv/linux/sparc/sparc64/get_clockfreq.c  | 250 ------------------
 8 files changed, 81 insertions(+), 564 deletions(-)
 delete mode 100644 rt/get_clockfreq.c
 delete mode 100644 sysdeps/unix/sysv/linux/i386/get_clockfreq.c
 delete mode 100644 sysdeps/unix/sysv/linux/ia64/get_clockfreq.c
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c

diff --git a/include/libc-internal.h b/include/libc-internal.h
index 70edd77f81..db4d12432c 100644
--- a/include/libc-internal.h
+++ b/include/libc-internal.h
@@ -36,9 +36,6 @@ libc_hidden_proto (__profile_frequency)
 extern void __cyg_profile_func_enter (void *this_fn, void *call_site);
 extern void __cyg_profile_func_exit (void *this_fn, void *call_site);
 
-/* Get frequency of the system processor.  */
-extern hp_timing_t __get_clockfreq (void);
-
 /* Free all allocated resources.  */
 extern void __libc_freeres (void);
 libc_hidden_proto (__libc_freeres)
diff --git a/rt/Makefile b/rt/Makefile
index 0789bb8db7..9ea8394565 100644
--- a/rt/Makefile
+++ b/rt/Makefile
@@ -28,7 +28,7 @@ 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 := get_clockfreq clock_getcpuclockid			\
+clock-routines := clock_getcpuclockid					\
 		  clock_getres clock_gettime clock_settime		\
 		  clock_nanosleep
 timer-routines := timer_create timer_delete timer_getoverr		\
diff --git a/rt/get_clockfreq.c b/rt/get_clockfreq.c
deleted file mode 100644
index e62a7a5118..0000000000
--- a/rt/get_clockfreq.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Get frequency of the system processor.
-   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 <libc-internal.h>
-
-hp_timing_t
-__get_clockfreq (void)
-{
-  /* There is no generic way to find this out since we have in general
-     no counter register either.  */
-  return 0;
-}
diff --git a/sysdeps/unix/sysv/linux/i386/get_clockfreq.c b/sysdeps/unix/sysv/linux/i386/get_clockfreq.c
deleted file mode 100644
index 621d52491b..0000000000
--- a/sysdeps/unix/sysv/linux/i386/get_clockfreq.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Get frequency of the system processor.  i386/Linux 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 <ctype.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-
-hp_timing_t
-__get_clockfreq (void)
-{
-  /* We read the information from the /proc filesystem.  It contains at
-     least one line like
-	cpu MHz         : 497.840237
-     or also
-	cpu MHz         : 497.841
-     We search for this line and convert the number in an integer.  */
-  static hp_timing_t result;
-  int fd;
-
-  /* If this function was called before, we know the result.  */
-  if (result != 0)
-    return result;
-
-  fd = __open ("/proc/cpuinfo", O_RDONLY);
-  if (__glibc_likely (fd != -1))
-    {
-      /* XXX AFAIK the /proc filesystem can generate "files" only up
-         to a size of 4096 bytes.  */
-      char buf[4096];
-      ssize_t n;
-
-      n = __read (fd, buf, sizeof buf);
-      if (__builtin_expect (n, 1) > 0)
-	{
-	  char *mhz = memmem (buf, n, "cpu MHz", 7);
-
-	  if (__glibc_likely (mhz != NULL))
-	    {
-	      char *endp = buf + n;
-	      int seen_decpoint = 0;
-	      int ndigits = 0;
-
-	      /* Search for the beginning of the string.  */
-	      while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
-		++mhz;
-
-	      while (mhz < endp && *mhz != '\n')
-		{
-		  if (*mhz >= '0' && *mhz <= '9')
-		    {
-		      result *= 10;
-		      result += *mhz - '0';
-		      if (seen_decpoint)
-			++ndigits;
-		    }
-		  else if (*mhz == '.')
-		    seen_decpoint = 1;
-
-		  ++mhz;
-		}
-
-	      /* Compensate for missing digits at the end.  */
-	      while (ndigits++ < 6)
-		result *= 10;
-	    }
-	}
-
-      __close (fd);
-    }
-
-  return result;
-}
diff --git a/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c b/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c
deleted file mode 100644
index 581f87f3e6..0000000000
--- a/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Get frequency of the system processor.  IA-64/Linux version.
-   Copyright (C) 2001-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 <ctype.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-
-
-hp_timing_t
-__get_clockfreq (void)
-{
-  /* We read the information from the /proc filesystem.  It contains at
-     least one line like
-	itc MHz    : 733.390988
-     We search for this line and convert the number in an integer.  */
-  static hp_timing_t result;
-  int fd;
-
-  /* If this function was called before, we know the result.  */
-  if (result != 0)
-    return result;
-
-  fd = __open ("/proc/cpuinfo", O_RDONLY);
-  if (__builtin_expect (fd != -1, 1))
-    {
-      /* XXX AFAIK the /proc filesystem can generate "files" only up
-         to a size of 4096 bytes.  */
-      char buf[4096];
-      ssize_t n;
-
-      n = __read (fd, buf, sizeof buf);
-      if (__builtin_expect (n, 1) > 0)
-	{
-	  char *mhz = memmem (buf, n, "itc MHz", 7);
-
-	  if (__builtin_expect (mhz != NULL, 1))
-	    {
-	      char *endp = buf + n;
-	      int seen_decpoint = 0;
-	      int ndigits = 0;
-
-	      /* Search for the beginning of the string.  */
-	      while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
-		++mhz;
-
-	      while (mhz < endp && *mhz != '\n')
-		{
-		  if (*mhz >= '0' && *mhz <= '9')
-		    {
-		      result *= 10;
-		      result += *mhz - '0';
-		      if (seen_decpoint)
-			++ndigits;
-		    }
-		  else if (*mhz == '.')
-		    seen_decpoint = 1;
-
-		  ++mhz;
-		}
-
-	      /* Compensate for missing digits at the end.  */
-	      while (ndigits++ < 6)
-		result *= 10;
-	    }
-	}
-
-      __close (fd);
-    }
-
-  return result;
-}
diff --git a/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c b/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c
deleted file mode 100644
index 98668fa718..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Get frequency of the system processor.  powerpc/Linux 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 <ctype.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <sysdep.h>
-#include <libc-vdso.h>
-#include <not-cancel.h>
-
-hp_timing_t
-__get_clockfreq (void)
-{
-  hp_timing_t result = 0L;
-
-#ifdef SHARED
-  /* The vDSO does not return an error (it clear cr0.so on returning).  */
-  INTERNAL_SYSCALL_DECL (err);
-  result =
-    INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, uint64_t, 0);
-#else
-  /* We read the information from the /proc filesystem.  /proc/cpuinfo
-     contains at least one line like:
-     timebase        : 33333333
-     We search for this line and convert the number into an integer.  */
-  int fd = __open_nocancel ("/proc/cpuinfo", O_RDONLY);
-  if (__glibc_likely (fd != -1))
-    return result;
-
-  /* The timebase will be in the 1st 1024 bytes for systems with up
-     to 8 processors.  If the first read returns less then 1024
-     bytes read,  we have the whole cpuinfo and can start the scan.
-     Otherwise we will have to read more to insure we have the
-     timebase value in the scan.  */
-  char buf[1024];
-  ssize_t n;
-
-  n = __read_nocancel (fd, buf, sizeof (buf));
-  if (n == sizeof (buf))
-    {
-      /* We are here because the 1st read returned exactly sizeof
-         (buf) bytes.  This implies that we are not at EOF and may
-         not have read the timebase value yet.  So we need to read
-         more bytes until we know we have EOF.  We copy the lower
-         half of buf to the upper half and read sizeof (buf)/2
-         bytes into the lower half of buf and repeat until we
-         reach EOF.  We can assume that the timebase will be in
-         the last 512 bytes of cpuinfo, so two 512 byte half_bufs
-         will be sufficient to contain the timebase and will
-         handle the case where the timebase spans the half_buf
-         boundry.  */
-      const ssize_t half_buf = sizeof (buf) / 2;
-      while (n >= half_buf)
-	{
-	  memcpy (buf, buf + half_buf, half_buf);
-	  n = __read_nocancel (fd, buf + half_buf, half_buf);
-	}
-      if (n >= 0)
-	n += half_buf;
-    }
-  __close_nocancel (fd);
-
-  if (__glibc_likely (n > 0))
-    {
-      char *mhz = memmem (buf, n, "timebase", 7);
-
-      if (__glibc_likely (mhz != NULL))
-	{
-	  char *endp = buf + n;
-
-	  /* Search for the beginning of the string.  */
-	  while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
-	    ++mhz;
-
-	  while (mhz < endp && *mhz != '\n')
-	    {
-	      if (*mhz >= '0' && *mhz <= '9')
-		{
-		  result *= 10;
-		  result += *mhz - '0';
-		}
-
-	      ++mhz;
-	    }
-	}
-    }
-#endif
-
-  return result;
-}
diff --git a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
index 5903a909e3..23e7694d87 100644
--- a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
+++ b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
@@ -17,11 +17,90 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <stdint.h>
+#include <string.h>
+
 #include <libc-internal.h>
+#include <not-cancel.h>
+#include <libc-vdso.h>
 
 uint64_t
 __get_timebase_freq (void)
 {
-  return (uint64_t) __get_clockfreq ();
+  hp_timing_t result = 0L;
+
+#ifdef SHARED
+  /* The vDSO does not return an error (it clear cr0.so on returning).  */
+  INTERNAL_SYSCALL_DECL (err);
+  result =
+    INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, uint64_t, 0);
+#else
+  /* We read the information from the /proc filesystem.  /proc/cpuinfo
+     contains at least one line like:
+     timebase        : 33333333
+     We search for this line and convert the number into an integer.  */
+  int fd = __open_nocancel ("/proc/cpuinfo", O_RDONLY);
+  if (__glibc_likely (fd != -1))
+    return result;
+
+  /* The timebase will be in the 1st 1024 bytes for systems with up
+     to 8 processors.  If the first read returns less then 1024
+     bytes read,  we have the whole cpuinfo and can start the scan.
+     Otherwise we will have to read more to insure we have the
+     timebase value in the scan.  */
+  char buf[1024];
+  ssize_t n;
+
+  n = __read_nocancel (fd, buf, sizeof (buf));
+  if (n == sizeof (buf))
+    {
+      /* We are here because the 1st read returned exactly sizeof
+         (buf) bytes.  This implies that we are not at EOF and may
+         not have read the timebase value yet.  So we need to read
+         more bytes until we know we have EOF.  We copy the lower
+         half of buf to the upper half and read sizeof (buf)/2
+         bytes into the lower half of buf and repeat until we
+         reach EOF.  We can assume that the timebase will be in
+         the last 512 bytes of cpuinfo, so two 512 byte half_bufs
+         will be sufficient to contain the timebase and will
+         handle the case where the timebase spans the half_buf
+         boundry.  */
+      const ssize_t half_buf = sizeof (buf) / 2;
+      while (n >= half_buf)
+	{
+	  memcpy (buf, buf + half_buf, half_buf);
+	  n = __read_nocancel (fd, buf + half_buf, half_buf);
+	}
+      if (n >= 0)
+	n += half_buf;
+    }
+  __close_nocancel (fd);
+
+  if (__glibc_likely (n > 0))
+    {
+      char *mhz = memmem (buf, n, "timebase", 7);
+
+      if (__glibc_likely (mhz != NULL))
+	{
+	  char *endp = buf + n;
+
+	  /* Search for the beginning of the string.  */
+	  while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
+	    ++mhz;
+
+	  while (mhz < endp && *mhz != '\n')
+	    {
+	      if (*mhz >= '0' && *mhz <= '9')
+		{
+		  result *= 10;
+		  result += *mhz - '0';
+		}
+
+	      ++mhz;
+	    }
+	}
+    }
+#endif
+
+  return result;
 }
 weak_alias (__get_timebase_freq, __ppc_get_timebase_freq)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c b/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c
deleted file mode 100644
index 87853d6b6e..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/* Get frequency of the system processor.  sparc64 version.
-   Copyright (C) 2001-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 <ctype.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <sys/ioctl.h>
-#include <asm/openpromio.h>
-
-static hp_timing_t
-__get_clockfreq_via_cpuinfo (void)
-{
-  hp_timing_t result;
-  int fd;
-
-  result = 0;
-
-  fd = __open ("/proc/cpuinfo", O_RDONLY);
-  if (fd != -1)
-    {
-      char buf[8192];
-      ssize_t n;
-
-      n = __read (fd, buf, sizeof buf);
-      if (n > 0)
-	{
-	  char *mhz = memmem (buf, n, "Cpu0ClkTck", 7);
-
-	  if (mhz != NULL)
-	    {
-	      char *endp = buf + n;
-
-	      /* Search for the beginning of the string.  */
-	      while (mhz < endp
-		     && (*mhz < '0' || *mhz > '9')
-		     && (*mhz < 'a' || *mhz > 'f')
-		     && *mhz != '\n')
-		++mhz;
-
-	      while (mhz < endp && *mhz != '\n')
-		{
-		  if ((*mhz >= '0' && *mhz <= '9') ||
-		      (*mhz >= 'a' && *mhz <= 'f'))
-		    {
-		      result <<= 4;
-		      if (*mhz >= '0' && *mhz <= '9')
-			result += *mhz - '0';
-		      else
-			result += (*mhz - 'a') + 10;
-		    }
-		  ++mhz;
-		}
-	    }
-	}
-
-      __close (fd);
-    }
-
-  return result;
-}
-
-static hp_timing_t
-__get_clockfreq_via_proc_openprom (void)
-{
-  hp_timing_t result;
-  int obp_fd;
-
-  result = 0;
-
-  obp_fd = __open ("/proc/openprom", O_RDONLY);
-  if (obp_fd != -1)
-    {
-      unsigned long int buf[4096 / sizeof (unsigned long int)];
-      struct dirent64 *dirp = (struct dirent64 *) buf;
-      ssize_t len;
-
-      while ((len = __getdents64 (obp_fd, (char *) dirp, sizeof (buf))) > 0)
-	{
-	  struct dirent64 *this_dirp = dirp;
-
-	  while (len > 0)
-	    {
-	      char node[strlen ("/proc/openprom/")
-			+ _D_ALLOC_NAMLEN (this_dirp)
-			+ strlen ("/clock-frequency")];
-	      char *prop;
-	      int fd;
-
-	      /* Note that
-		   strlen("/clock-frequency") > strlen("/device_type")
-	      */
-	      __stpcpy (prop = __stpcpy (__stpcpy (node, "/proc/openprom/"),
-					 this_dirp->d_name),
-			"/device_type");
-	      fd = __open (node, O_RDONLY);
-	      if (fd != -1)
-		{
-		  char type_string[128];
-		  int ret;
-
-		  ret = __read (fd, type_string, sizeof (type_string));
-		  if (ret > 0 && strncmp (type_string, "'cpu'", 5) == 0)
-		    {
-		      int clkfreq_fd;
-
-		      __stpcpy (prop, "/clock-frequency");
-		      clkfreq_fd = __open (node, O_RDONLY);
-		      if (clkfreq_fd != -1)
-			{
-			  if (__read (clkfreq_fd, type_string,
-				      sizeof (type_string)) > 0)
-			    result = (hp_timing_t)
-			      strtoumax (type_string, NULL, 16);
-			  __close (clkfreq_fd);
-			}
-		    }
-		  __close (fd);
-		}
-
-	      if (result != 0)
-		break;
-
-	      len -= this_dirp->d_reclen;
-	      this_dirp = (struct dirent64 *)
-		((char *) this_dirp + this_dirp->d_reclen);
-	    }
-	  if (result != 0)
-	    break;
-	}
-      __close (obp_fd);
-    }
-
-  return result;
-}
-
-static void set_obp_int (struct openpromio *op, int val)
-{
-  char *cp = op->oprom_array;
-  int *ip = (int *) cp;
-
-  *ip = val;
-}
-
-static int get_obp_int (struct openpromio *op)
-{
-  char *cp = op->oprom_array;
-  int *ip = (int *) cp;
-
-  return *ip;
-}
-
-static hp_timing_t
-__get_clockfreq_via_dev_openprom (void)
-{
-  hp_timing_t result;
-  int obp_dev_fd;
-
-  result = 0;
-
-  obp_dev_fd = __open ("/dev/openprom", O_RDONLY);
-  if (obp_dev_fd != -1)
-    {
-      char obp_buf[8192];
-      struct openpromio *obp_cmd = (struct openpromio *)obp_buf;
-      int ret;
-
-      obp_cmd->oprom_size =
-	sizeof (obp_buf) - sizeof (unsigned int);
-      set_obp_int (obp_cmd, 0);
-      ret = __ioctl (obp_dev_fd, OPROMCHILD, (char *) obp_cmd);
-      if (ret == 0)
-	{
-	  int cur_node = get_obp_int (obp_cmd);
-
-	  while (cur_node != 0 && cur_node != -1)
-	    {
-	      obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int);
-	      strcpy (obp_cmd->oprom_array, "device_type");
-	      ret = __ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd);
-	      if (ret == 0
-		  && strncmp (obp_cmd->oprom_array, "cpu", 3) == 0)
-		{
-		  obp_cmd->oprom_size = (sizeof (obp_buf)
-					 - sizeof (unsigned int));
-		  strcpy (obp_cmd->oprom_array, "clock-frequency");
-		  ret = __ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd);
-		  if (ret == 0)
-		    result = (hp_timing_t) get_obp_int (obp_cmd);
-		}
-	      obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int);
-	      set_obp_int (obp_cmd, cur_node);
-	      ret = __ioctl (obp_dev_fd, OPROMNEXT, (char *) obp_cmd);
-	      if (ret < 0)
-		break;
-	      cur_node = get_obp_int (obp_cmd);
-	    }
-	}
-    }
-
-  return result;
-}
-
-hp_timing_t
-__get_clockfreq (void)
-{
-  static hp_timing_t result;
-
-  /* If this function was called before, we know the result.  */
-  if (result != 0)
-    return result;
-
-  /* We first read the information from the /proc/cpuinfo file.
-     It contains at least one line like
-	Cpu0ClkTick         : 000000002cb41780
-     We search for this line and convert the number in an integer.  */
-  result = __get_clockfreq_via_cpuinfo ();
-  if (result != 0)
-    return result;
-
-  /* If that did not work, try to find an OpenPROM node
-     with device_type equal to 'cpu' using /dev/openprom
-     and fetch the clock-frequency property from there.  */
-  result = __get_clockfreq_via_dev_openprom ();
-  if (result != 0)
-    return result;
-
-  /* Finally, try the same lookup as above but using /proc/openprom.  */
-  result = __get_clockfreq_via_proc_openprom ();
-
-  return result;
-}
-- 
2.17.1


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

* [PATCH v2 4/6] Do not use HP_TIMING_NOW for random bits
  2019-02-18 21:11 [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
  2019-02-18 21:11 ` [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID Adhemerval Zanella
  2019-02-18 21:11 ` [PATCH v2 3/6] Remove __get_clockfreq Adhemerval Zanella
@ 2019-02-18 21:11 ` Adhemerval Zanella
  2019-02-18 21:11 ` [PATCH v2 5/6] Refactor hp-timing rtld usage Adhemerval Zanella
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Adhemerval Zanella @ 2019-02-18 21:11 UTC (permalink / raw)
  To: libc-alpha

Changes from previous version:

  - Change random_bits return type to uint32_t and shuffle the bits
    internally to avoid clock bias.

---

This patch removes the HP_TIMING_BITS usage for fast random bits and replace
with clock_gettime (CLOCK_MONOTONIC).  It has unspecified starting time and
nano-second accuracy, so its randomness is significantly better than
gettimeofday.

Althoug it should incur in more overhead (specially for architecture that
support hp-timing), the symbol is also common implemented as a vDSO.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. I also
checked on a i686-gnu build.

	* include/random-bits.h: New file.
	* resolv/res_mkquery.c [HP_TIMING_AVAIL] (RANDOM_BITS,
	(__res_context_mkquery): Remove usage hp-timing usage and replace with
	random_bits.
	* resolv/res_send.c [HP_TIMING_AVAIL] (nameserver_offset): Likewise.
	* sysdeps/posix/tempname.c [HP_TIMING_AVAIL] (__gen_tempname):
	Likewise.
---
 include/random-bits.h    | 41 ++++++++++++++++++++++++++++++++++++++++
 resolv/res_mkquery.c     | 19 +++----------------
 resolv/res_send.c        | 12 ++----------
 sysdeps/posix/tempname.c | 19 +++----------------
 4 files changed, 49 insertions(+), 42 deletions(-)
 create mode 100644 include/random-bits.h

diff --git a/include/random-bits.h b/include/random-bits.h
new file mode 100644
index 0000000000..5ab53450af
--- /dev/null
+++ b/include/random-bits.h
@@ -0,0 +1,41 @@
+/* Fast pseudo-random bits based on clock_gettime.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _RANDOM_BITS_H
+# define _RANDOM_BITS_H
+
+#include <time.h>
+#include <stdint.h>
+
+/* Provides fast pseudo-random bits through clock_gettime.  It has unspecified
+   starting time, nano-second accuracy, its randomness is significantly better
+   than gettimeofday, and for mostly architectures it is implemented through
+   vDSO instead of a syscall.  Since the source is a system clock, the upper 
+   bits will have less entropy. */
+static inline uint32_t
+random_bits (void)
+{
+  struct timespec tv;
+  __clock_gettime (CLOCK_MONOTONIC, &tv);
+  /* Shuffle the lower bits to minimize the clock bias.  */
+  uint32_t ret = tv.tv_nsec ^ tv.tv_sec;
+  ret ^= (ret << 24) | (ret >> 8);
+  return ret;
+}
+
+#endif
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
index 19b8b402c4..dd43d347af 100644
--- a/resolv/res_mkquery.c
+++ b/resolv/res_mkquery.c
@@ -82,6 +82,7 @@
  * SOFTWARE.
  */
 
+#include <stdint.h>
 #include <sys/types.h>
 #include <sys/param.h>
 #include <netinet/in.h>
@@ -92,12 +93,7 @@
 #include <string.h>
 #include <sys/time.h>
 #include <shlib-compat.h>
-
-#include <hp-timing.h>
-#include <stdint.h>
-#if HP_TIMING_AVAIL
-# define RANDOM_BITS(Var) { uint64_t v64; HP_TIMING_NOW (v64); Var = v64; }
-#endif
+#include <random-bits.h>
 
 int
 __res_context_mkquery (struct resolv_context *ctx, int op, const char *dname,
@@ -120,16 +116,7 @@ __res_context_mkquery (struct resolv_context *ctx, int op, const char *dname,
   /* We randomize the IDs every time.  The old code just incremented
      by one after the initial randomization which still predictable if
      the application does multiple requests.  */
-  int randombits;
-#ifdef RANDOM_BITS
-  RANDOM_BITS (randombits);
-#else
-  struct timeval tv;
-  __gettimeofday (&tv, NULL);
-  randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
-#endif
-
-  hp->id = randombits;
+  hp->id = random_bits ();
   hp->opcode = op;
   hp->rd = (ctx->resp->options & RES_RECURSE) != 0;
   hp->rcode = NOERROR;
diff --git a/resolv/res_send.c b/resolv/res_send.c
index fa040c1198..1b59b6080c 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -109,7 +109,7 @@
 #include <unistd.h>
 #include <kernel-features.h>
 #include <libc-diag.h>
-#include <hp-timing.h>
+#include <random-bits.h>
 
 #if PACKETSZ > 65536
 #define MAXPACKET       PACKETSZ
@@ -309,15 +309,7 @@ nameserver_offset (struct __res_state *statp)
   if ((offset & 1) == 0)
     {
       /* Initialization is required.  */
-#if HP_TIMING_AVAIL
-      uint64_t ticks;
-      HP_TIMING_NOW (ticks);
-      offset = ticks;
-#else
-      struct timeval tv;
-      __gettimeofday (&tv, NULL);
-      offset = ((tv.tv_sec << 8) ^ tv.tv_usec);
-#endif
+      offset = random_bits ();
       /* The lowest bit is the most random.  Preserve it.  */
       offset <<= 1;
 
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index 2ed39d1a42..5217cb38e1 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -71,22 +71,8 @@
 #endif
 
 #ifdef _LIBC
-# include <hp-timing.h>
-# if HP_TIMING_AVAIL
-#  define RANDOM_BITS(Var) \
-  if (__glibc_unlikely (value == UINT64_C (0)))				      \
-    {									      \
-      /* If this is the first time this function is used initialize	      \
-	 the variable we accumulate the value in to some somewhat	      \
-	 random value.  If we'd not do this programs at startup time	      \
-	 might have a reduced set of possible names, at least on slow	      \
-	 machines.  */							      \
-      struct timeval tv;						      \
-      __gettimeofday (&tv, NULL);					      \
-      value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;		      \
-    }									      \
-  HP_TIMING_NOW (Var)
-# endif
+# include <random-bits.h>
+# define RANDOM_BITS(Var) ((Var) = random_bits ())
 #endif
 
 /* Use the widest available unsigned type if uint64_t is not
@@ -237,6 +223,7 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
   }
 #endif
   value += random_time_bits ^ __getpid ();
+  value += random_bits () ^ __getpid ();
 
   for (count = 0; count < attempts; value += 7777, ++count)
     {
-- 
2.17.1


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

* [PATCH v2 5/6] Refactor hp-timing rtld usage
  2019-02-18 21:11 [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2019-02-18 21:11 ` [PATCH v2 4/6] Do not use HP_TIMING_NOW for random bits Adhemerval Zanella
@ 2019-02-18 21:11 ` Adhemerval Zanella
  2019-02-18 21:11 ` [PATCH v2 6/6] Add generic hp-timing support Adhemerval Zanella
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Adhemerval Zanella @ 2019-02-18 21:11 UTC (permalink / raw)
  To: libc-alpha

Changes from previous version:

  - Add rtld_timer_start, rtld_timer_stop, and rtld_timer_accum to simplify
    the profiling timer calculation.  It allows remove the declaration of
    some temporary variables.

  - Simplify print_statistics and refactor HP_TIMING_PRINT to remove 'cycle'
    print.

---

This patch refactor how hp-timing is used on loader code for statistics
report.  The HP_TIMING_AVAIL and HP_SMALL_TIMING_AVAIL are removed and
HP_TIMING_INLINE is used instead to check for hp-timing avaliability.
For alpha, which only defines HP_SMALL_TIMING_AVAIL, the HP_TIMING_INLINE
is set iff for IS_IN(rtld).

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. I also
checked the builds for all afected ABIs.

	* benchtests/bench-timing.h: Replace HP_TIMING_AVAIL with
	HP_TIMING_INLINE.
	* nptl/descr.h: Likewise.
	* elf/rtld.c (RLTD_TIMING_DECLARE, RTLD_TIMING_NOW, RTLD_TIMING_DIFF,
	RTLD_TIMING_ACCUM_NT, RTLD_TIMING_SET): Define.
	(dl_start_final_info, _dl_start_final, dl_main, print_statistics):
	Abstract hp-timing usage with RTLD_* macros.
	* sysdeps/alpha/hp-timing.h (HP_TIMING_INLINE): Define iff IS_IN(rtld).
	(HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL): Remove.
	* sysdeps/generic/hp-timing.h (HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL,
	HP_TIMING_NONAVAIL): Likewise.
	* sysdeps/ia64/hp-timing.h (HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL):
	Likewise.
	* sysdeps/powerpc/powerpc32/power4/hp-timing.h (HP_TIMING_AVAIL,
	HP_SMALL_TIMING_AVAIL): Likewise.
	* sysdeps/powerpc/powerpc64/hp-timing.h (HP_TIMING_AVAIL,
	HP_SMALL_TIMING_AVAIL): Likewise.
	* sysdeps/sparc/sparc32/sparcv9/hp-timing.h (HP_TIMING_AVAIL,
	HP_SMALL_TIMING_AVAIL): Likewise.
	* sysdeps/sparc/sparc64/hp-timing.h (HP_TIMING_AVAIL,
	HP_SMALL_TIMING_AVAIL): Likewise.
	* sysdeps/x86/hp-timing.h (HP_TIMING_AVAIL, HP_SMALL_TIMING_AVAIL):
	Likewise.
	* sysdeps/generic/hp-timing-common.h: Update comment with
	HP_TIMING_AVAIL removal.
	(HP_TIMING_PRINT_SIZE): New define.
	(HP_TIMING_PRINT): Remove cycle printing.
---
 benchtests/bench-timing.h                    |   2 +-
 elf/rtld.c                                   | 281 +++++++++----------
 nptl/descr.h                                 |   2 +-
 sysdeps/alpha/hp-timing.h                    |  18 +-
 sysdeps/generic/hp-timing-common.h           |   8 +-
 sysdeps/generic/hp-timing.h                  |   5 -
 sysdeps/ia64/hp-timing.h                     |   4 -
 sysdeps/powerpc/powerpc32/power4/hp-timing.h |   4 -
 sysdeps/powerpc/powerpc64/hp-timing.h        |   4 -
 sysdeps/sparc/sparc32/sparcv9/hp-timing.h    |   2 -
 sysdeps/sparc/sparc64/hp-timing.h            |   2 -
 sysdeps/x86/hp-timing.h                      |   4 -
 12 files changed, 144 insertions(+), 192 deletions(-)

diff --git a/benchtests/bench-timing.h b/benchtests/bench-timing.h
index 41b7324527..93fe379f99 100644
--- a/benchtests/bench-timing.h
+++ b/benchtests/bench-timing.h
@@ -21,7 +21,7 @@
 #include <hp-timing.h>
 #include <stdint.h>
 
-#if HP_TIMING_AVAIL && !defined USE_CLOCK_GETTIME
+#if HP_TIMING_INLINE && !defined USE_CLOCK_GETTIME
 # define GL(x) _##x
 # define GLRO(x) _##x
 typedef hp_timing_t timing_t;
diff --git a/elf/rtld.c b/elf/rtld.c
index 1f124b31fc..18d30074ea 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -46,6 +46,49 @@
 
 #include <assert.h>
 
+/* Only enables rtld profiling for architectures which provides non generic
+   hp-timing support.  The generic support requires either syscall
+   (clock_gettime), which will incur in extra overhead  on loading time.
+   Using vDSO is also an option, but it will require extra support on loader
+   to setup the vDSO pointer before its usage.  */
+#if HP_TIMING_INLINE
+# define RLTD_TIMING_DECLARE(var, classifier,...) \
+  classifier hp_timing_t var __VA_ARGS__
+# define RTLD_TIMING_VAR(var)        RLTD_TIMING_DECLARE (var, )
+# define RTLD_TIMING_SET(var, value) (var) = (value)
+# define RTLD_TIMING_REF(var)        &(var)
+
+static inline void
+rtld_timer_start (hp_timing_t *var)
+{
+  HP_TIMING_NOW (*var);
+}
+
+static inline void
+rtld_timer_stop (hp_timing_t *var, hp_timing_t start)
+{
+  hp_timing_t stop;
+  HP_TIMING_NOW (stop);
+  HP_TIMING_DIFF (*var, start, stop);
+}
+
+static inline void
+rtld_timer_accum (hp_timing_t *sum, hp_timing_t start)
+{
+  hp_timing_t stop;
+  rtld_timer_stop (&stop, start);
+  HP_TIMING_ACCUM_NT(*sum, stop);
+}
+#else
+# define RLTD_TIMING_DECLARE(var, classifier...)
+# define RTLD_TIMING_SET(var, value)
+# define RTLD_TIMING_VAR(var)
+# define RTLD_TIMING_REF(var)			 0
+# define rtld_timer_start(var)
+# define rtld_timer_stop(var, start)
+# define rtld_timer_accum(sum, start)
+#endif
+
 /* Avoid PLT use for our local calls at startup.  */
 extern __typeof (__mempcpy) __mempcpy attribute_hidden;
 
@@ -62,7 +105,7 @@ static void print_missing_version (int errcode, const char *objname,
 				   const char *errsting);
 
 /* Print the various times we collected.  */
-static void print_statistics (hp_timing_t *total_timep);
+static void print_statistics (const hp_timing_t *total_timep);
 
 /* Add audit objects.  */
 static void process_dl_audit (char *str);
@@ -303,11 +346,9 @@ static struct libname_list _dl_rtld_libname;
 static struct libname_list _dl_rtld_libname2;
 
 /* Variable for statistics.  */
-#ifndef HP_TIMING_NONAVAIL
-static hp_timing_t relocate_time;
-static hp_timing_t load_time attribute_relro;
-static hp_timing_t start_time attribute_relro;
-#endif
+RLTD_TIMING_DECLARE (relocate_time, static);
+RLTD_TIMING_DECLARE (load_time,     static, attribute_relro);
+RLTD_TIMING_DECLARE (start_time,    static, attribute_relro);
 
 /* Additional definitions needed by TLS initialization.  */
 #ifdef TLS_INIT_HELPER
@@ -335,9 +376,7 @@ static ElfW(Addr) _dl_start_final (void *arg);
 struct dl_start_final_info
 {
   struct link_map l;
-#if !defined HP_TIMING_NONAVAIL && HP_TIMING_INLINE
-  hp_timing_t start_time;
-#endif
+  RTLD_TIMING_VAR (start_time);
 };
 static ElfW(Addr) _dl_start_final (void *arg,
 				   struct dl_start_final_info *info);
@@ -371,16 +410,11 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
 {
   ElfW(Addr) start_addr;
 
-  if (HP_SMALL_TIMING_AVAIL)
-    {
-      /* If it hasn't happen yet record the startup time.  */
-      if (! HP_TIMING_INLINE)
-	HP_TIMING_NOW (start_time);
-#if !defined DONT_USE_BOOTSTRAP_MAP && !defined HP_TIMING_NONAVAIL
-      else
-	start_time = info->start_time;
+  /* If it hasn't happen yet record the startup time.  */
+  rtld_timer_start (&start_time);
+#if !defined DONT_USE_BOOTSTRAP_MAP
+  RTLD_TIMING_SET (start_time, info->start_time);
 #endif
-    }
 
   /* Transfer data about ourselves to the permanent link_map structure.  */
 #ifndef DONT_USE_BOOTSTRAP_MAP
@@ -412,27 +446,11 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
      entry point on the same stack we entered on.  */
   start_addr = _dl_sysdep_start (arg, &dl_main);
 
-#ifndef HP_TIMING_NONAVAIL
-  hp_timing_t rtld_total_time;
-  if (HP_SMALL_TIMING_AVAIL)
-    {
-      hp_timing_t end_time;
-
-      /* Get the current time.  */
-      HP_TIMING_NOW (end_time);
-
-      /* Compute the difference.  */
-      HP_TIMING_DIFF (rtld_total_time, start_time, end_time);
-    }
-#endif
-
   if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
     {
-#ifndef HP_TIMING_NONAVAIL
-      print_statistics (&rtld_total_time);
-#else
-      print_statistics (NULL);
-#endif
+      RTLD_TIMING_VAR (rtld_total_time);
+      rtld_timer_stop (&rtld_total_time, start_time);
+      print_statistics (RTLD_TIMING_REF(rtld_total_time));
     }
 
   return start_addr;
@@ -457,11 +475,10 @@ _dl_start (void *arg)
 #define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
 #include "dynamic-link.h"
 
-  if (HP_TIMING_INLINE && HP_SMALL_TIMING_AVAIL)
 #ifdef DONT_USE_BOOTSTRAP_MAP
-    HP_TIMING_NOW (start_time);
+  rtld_timer_start (&start_time);
 #else
-    HP_TIMING_NOW (info.start_time);
+  rtld_timer_start (&info.start_time);
 #endif
 
   /* Partly clean the `bootstrap_map' structure up.  Don't use
@@ -1078,11 +1095,6 @@ dl_main (const ElfW(Phdr) *phdr,
   unsigned int i;
   bool prelinked = false;
   bool rtld_is_main = false;
-#ifndef HP_TIMING_NONAVAIL
-  hp_timing_t start;
-  hp_timing_t stop;
-  hp_timing_t diff;
-#endif
   void *tcbp = NULL;
 
   GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
@@ -1258,12 +1270,11 @@ of this helper program; chances are you did not intend to run this program.\n\
 	}
       else
 	{
-	  HP_TIMING_NOW (start);
+	  RTLD_TIMING_VAR (start);
+	  rtld_timer_start (&start);
 	  _dl_map_object (NULL, rtld_progname, lt_executable, 0,
 			  __RTLD_OPENEXEC, LM_ID_BASE);
-	  HP_TIMING_NOW (stop);
-
-	  HP_TIMING_DIFF (load_time, start, stop);
+	  rtld_timer_stop (&load_time, start);
 	}
 
       /* Now the map for the main executable is available.  */
@@ -1666,20 +1677,18 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
 
   if (__glibc_unlikely (preloadlist != NULL))
     {
-      HP_TIMING_NOW (start);
+      RTLD_TIMING_VAR (start);
+      rtld_timer_start (&start);
       npreloads += handle_preload_list (preloadlist, main_map, "LD_PRELOAD");
-      HP_TIMING_NOW (stop);
-      HP_TIMING_DIFF (diff, start, stop);
-      HP_TIMING_ACCUM_NT (load_time, diff);
+      rtld_timer_accum (&load_time, start);
     }
 
   if (__glibc_unlikely (preloadarg != NULL))
     {
-      HP_TIMING_NOW (start);
+      RTLD_TIMING_VAR (start);
+      rtld_timer_start (&start);
       npreloads += handle_preload_list (preloadarg, main_map, "--preload");
-      HP_TIMING_NOW (stop);
-      HP_TIMING_DIFF (diff, start, stop);
-      HP_TIMING_ACCUM_NT (load_time, diff);
+      rtld_timer_accum (&load_time, start);
     }
 
   /* There usually is no ld.so.preload file, it should only be used
@@ -1739,7 +1748,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
 	      file[file_size - 1] = '\0';
 	    }
 
-	  HP_TIMING_NOW (start);
+	  RTLD_TIMING_VAR (start);
+	  rtld_timer_start (&start);
 
 	  if (file != problem)
 	    {
@@ -1757,9 +1767,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
 	      npreloads += do_preload (p, main_map, preload_file);
 	    }
 
-	  HP_TIMING_NOW (stop);
-	  HP_TIMING_DIFF (diff, start, stop);
-	  HP_TIMING_ACCUM_NT (load_time, diff);
+	  rtld_timer_accum (&load_time, start);
 
 	  /* We don't need the file anymore.  */
 	  __munmap (file, file_size);
@@ -1783,11 +1791,12 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
   /* Load all the libraries specified by DT_NEEDED entries.  If LD_PRELOAD
      specified some libraries to load, these are inserted before the actual
      dependencies in the executable's searchlist for symbol resolution.  */
-  HP_TIMING_NOW (start);
-  _dl_map_object_deps (main_map, preloads, npreloads, mode == trace, 0);
-  HP_TIMING_NOW (stop);
-  HP_TIMING_DIFF (diff, start, stop);
-  HP_TIMING_ACCUM_NT (load_time, diff);
+  {
+    RTLD_TIMING_VAR (start);
+    rtld_timer_start (&start);
+    _dl_map_object_deps (main_map, preloads, npreloads, mode == trace, 0);
+    rtld_timer_accum (&load_time, start);
+  }
 
   /* Mark all objects as being in the global scope.  */
   for (i = main_map->l_searchlist.r_nlist; i > 0; )
@@ -2180,12 +2189,10 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
       if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL)
 	{
 	  ElfW(Rela) *conflict, *conflictend;
-#ifndef HP_TIMING_NONAVAIL
-	  hp_timing_t start;
-	  hp_timing_t stop;
-#endif
 
-	  HP_TIMING_NOW (start);
+	  RTLD_TIMING_VAR (start);
+	  rtld_timer_start (&start);
+
 	  assert (main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL);
 	  conflict = (ElfW(Rela) *)
 	    main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr;
@@ -2193,8 +2200,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
 	    ((char *) conflict
 	     + main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val);
 	  _dl_resolve_conflicts (main_map, conflict, conflictend);
-	  HP_TIMING_NOW (stop);
-	  HP_TIMING_DIFF (relocate_time, start, stop);
+
+	  rtld_timer_stop (&relocate_time, start);
 	}
 
 
@@ -2222,15 +2229,12 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
 	 know that because it is self-contained).  */
 
       int consider_profiling = GLRO(dl_profile) != NULL;
-#ifndef HP_TIMING_NONAVAIL
-      hp_timing_t start;
-      hp_timing_t stop;
-#endif
 
       /* If we are profiling we also must do lazy reloaction.  */
       GLRO(dl_lazy) |= consider_profiling;
 
-      HP_TIMING_NOW (start);
+      RTLD_TIMING_VAR (start);
+      rtld_timer_start (&start);
       unsigned i = main_map->l_searchlist.r_nlist;
       while (i-- > 0)
 	{
@@ -2257,9 +2261,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
 	  if (l->l_tls_blocksize != 0 && tls_init_tp_called)
 	    _dl_add_to_slotinfo (l);
 	}
-      HP_TIMING_NOW (stop);
-
-      HP_TIMING_DIFF (relocate_time, start, stop);
+      rtld_timer_stop (&relocate_time, start);
 
       /* Now enable profiling if needed.  Like the previous call,
 	 this has to go here because the calls it makes should use the
@@ -2302,19 +2304,14 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
 	 re-relocation, we might call a user-supplied function
 	 (e.g. calloc from _dl_relocate_object) that uses TLS data.  */
 
-#ifndef HP_TIMING_NONAVAIL
-      hp_timing_t start;
-      hp_timing_t stop;
-      hp_timing_t add;
-#endif
+      RTLD_TIMING_VAR (start);
+      rtld_timer_start (&start);
 
-      HP_TIMING_NOW (start);
       /* Mark the link map as not yet relocated again.  */
       GL(dl_rtld_map).l_relocated = 0;
       _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
-      HP_TIMING_NOW (stop);
-      HP_TIMING_DIFF (add, start, stop);
-      HP_TIMING_ACCUM_NT (relocate_time, add);
+
+      rtld_timer_accum (&relocate_time, start);
     }
 
   /* Do any necessary cleanups for the startup OS interface code.
@@ -2746,46 +2743,51 @@ process_envvars (enum mode *modep)
     }
 }
 
+#if HP_TIMING_INLINE
+static void
+print_statistics_item (const char *title, hp_timing_t time,
+		       hp_timing_t total)
+{
+  char cycles[HP_TIMING_PRINT_SIZE];
+  HP_TIMING_PRINT (cycles, sizeof (cycles), time);
+
+  char relative[3 * sizeof (hp_timing_t) + 2];
+  char *cp = _itoa ((1000ULL * time) / total, relative + sizeof (relative),
+		    10, 0);
+  /* Sets the decimal point.  */
+  char *wp = relative;
+  switch (relative + sizeof (relative) - cp)
+    {
+    case 3:
+      *wp++ = *cp++;
+      /* Fall through.  */
+    case 2:
+      *wp++ = *cp++;
+      /* Fall through.  */
+    case 1:
+      *wp++ = '.';
+      *wp++ = *cp++;
+    }
+  *wp = '\0';
+  _dl_debug_printf ("%s: %s cycles (%s%%)\n", title, cycles, relative);
+}
+#endif
 
 /* Print the various times we collected.  */
 static void
 __attribute ((noinline))
-print_statistics (hp_timing_t *rtld_total_timep)
+print_statistics (const hp_timing_t *rtld_total_timep)
 {
-#ifndef HP_TIMING_NONAVAIL
-  char buf[200];
-  char *cp;
-  char *wp;
-
-  /* Total time rtld used.  */
-  if (HP_SMALL_TIMING_AVAIL)
-    {
-      HP_TIMING_PRINT (buf, sizeof (buf), *rtld_total_timep);
-      _dl_debug_printf ("\nruntime linker statistics:\n"
-			"  total startup time in dynamic loader: %s\n", buf);
-
-      /* Print relocation statistics.  */
-      char pbuf[30];
-      HP_TIMING_PRINT (buf, sizeof (buf), relocate_time);
-      cp = _itoa ((1000ULL * relocate_time) / *rtld_total_timep,
-		  pbuf + sizeof (pbuf), 10, 0);
-      wp = pbuf;
-      switch (pbuf + sizeof (pbuf) - cp)
-	{
-	case 3:
-	  *wp++ = *cp++;
-	  /* Fall through.  */
-	case 2:
-	  *wp++ = *cp++;
-	  /* Fall through.  */
-	case 1:
-	  *wp++ = '.';
-	  *wp++ = *cp++;
-	}
-      *wp = '\0';
-      _dl_debug_printf ("\
-	    time needed for relocation: %s (%s%%)\n", buf, pbuf);
-    }
+#if HP_TIMING_INLINE
+  {
+    char cycles[HP_TIMING_PRINT_SIZE];
+    HP_TIMING_PRINT (cycles, sizeof (cycles), *rtld_total_timep);
+    _dl_debug_printf ("\nruntime linker statistics:\n"
+		      "  total startup time in dynamic loader: %s cycles\n",
+		      cycles);
+    print_statistics_item ("            time needed for relocation",
+			   relocate_time, *rtld_total_timep);
+  }
 #endif
 
   unsigned long int num_relative_relocations = 0;
@@ -2826,31 +2828,8 @@ print_statistics (hp_timing_t *rtld_total_timep)
 		    GL(dl_num_cache_relocations),
 		    num_relative_relocations);
 
-#ifndef HP_TIMING_NONAVAIL
-  /* Time spend while loading the object and the dependencies.  */
-  if (HP_SMALL_TIMING_AVAIL)
-    {
-      char pbuf[30];
-      HP_TIMING_PRINT (buf, sizeof (buf), load_time);
-      cp = _itoa ((1000ULL * load_time) / *rtld_total_timep,
-		  pbuf + sizeof (pbuf), 10, 0);
-      wp = pbuf;
-      switch (pbuf + sizeof (pbuf) - cp)
-	{
-	case 3:
-	  *wp++ = *cp++;
-	  /* Fall through.  */
-	case 2:
-	  *wp++ = *cp++;
-	  /* Fall through.  */
-	case 1:
-	  *wp++ = '.';
-	  *wp++ = *cp++;
-	}
-      *wp = '\0';
-      _dl_debug_printf ("\
-	   time needed to load objects: %s (%s%%)\n",
-				buf, pbuf);
-    }
+#if HP_TIMING_INLINE
+  print_statistics_item ("           time needed to load objects",
+			 load_time, *rtld_total_timep);
 #endif
 }
diff --git a/nptl/descr.h b/nptl/descr.h
index cb7d4c2282..b4db99fe3f 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -342,7 +342,7 @@ struct pthread
   /* Lock for synchronizing setxid calls.  */
   unsigned int setxid_futex;
 
-#if HP_TIMING_AVAIL
+#if HP_TIMING_INLINE
   hp_timing_t cpuclock_offset_ununsed;
 #endif
 
diff --git a/sysdeps/alpha/hp-timing.h b/sysdeps/alpha/hp-timing.h
index 481132663c..08d8d6627c 100644
--- a/sysdeps/alpha/hp-timing.h
+++ b/sysdeps/alpha/hp-timing.h
@@ -17,16 +17,13 @@
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifndef _HP_TIMING_H
-#define _HP_TIMING_H	1
+#ifndef _HP_TIMING_ALPHA_H
+#define _HP_TIMING_ALPHA_H	1
 
+#if IS_IN(rtld)
 /* We always have the timestamp register, but it's got only a 4 second
    range.  Use it for ld.so profiling only.  */
-#define HP_TIMING_AVAIL		(0)
-#define HP_SMALL_TIMING_AVAIL	(1)
-
-/* We indeed have inlined functions.  */
-#define HP_TIMING_INLINE	(1)
+# define HP_TIMING_INLINE	(1)
 
 /* We use 32 bit values for the times.  */
 typedef unsigned int hp_timing_t;
@@ -34,13 +31,16 @@ typedef unsigned int hp_timing_t;
 /* The "rpcc" instruction returns a 32-bit counting half and a 32-bit
    "virtual cycle counter displacement".  Subtracting the two gives us
    a virtual cycle count.  */
-#define HP_TIMING_NOW(VAR) \
+# define HP_TIMING_NOW(VAR) \
   do {									      \
     unsigned long int x_;						      \
     asm volatile ("rpcc %0" : "=r"(x_));				      \
     (VAR) = (int) (x_) - (int) (x_ >> 32);				      \
   } while (0)
+# include <hp-timing-common.h>
 
-#include <hp-timing-common.h>
+#else
+# include <sysdeps/generic/hp-timing.h>
+#endif /* IS_IN(rtld)  */
 
 #endif	/* hp-timing.h */
diff --git a/sysdeps/generic/hp-timing-common.h b/sysdeps/generic/hp-timing-common.h
index 0ffb853444..8749d25647 100644
--- a/sysdeps/generic/hp-timing-common.h
+++ b/sysdeps/generic/hp-timing-common.h
@@ -20,8 +20,6 @@
 /* In case a platform supports timers in the hardware the following macros
    and types must be defined:
 
-   - HP_TIMING_AVAIL: test for availability.
-
    - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
      implemented using function calls but instead uses some inlined code
      which might simply consist of a few assembler instructions.  We have to
@@ -47,16 +45,16 @@
 /* Accumulate ADD into SUM.  No attempt is made to be thread-safe.  */
 #define HP_TIMING_ACCUM_NT(Sum, Diff)		((Sum) += (Diff))
 
+#define HP_TIMING_PRINT_SIZE (3 * sizeof (hp_timing_t) + 1)
+
 /* Write a decimal representation of the timing value into the given string.  */
 #define HP_TIMING_PRINT(Dest, Len, Val) 				\
   do {									\
-    char __buf[20];							\
+    char __buf[HP_TIMING_PRINT_SIZE];					\
     char *__dest = (Dest);						\
     size_t __len = (Len);						\
     char *__cp = _itoa ((Val), __buf + sizeof (__buf), 10, 0);		\
     size_t __cp_len = MIN (__buf + sizeof (__buf) - __cp, __len);	\
     memcpy (__dest, __cp, __cp_len);					\
-    memcpy (__dest + __cp_len, " cycles",				\
-	    MIN (__len - __cp_len, sizeof (" cycles")));		\
     __dest[__len - 1] = '\0';						\
   } while (0)
diff --git a/sysdeps/generic/hp-timing.h b/sysdeps/generic/hp-timing.h
index fb2a6036fc..278998d2c2 100644
--- a/sysdeps/generic/hp-timing.h
+++ b/sysdeps/generic/hp-timing.h
@@ -25,8 +25,6 @@
    the system call might be too high.  */
 
 /* Provide dummy definitions.  */
-#define HP_TIMING_AVAIL		(0)
-#define HP_SMALL_TIMING_AVAIL	(0)
 #define HP_TIMING_INLINE	(0)
 typedef int hp_timing_t;
 #define HP_TIMING_NOW(var)
@@ -34,7 +32,4 @@ typedef int hp_timing_t;
 #define HP_TIMING_ACCUM_NT(Sum, Diff)
 #define HP_TIMING_PRINT(Buf, Len, Val)
 
-/* Since this implementation is not available we tell the user about it.  */
-#define HP_TIMING_NONAVAIL	1
-
 #endif	/* hp-timing.h */
diff --git a/sysdeps/ia64/hp-timing.h b/sysdeps/ia64/hp-timing.h
index 17ef023a11..2ca248a530 100644
--- a/sysdeps/ia64/hp-timing.h
+++ b/sysdeps/ia64/hp-timing.h
@@ -20,10 +20,6 @@
 #ifndef _HP_TIMING_H
 #define _HP_TIMING_H	1
 
-/* We always assume having the timestamp register.  */
-#define HP_TIMING_AVAIL		(1)
-#define HP_SMALL_TIMING_AVAIL	(1)
-
 /* We indeed have inlined functions.  */
 #define HP_TIMING_INLINE	(1)
 
diff --git a/sysdeps/powerpc/powerpc32/power4/hp-timing.h b/sysdeps/powerpc/powerpc32/power4/hp-timing.h
index 0d77aa0992..ed2ca9bc7a 100644
--- a/sysdeps/powerpc/powerpc32/power4/hp-timing.h
+++ b/sysdeps/powerpc/powerpc32/power4/hp-timing.h
@@ -20,10 +20,6 @@
 #ifndef _HP_TIMING_H
 #define _HP_TIMING_H	1
 
-/* We always assume having the timestamp register.  */
-#define HP_TIMING_AVAIL		(1)
-#define HP_SMALL_TIMING_AVAIL	(1)
-
 /* We indeed have inlined functions.  */
 #define HP_TIMING_INLINE	(1)
 
diff --git a/sysdeps/powerpc/powerpc64/hp-timing.h b/sysdeps/powerpc/powerpc64/hp-timing.h
index fb9ac1ce2a..01678cd634 100644
--- a/sysdeps/powerpc/powerpc64/hp-timing.h
+++ b/sysdeps/powerpc/powerpc64/hp-timing.h
@@ -20,10 +20,6 @@
 #ifndef _HP_TIMING_H
 #define _HP_TIMING_H	1
 
-/* We always assume having the timestamp register.  */
-#define HP_TIMING_AVAIL		(1)
-#define HP_SMALL_TIMING_AVAIL	(1)
-
 /* We indeed have inlined functions.  */
 #define HP_TIMING_INLINE	(1)
 
diff --git a/sysdeps/sparc/sparc32/sparcv9/hp-timing.h b/sysdeps/sparc/sparc32/sparcv9/hp-timing.h
index 6a4ab08679..3270c5b40a 100644
--- a/sysdeps/sparc/sparc32/sparcv9/hp-timing.h
+++ b/sysdeps/sparc/sparc32/sparcv9/hp-timing.h
@@ -20,8 +20,6 @@
 #ifndef _HP_TIMING_H
 #define _HP_TIMING_H	1
 
-#define HP_TIMING_AVAIL		(1)
-#define HP_SMALL_TIMING_AVAIL	(1)
 #define HP_TIMING_INLINE	(1)
 
 typedef unsigned long long int hp_timing_t;
diff --git a/sysdeps/sparc/sparc64/hp-timing.h b/sysdeps/sparc/sparc64/hp-timing.h
index db95c02a8d..0f02b2a98f 100644
--- a/sysdeps/sparc/sparc64/hp-timing.h
+++ b/sysdeps/sparc/sparc64/hp-timing.h
@@ -20,8 +20,6 @@
 #ifndef _HP_TIMING_H
 #define _HP_TIMING_H	1
 
-#define HP_TIMING_AVAIL		(1)
-#define HP_SMALL_TIMING_AVAIL	(1)
 #define HP_TIMING_INLINE	(1)
 
 typedef unsigned long int hp_timing_t;
diff --git a/sysdeps/x86/hp-timing.h b/sysdeps/x86/hp-timing.h
index 9b6a998bcd..ccb9f9250a 100644
--- a/sysdeps/x86/hp-timing.h
+++ b/sysdeps/x86/hp-timing.h
@@ -22,10 +22,6 @@
 #include <isa.h>
 
 #if MINIMUM_ISA == 686 || MINIMUM_ISA == 8664
-/* We always assume having the timestamp register.  */
-# define HP_TIMING_AVAIL	(1)
-# define HP_SMALL_TIMING_AVAIL	(1)
-
 /* We indeed have inlined functions.  */
 # define HP_TIMING_INLINE	(1)
 
-- 
2.17.1


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

* [PATCH v2 6/6] Add generic hp-timing support
  2019-02-18 21:11 [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2019-02-18 21:11 ` [PATCH v2 5/6] Refactor hp-timing rtld usage Adhemerval Zanella
@ 2019-02-18 21:11 ` Adhemerval Zanella
  2019-03-19 17:23 ` [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
  2019-03-20 11:32 ` Andreas Schwab
  6 siblings, 0 replies; 14+ messages in thread
From: Adhemerval Zanella @ 2019-02-18 21:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: Wilco Dijkstra

From: Wilco Dijkstra <Wilco.Dijkstra@arm.com>

Add missing generic hp_timing support.  It uses clock_gettime (CLOCK_MONOTONIC)
which has unspecified starting time, nano-second accuracy, and should faster on
architectures that implementes the symbol as vDSO.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. I also
checked the builds for all afected ABIs.

	* benchtests/Makefile (USE_CLOCK_GETTIME) Remove.
	* benchtests/README: Update description.
	* benchtests/bench-timing.h: Default to hp-timing.
	* sysdeps/generic/hp-timing.h (HP_TIMING_DIFF, HP_TIMING_ACCUM_NT,
	HP_TIMING_PRINT): Remove.
	(HP_TIMING_NOW): Add generic implementation.
	(hp_timing_t): Change to uint64_t.
---
 benchtests/Makefile         |  6 -----
 benchtests/README           |  7 +-----
 benchtests/bench-timing.h   | 44 +++++++------------------------------
 sysdeps/generic/hp-timing.h | 25 +++++++++++++--------
 4 files changed, 25 insertions(+), 57 deletions(-)

diff --git a/benchtests/Makefile b/benchtests/Makefile
index d00993eca4..cdc89488d6 100644
--- a/benchtests/Makefile
+++ b/benchtests/Makefile
@@ -127,17 +127,11 @@ endif
 
 CPPFLAGS-nonlib += -DDURATION=$(BENCH_DURATION) -D_ISOMAC
 
-# Use clock_gettime to measure performance of functions.  The default is to use
-# HP_TIMING if it is available.
-ifdef USE_CLOCK_GETTIME
-CPPFLAGS-nonlib += -DUSE_CLOCK_GETTIME
-else
 # On x86 processors, use RDTSCP, instead of RDTSC, to measure performance
 # of functions.  All x86 processors since 2010 support RDTSCP instruction.
 ifdef USE_RDTSCP
 CPPFLAGS-nonlib += -DUSE_RDTSCP
 endif
-endif
 
 DETAILED_OPT :=
 
diff --git a/benchtests/README b/benchtests/README
index aaf0b659e2..c4f03fd872 100644
--- a/benchtests/README
+++ b/benchtests/README
@@ -27,12 +27,7 @@ BENCH_DURATION.
 
 The benchmark suite does function call measurements using architecture-specific
 high precision timing instructions whenever available.  When such support is
-not available, it uses clock_gettime (CLOCK_PROCESS_CPUTIME_ID).  One can force
-the benchmark to use clock_gettime by invoking make as follows:
-
-  $ make USE_CLOCK_GETTIME=1 bench
-
-Again, one must run `make bench-clean' before changing the measurement method.
+not available, it uses clock_gettime (CLOCK_MONOTONIC).
 
 On x86 processors, RDTSCP instruction provides more precise timing data
 than RDTSC instruction.  All x86 processors since 2010 support RDTSCP
diff --git a/benchtests/bench-timing.h b/benchtests/bench-timing.h
index 93fe379f99..e213dec3fd 100644
--- a/benchtests/bench-timing.h
+++ b/benchtests/bench-timing.h
@@ -18,49 +18,21 @@
 
 #undef attribute_hidden
 #define attribute_hidden
+#define __clock_gettime clock_gettime
 #include <hp-timing.h>
 #include <stdint.h>
 
-#if HP_TIMING_INLINE && !defined USE_CLOCK_GETTIME
-# define GL(x) _##x
-# define GLRO(x) _##x
+#define GL(x) _##x
+#define GLRO(x) _##x
 typedef hp_timing_t timing_t;
 
-# define TIMING_TYPE "hp_timing"
+#define TIMING_TYPE "hp_timing"
 
-# define TIMING_INIT(res) ({ (res) = 1; })
+#define TIMING_INIT(res) ({ (res) = 1; })
 
-# define TIMING_NOW(var) HP_TIMING_NOW (var)
-# define TIMING_DIFF(diff, start, end) HP_TIMING_DIFF ((diff), (start), (end))
-# define TIMING_ACCUM(sum, diff) HP_TIMING_ACCUM_NT ((sum), (diff))
-
-#else
-
-#include <time.h>
-typedef uint64_t timing_t;
-
-# define TIMING_TYPE "clock_gettime"
-
-/* Measure the resolution of the clock so we can scale the number of
-   benchmark iterations by this value.  */
-# define TIMING_INIT(res) \
-({									      \
-  struct timespec start;						      \
-  clock_getres (CLOCK_PROCESS_CPUTIME_ID, &start);			      \
-  (res) = start.tv_nsec;					      \
-})
-
-# define TIMING_NOW(var) \
-({									      \
-  struct timespec tv;							      \
-  clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &tv);			      \
-  (var) = (uint64_t) (tv.tv_nsec + (uint64_t) 1000000000 * tv.tv_sec);	      \
-})
-
-# define TIMING_DIFF(diff, start, end) (diff) = (end) - (start)
-# define TIMING_ACCUM(sum, diff) (sum) += (diff)
-
-#endif
+#define TIMING_NOW(var) HP_TIMING_NOW (var)
+#define TIMING_DIFF(diff, start, end) HP_TIMING_DIFF ((diff), (start), (end))
+#define TIMING_ACCUM(sum, diff) HP_TIMING_ACCUM_NT ((sum), (diff))
 
 #define TIMING_PRINT_MEAN(d_total_s, d_iters) \
   printf ("\t%g", (d_total_s) / (d_iters))
diff --git a/sysdeps/generic/hp-timing.h b/sysdeps/generic/hp-timing.h
index 278998d2c2..2528279558 100644
--- a/sysdeps/generic/hp-timing.h
+++ b/sysdeps/generic/hp-timing.h
@@ -20,16 +20,23 @@
 #ifndef _HP_TIMING_H
 #define _HP_TIMING_H	1
 
-/* There are no generic definitions for the times.  We could write something
-   using the `gettimeofday' system call where available but the overhead of
-   the system call might be too high.  */
+#include <time.h>
+#include <stdint.h>
+#include <hp-timing-common.h>
 
-/* Provide dummy definitions.  */
+/* It should not be used for ld.so.  */
 #define HP_TIMING_INLINE	(0)
-typedef int hp_timing_t;
-#define HP_TIMING_NOW(var)
-#define HP_TIMING_DIFF(Diff, Start, End)
-#define HP_TIMING_ACCUM_NT(Sum, Diff)
-#define HP_TIMING_PRINT(Buf, Len, Val)
+
+typedef uint64_t hp_timing_t;
+
+/* The clock_gettime (CLOCK_MONOTONIC) has unspecified starting time,
+   nano-second accuracy, and for some architectues is implemented as
+   vDSO symbol.  */
+#define HP_TIMING_NOW(var) \
+({								\
+  struct timespec tv;						\
+  __clock_gettime (CLOCK_MONOTONIC, &tv);			\
+  (var) = (tv.tv_nsec + UINT64_C(1000000000) * tv.tv_sec);	\
+})
 
 #endif	/* hp-timing.h */
-- 
2.17.1


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

* Re: [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime
  2019-02-18 21:11 [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
                   ` (4 preceding siblings ...)
  2019-02-18 21:11 ` [PATCH v2 6/6] Add generic hp-timing support Adhemerval Zanella
@ 2019-03-19 17:23 ` Adhemerval Zanella
  2019-03-20 11:32 ` Andreas Schwab
  6 siblings, 0 replies; 14+ messages in thread
From: Adhemerval Zanella @ 2019-03-19 17:23 UTC (permalink / raw)
  To: libc-alpha

Ping.

On 18/02/2019 18:11, Adhemerval Zanella wrote:
> This patch removes CLOCK_THREAD_CPUTIME_ID and CLOCK_PROCESS_CPUTIME_ID support
> from clock_gettime and clock_settime generic implementation.  For Linux, kernel
> already provides supports through the syscall and Hurd HTL lacks
> __pthread_clock_gettime and __pthread_clock_settime internal implementation.
> 
> As described in clock_gettime man-page [1] on 'Historical note for SMP
> system', implementing CLOCK_{THREAD,PROCESS}_CPUTIME_ID with timer registers
> is error-prone and susceptible to timing and accurary issues that the libc
> can not deal without kernel support.
> 
> This allows removes unused code which, however, still incur in some runtime
> overhead in thread creation (the struct pthread cpuclock_offset
> initialization).
> 
> If hurd eventually wants to support them it should either either implement as
> a kernel facility (or something related due its architecture) or in system
> specific implementation.
> 
> Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu. I also
> checked on a i686-gnu build.
> 
> 	* nptl/Makefile (libpthread-routines): Remove pthread_clock_gettime and
> 	pthread_clock_settime.
> 	* nptl/pthreadP.h (__find_thread_by_id): Remove prototype.
> 	* elf/dl-support.c [!HP_TIMING_NOAVAIL] (_dl_cpuclock_offset): Remove.
> 	(_dl_non_dynamic_init): Remove _dl_cpuclock_offset setting.
> 	* elf/rtld.c (_dl_start_final): Likewise.
> 	* nptl/allocatestack.c (__find_thread_by_id): Remove function.
> 	* sysdeps/generic/ldsodefs.h [!HP_TIMING_NOAVAIL] (_dl_cpuclock_offset):
> 	Remove.
> 	* sysdeps/mach/hurd/dl-sysdep.c [!HP_TIMING_NOAVAIL]
> 	(_dl_cpuclock_offset): Remove.
> 	* nptl/descr.h (struct pthread): Rename cpuclock_offset to
> 	cpuclock_offset_ununsed.
> 	* nptl/nptl-init.c (__pthread_initialize_minimal_internal): Remove
> 	cpuclock_offset set.
> 	* nptl/pthread_create.c (START_THREAD_DEFN): Likewise.
> 	* sysdeps/nptl/fork.c (__libc_fork): Likewise.
> 	* nptl/pthread_clock_gettime.c: Remove file.
> 	* nptl/pthread_clock_settime.c: Likewise.
> 	* sysdeps/unix/clock_gettime.c (hp_timing_gettime): Remove function.
> 	[HP_TIMING_AVAIL] (realtime_gettime): Remove CLOCK_THREAD_CPUTIME_ID
> 	and CLOCK_PROCESS_CPUTIME_ID support.
> 	* sysdeps/unix/clock_settime.c (hp_timing_gettime): Likewise.
> 	[HP_TIMING_AVAIL] (realtime_gettime): Likewise.
> 	* sysdeps/posix/clock_getres.c (hp_timing_getres): Likewise.
> 	[HP_TIMING_AVAIL] (__clock_getres): Likewise.
> 	* sysdeps/unix/clock_nanosleep.c (CPUCLOCK_P, INVALID_CLOCK_P):
> 	Likewise.
> 	(__clock_nanosleep): Remove CPUCLOCK_P and INVALID_CLOCK_P usage.
> 
> [1] http://man7.org/linux/man-pages/man2/clock_gettime.2.html
> ---
>  elf/dl-support.c               |  8 ----
>  elf/rtld.c                     |  2 -
>  nptl/Makefile                  |  1 -
>  nptl/allocatestack.c           | 48 ------------------------
>  nptl/descr.h                   |  3 +-
>  nptl/nptl-init.c               |  3 --
>  nptl/pthreadP.h                | 10 -----
>  nptl/pthread_clock_gettime.c   | 67 ----------------------------------
>  nptl/pthread_clock_settime.c   | 54 ---------------------------
>  nptl/pthread_create.c          |  7 ----
>  sysdeps/generic/ldsodefs.h     |  5 ---
>  sysdeps/mach/hurd/dl-sysdep.c  |  8 ----
>  sysdeps/nptl/fork.c            |  8 ----
>  sysdeps/posix/clock_getres.c   | 46 +----------------------
>  sysdeps/unix/clock_gettime.c   | 65 +--------------------------------
>  sysdeps/unix/clock_nanosleep.c | 30 ++-------------
>  sysdeps/unix/clock_settime.c   | 61 +------------------------------
>  17 files changed, 9 insertions(+), 417 deletions(-)
>  delete mode 100644 nptl/pthread_clock_gettime.c
>  delete mode 100644 nptl/pthread_clock_settime.c
> 
> diff --git a/elf/dl-support.c b/elf/dl-support.c
> index 42c350c75d..0a8b636d02 100644
> --- a/elf/dl-support.c
> +++ b/elf/dl-support.c
> @@ -129,11 +129,6 @@ void *_dl_random;
>  #include <dl-procruntime.c>
>  #include <dl-procinfo.c>
>  
> -/* Initial value of the CPU clock.  */
> -#ifndef HP_TIMING_NONAVAIL
> -hp_timing_t _dl_cpuclock_offset;
> -#endif
> -
>  void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
>  
>  size_t _dl_pagesize = EXEC_PAGESIZE;
> @@ -314,9 +309,6 @@ _dl_non_dynamic_init (void)
>    _dl_main_map.l_phdr = GL(dl_phdr);
>    _dl_main_map.l_phnum = GL(dl_phnum);
>  
> -  if (HP_SMALL_TIMING_AVAIL)
> -    HP_TIMING_NOW (_dl_cpuclock_offset);
> -
>    _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
>  
>    /* Set up the data structures for the system-supplied DSO early,
> diff --git a/elf/rtld.c b/elf/rtld.c
> index c1cc1b01f2..1f124b31fc 100644
> --- a/elf/rtld.c
> +++ b/elf/rtld.c
> @@ -403,8 +403,6 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
>  # endif
>  #endif
>  
> -  HP_TIMING_NOW (GL(dl_cpuclock_offset));
> -
>    /* Initialize the stack end variable.  */
>    __libc_stack_end = __builtin_frame_address (0);
>  
> diff --git a/nptl/Makefile b/nptl/Makefile
> index 5acfdcceff..f9bc5cc887 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -109,7 +109,6 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
>  		      pthread_once \
>  		      old_pthread_atfork \
>  		      pthread_getcpuclockid \
> -		      pthread_clock_gettime pthread_clock_settime \
>  		      shm-directory \
>  		      sem_init sem_destroy \
>  		      sem_open sem_close sem_unlink \
> diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
> index d8e8570a7d..fcbc46f0d7 100644
> --- a/nptl/allocatestack.c
> +++ b/nptl/allocatestack.c
> @@ -963,54 +963,6 @@ __reclaim_stacks (void)
>  }
>  
>  
> -#if HP_TIMING_AVAIL
> -# undef __find_thread_by_id
> -/* Find a thread given the thread ID.  */
> -attribute_hidden
> -struct pthread *
> -__find_thread_by_id (pid_t tid)
> -{
> -  struct pthread *result = NULL;
> -
> -  lll_lock (stack_cache_lock, LLL_PRIVATE);
> -
> -  /* Iterate over the list with system-allocated threads first.  */
> -  list_t *runp;
> -  list_for_each (runp, &stack_used)
> -    {
> -      struct pthread *curp;
> -
> -      curp = list_entry (runp, struct pthread, list);
> -
> -      if (curp->tid == tid)
> -	{
> -	  result = curp;
> -	  goto out;
> -	}
> -    }
> -
> -  /* Now the list with threads using user-allocated stacks.  */
> -  list_for_each (runp, &__stack_user)
> -    {
> -      struct pthread *curp;
> -
> -      curp = list_entry (runp, struct pthread, list);
> -
> -      if (curp->tid == tid)
> -	{
> -	  result = curp;
> -	  goto out;
> -	}
> -    }
> -
> - out:
> -  lll_unlock (stack_cache_lock, LLL_PRIVATE);
> -
> -  return result;
> -}
> -#endif
> -
> -
>  #ifdef SIGSETXID
>  static void
>  setxid_mark_thread (struct xid_command *cmdp, struct pthread *t)
> diff --git a/nptl/descr.h b/nptl/descr.h
> index 4ef33ae465..cb7d4c2282 100644
> --- a/nptl/descr.h
> +++ b/nptl/descr.h
> @@ -343,8 +343,7 @@ struct pthread
>    unsigned int setxid_futex;
>  
>  #if HP_TIMING_AVAIL
> -  /* Offset of the CPU clock at start thread start time.  */
> -  hp_timing_t cpuclock_offset;
> +  hp_timing_t cpuclock_offset_ununsed;
>  #endif
>  
>    /* If the thread waits to join another one the ID of the latter is
> diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
> index b5895fabf3..6691211e4e 100644
> --- a/nptl/nptl-init.c
> +++ b/nptl/nptl-init.c
> @@ -276,9 +276,6 @@ __pthread_initialize_minimal_internal (void)
>    THREAD_SETMEM (pd, user_stack, true);
>    if (LLL_LOCK_INITIALIZER != 0)
>      THREAD_SETMEM (pd, lock, LLL_LOCK_INITIALIZER);
> -#if HP_TIMING_AVAIL
> -  THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset));
> -#endif
>  
>    /* Initialize the robust mutex data.  */
>    {
> diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
> index 626bd4b096..f0facfdb7d 100644
> --- a/nptl/pthreadP.h
> +++ b/nptl/pthreadP.h
> @@ -401,16 +401,6 @@ extern int __pthread_multiple_threads attribute_hidden;
>  extern int *__libc_multiple_threads_ptr attribute_hidden;
>  #endif
>  
> -/* Find a thread given its TID.  */
> -extern struct pthread *__find_thread_by_id (pid_t tid) attribute_hidden
> -#ifdef SHARED
> -;
> -#else
> -weak_function;
> -#define __find_thread_by_id(tid) \
> -  (__find_thread_by_id ? (__find_thread_by_id) (tid) : (struct pthread *) NULL)
> -#endif
> -
>  extern void __pthread_init_static_tls (struct link_map *) attribute_hidden;
>  
>  extern size_t __pthread_get_minstack (const pthread_attr_t *attr);
> diff --git a/nptl/pthread_clock_gettime.c b/nptl/pthread_clock_gettime.c
> deleted file mode 100644
> index f1d9104b24..0000000000
> --- a/nptl/pthread_clock_gettime.c
> +++ /dev/null
> @@ -1,67 +0,0 @@
> -/* Copyright (C) 2001-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; see the file COPYING.LIB.  If
> -   not, see <http://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <stdlib.h>
> -#include <time.h>
> -#include "pthreadP.h"
> -
> -
> -#if HP_TIMING_AVAIL
> -int
> -__pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
> -			 struct timespec *tp)
> -{
> -  hp_timing_t tsc;
> -
> -  /* Get the current counter.  */
> -  HP_TIMING_NOW (tsc);
> -
> -  /* This is the ID of the thread we are looking for.  */
> -  pid_t tid = ((unsigned int) clock_id) >> CLOCK_IDFIELD_SIZE;
> -
> -  /* Compute the offset since the start time of the process.  */
> -  if (tid == 0 || tid == THREAD_GETMEM (THREAD_SELF, tid))
> -    /* Our own clock.  */
> -    tsc -= THREAD_GETMEM (THREAD_SELF, cpuclock_offset);
> -  else
> -    {
> -      /* This is more complicated.  We have to locate the thread based
> -	 on the ID.  This means walking the list of existing
> -	 threads.  */
> -      struct pthread *thread = __find_thread_by_id (tid);
> -      if (thread == NULL)
> -	{
> -	  __set_errno (EINVAL);
> -	  return -1;
> -	}
> -
> -      /* There is a race here.  The thread might terminate and the stack
> -	 become unusable.  But this is the user's problem.  */
> -      tsc -= thread->cpuclock_offset;
> -    }
> -
> -  /* Compute the seconds.  */
> -  tp->tv_sec = tsc / freq;
> -
> -  /* And the nanoseconds.  This computation should be stable until
> -     we get machines with about 16GHz frequency.  */
> -  tp->tv_nsec = ((tsc % freq) * 1000000000ull) / freq;
> -
> -  return 0;
> -}
> -#endif
> diff --git a/nptl/pthread_clock_settime.c b/nptl/pthread_clock_settime.c
> deleted file mode 100644
> index 0fe6482f78..0000000000
> --- a/nptl/pthread_clock_settime.c
> +++ /dev/null
> @@ -1,54 +0,0 @@
> -/* Copyright (C) 2001-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; see the file COPYING.LIB.  If
> -   not, see <http://www.gnu.org/licenses/>.  */
> -
> -#include <errno.h>
> -#include <stdlib.h>
> -#include <time.h>
> -#include "pthreadP.h"
> -
> -
> -#if HP_TIMING_AVAIL
> -int
> -__pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
> -{
> -  /* This is the ID of the thread we are looking for.  */
> -  pid_t tid = ((unsigned int) clock_id) >> CLOCK_IDFIELD_SIZE;
> -
> -  /* Compute the offset since the start time of the process.  */
> -  if (tid == 0 || tid == THREAD_GETMEM (THREAD_SELF, tid))
> -    /* Our own clock.  */
> -    THREAD_SETMEM (THREAD_SELF, cpuclock_offset, offset);
> -  else
> -    {
> -      /* This is more complicated.  We have to locate the thread based
> -	 on the ID.  This means walking the list of existing
> -	 threads.  */
> -      struct pthread *thread = __find_thread_by_id (tid);
> -      if (thread == NULL)
> -	{
> -	  __set_errno (EINVAL);
> -	  return -1;
> -	}
> -
> -      /* There is a race here.  The thread might terminate and the stack
> -	 become unusable.  But this is the user's problem.  */
> -      thread->cpuclock_offset = offset;
> -    }
> -
> -  return 0;
> -}
> -#endif
> diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
> index 2bd2b10727..18b7bbe765 100644
> --- a/nptl/pthread_create.c
> +++ b/nptl/pthread_create.c
> @@ -379,13 +379,6 @@ START_THREAD_DEFN
>  {
>    struct pthread *pd = START_THREAD_SELF;
>  
> -#if HP_TIMING_AVAIL
> -  /* Remember the time when the thread was started.  */
> -  hp_timing_t now;
> -  HP_TIMING_NOW (now);
> -  THREAD_SETMEM (pd, cpuclock_offset, now);
> -#endif
> -
>    /* Initialize resolver state pointer.  */
>    __resp = &pd->res;
>  
> diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
> index 37cab6f06b..346bbb812d 100644
> --- a/sysdeps/generic/ldsodefs.h
> +++ b/sysdeps/generic/ldsodefs.h
> @@ -352,11 +352,6 @@ struct rtld_global
>    /* The object to be initialized first.  */
>    EXTERN struct link_map *_dl_initfirst;
>  
> -#if HP_SMALL_TIMING_AVAIL
> -  /* Start time on CPU clock.  */
> -  EXTERN hp_timing_t _dl_cpuclock_offset;
> -#endif
> -
>    /* Map of shared object to be profiled.  */
>    EXTERN struct link_map *_dl_profile_map;
>  
> diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c
> index a58338c930..72c80a8a46 100644
> --- a/sysdeps/mach/hurd/dl-sysdep.c
> +++ b/sysdeps/mach/hurd/dl-sysdep.c
> @@ -62,10 +62,6 @@ int __libc_multiple_libcs = 0;	/* Defining this here avoids the inclusion
>  void *__libc_stack_end = NULL;
>  rtld_hidden_data_def(__libc_stack_end)
>  
> -#if HP_TIMING_AVAIL
> -hp_timing_t _dl_cpuclock_offset;
> -#endif
> -
>  /* TODO: Initialize.  */
>  void *_dl_random attribute_relro = NULL;
>  
> @@ -246,10 +242,6 @@ unfmh();			/* XXX */
>    /* Initialize frequently used global variable.  */
>    GLRO(dl_pagesize) = __getpagesize ();
>  
> -#if HP_TIMING_AVAIL
> -  HP_TIMING_NOW (_dl_cpuclock_offset);
> -#endif
> -
>  fmh();				/* XXX */
>  
>    /* See hurd/hurdstartup.c; this deals with getting information
> diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
> index 14b69a6f89..3f357665bd 100644
> --- a/sysdeps/nptl/fork.c
> +++ b/sysdeps/nptl/fork.c
> @@ -83,14 +83,6 @@ __libc_fork (void)
>        if (__fork_generation_pointer != NULL)
>  	*__fork_generation_pointer += __PTHREAD_ONCE_FORK_GEN_INCR;
>  
> -#if HP_TIMING_AVAIL
> -      /* The CPU clock of the thread and process have to be set to zero.  */
> -      hp_timing_t now;
> -      HP_TIMING_NOW (now);
> -      THREAD_SETMEM (self, cpuclock_offset, now);
> -      GL(dl_cpuclock_offset) = now;
> -#endif
> -
>  #ifdef __NR_set_robust_list
>        /* Initialize the robust mutex list setting in the kernel which has
>  	 been reset during the fork.  We do not check for errors because if
> diff --git a/sysdeps/posix/clock_getres.c b/sysdeps/posix/clock_getres.c
> index dac4761fcc..01024a3f55 100644
> --- a/sysdeps/posix/clock_getres.c
> +++ b/sysdeps/posix/clock_getres.c
> @@ -24,37 +24,6 @@
>  #include <libc-internal.h>
>  
>  
> -#if HP_TIMING_AVAIL
> -static long int nsec;		/* Clock frequency of the processor.  */
> -
> -static int
> -hp_timing_getres (struct timespec *res)
> -{
> -  if (__glibc_unlikely (nsec == 0))
> -    {
> -      hp_timing_t freq;
> -
> -      /* This can only happen if we haven't initialized the `nsec'
> -	 variable yet.  Do this now.  We don't have to protect this
> -	 code against multiple execution since all of them should
> -	 lead to the same result.  */
> -      freq = __get_clockfreq ();
> -      if (__glibc_unlikely (freq == 0))
> -	/* Something went wrong.  */
> -	return -1;
> -
> -      nsec = MAX (UINT64_C (1000000000) / freq, 1);
> -    }
> -
> -  /* Fill in the values.
> -     The seconds are always zero (unless we have a 1Hz machine).  */
> -  res->tv_sec = 0;
> -  res->tv_nsec = nsec;
> -
> -  return 0;
> -}
> -#endif
> -
>  static inline int
>  realtime_getres (struct timespec *res)
>  {
> @@ -87,21 +56,8 @@ __clock_getres (clockid_t clock_id, struct timespec *res)
>        break;
>  
>      default:
> -#if HP_TIMING_AVAIL
> -      if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
> -	  == CLOCK_THREAD_CPUTIME_ID)
> -	retval = hp_timing_getres (res);
> -      else
> -#endif
> -	__set_errno (EINVAL);
> -      break;
> -
> -#if HP_TIMING_AVAIL
> -    case CLOCK_PROCESS_CPUTIME_ID:
> -    case CLOCK_THREAD_CPUTIME_ID:
> -      retval = hp_timing_getres (res);
> +      __set_errno (EINVAL);
>        break;
> -#endif
>      }
>  
>    return retval;
> diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/unix/clock_gettime.c
> index 33a1f3335c..10a6c96d9d 100644
> --- a/sysdeps/unix/clock_gettime.c
> +++ b/sysdeps/unix/clock_gettime.c
> @@ -24,57 +24,6 @@
>  #include <ldsodefs.h>
>  
>  
> -#if HP_TIMING_AVAIL
> -/* Clock frequency of the processor.  We make it a 64-bit variable
> -   because some jokers are already playing with processors with more
> -   than 4GHz.  */
> -static hp_timing_t freq;
> -
> -
> -/* This function is defined in the thread library.  */
> -extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
> -				    struct timespec *tp)
> -     __attribute__ ((__weak__));
> -
> -static int
> -hp_timing_gettime (clockid_t clock_id, struct timespec *tp)
> -{
> -  hp_timing_t tsc;
> -
> -  if (__glibc_unlikely (freq == 0))
> -    {
> -      /* This can only happen if we haven't initialized the `freq'
> -	 variable yet.  Do this now. We don't have to protect this
> -	 code against multiple execution since all of them should
> -	 lead to the same result.  */
> -      freq = __get_clockfreq ();
> -      if (__glibc_unlikely (freq == 0))
> -	/* Something went wrong.  */
> -	return -1;
> -    }
> -
> -  if (clock_id != CLOCK_PROCESS_CPUTIME_ID
> -      && __pthread_clock_gettime != NULL)
> -    return __pthread_clock_gettime (clock_id, freq, tp);
> -
> -  /* Get the current counter.  */
> -  HP_TIMING_NOW (tsc);
> -
> -  /* Compute the offset since the start time of the process.  */
> -  tsc -= GL(dl_cpuclock_offset);
> -
> -  /* Compute the seconds.  */
> -  tp->tv_sec = tsc / freq;
> -
> -  /* And the nanoseconds.  This computation should be stable until
> -     we get machines with about 16GHz frequency.  */
> -  tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq;
> -
> -  return 0;
> -}
> -#endif
> -
> -
>  static inline int
>  realtime_gettime (struct timespec *tp)
>  {
> @@ -105,20 +54,8 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp)
>        break;
>  
>      default:
> -#if HP_TIMING_AVAIL
> -      if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
> -	  == CLOCK_THREAD_CPUTIME_ID)
> -	retval = hp_timing_gettime (clock_id, tp);
> -      else
> -#endif
> -	__set_errno (EINVAL);
> -      break;
> -
> -#if HP_TIMING_AVAIL
> -    case CLOCK_PROCESS_CPUTIME_ID:
> -      retval = hp_timing_gettime (clock_id, tp);
> +      __set_errno (EINVAL);
>        break;
> -#endif
>      }
>  
>    return retval;
> diff --git a/sysdeps/unix/clock_nanosleep.c b/sysdeps/unix/clock_nanosleep.c
> index 7722d1111c..b27608570c 100644
> --- a/sysdeps/unix/clock_nanosleep.c
> +++ b/sysdeps/unix/clock_nanosleep.c
> @@ -19,23 +19,8 @@
>  #include <assert.h>
>  #include <errno.h>
>  #include <time.h>
> -#include <hp-timing.h>
>  #include <sysdep-cancel.h>
>  
> -#if HP_TIMING_AVAIL
> -# define CPUCLOCK_P(clock) \
> -  ((clock) == CLOCK_PROCESS_CPUTIME_ID					      \
> -   || ((clock) & ((1 << CLOCK_IDFIELD_SIZE) - 1)) == CLOCK_THREAD_CPUTIME_ID)
> -#else
> -# define CPUCLOCK_P(clock) 0
> -#endif
> -
> -#ifndef INVALID_CLOCK_P
> -# define INVALID_CLOCK_P(cl) \
> -  ((cl) < CLOCK_REALTIME || (cl) > CLOCK_THREAD_CPUTIME_ID)
> -#endif
> -
> -
>  /* This implementation assumes that these is only a `nanosleep' system
>     call.  So we have to remap all other activities.  */
>  int
> @@ -51,14 +36,7 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
>    if (clock_id == CLOCK_THREAD_CPUTIME_ID)
>      return EINVAL;		/* POSIX specifies EINVAL for this case.  */
>  
> -#ifdef SYSDEP_NANOSLEEP
> -  SYSDEP_NANOSLEEP;
> -#endif
> -
> -  if (CPUCLOCK_P (clock_id))
> -    return ENOTSUP;
> -
> -  if (INVALID_CLOCK_P (clock_id))
> +  if (clock_id < CLOCK_REALTIME || clock_id > CLOCK_THREAD_CPUTIME_ID)
>      return EINVAL;
>  
>    /* If we got an absolute time, remap it.  */
> @@ -71,7 +49,7 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
>        assert (sizeof (sec) >= sizeof (now.tv_sec));
>  
>        /* Get the current time for this clock.  */
> -      if (__builtin_expect (__clock_gettime (clock_id, &now), 0) != 0)
> +      if (__clock_gettime (clock_id, &now) != 0)
>  	return errno;
>  
>        /* Compute the difference.  */
> @@ -90,12 +68,12 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
>        /* Make sure we are not modifying the struct pointed to by REM.  */
>        rem = NULL;
>      }
> -  else if (__builtin_expect (flags, 0) != 0)
> +  else if (flags != 0)
>      return EINVAL;
>    else if (clock_id != CLOCK_REALTIME)
>      /* Not supported.  */
>      return ENOTSUP;
>  
> -  return __builtin_expect (__nanosleep (req, rem), 0) ? errno : 0;
> +  return __nanosleep (req, rem), 0 ? errno : 0;
>  }
>  weak_alias (__clock_nanosleep, clock_nanosleep)
> diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/unix/clock_settime.c
> index dcf9ff660a..109a1ad872 100644
> --- a/sysdeps/unix/clock_settime.c
> +++ b/sysdeps/unix/clock_settime.c
> @@ -21,59 +21,11 @@
>  #include <ldsodefs.h>
>  
>  
> -#if HP_TIMING_AVAIL
> -/* Clock frequency of the processor.  We make it a 64-bit variable
> -   because some jokers are already playing with processors with more
> -   than 4GHz.  */
> -static hp_timing_t freq;
> -
> -
> -/* This function is defined in the thread library.  */
> -extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
> -     __attribute__ ((__weak__));
> -
> -
> -static int
> -hp_timing_settime (clockid_t clock_id, const struct timespec *tp)
> -{
> -  hp_timing_t tsc;
> -  hp_timing_t usertime;
> -
> -  /* First thing is to get the current time.  */
> -  HP_TIMING_NOW (tsc);
> -
> -  if (__glibc_unlikely (freq == 0))
> -    {
> -      /* This can only happen if we haven't initialized the `freq'
> -	 variable yet.  Do this now. We don't have to protect this
> -	 code against multiple execution since all of them should lead
> -	 to the same result.  */
> -      freq = __get_clockfreq ();
> -      if (__glibc_unlikely (freq == 0))
> -	/* Something went wrong.  */
> -	return -1;
> -    }
> -
> -  /* Convert the user-provided time into CPU ticks.  */
> -  usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull;
> -
> -  /* Determine the offset and use it as the new base value.  */
> -  if (clock_id == CLOCK_PROCESS_CPUTIME_ID
> -      || __pthread_clock_settime == NULL)
> -    GL(dl_cpuclock_offset) = tsc - usertime;
> -  else
> -    __pthread_clock_settime (clock_id, tsc - usertime);
> -
> -  return 0;
> -}
> -#endif
> -
> -
>  /* Set CLOCK to value TP.  */
>  int
>  __clock_settime (clockid_t clock_id, const struct timespec *tp)
>  {
> -  int retval;
> +  int retval = -1;
>  
>    /* Make sure the time cvalue is OK.  */
>    if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000)
> @@ -93,16 +45,7 @@ __clock_settime (clockid_t clock_id, const struct timespec *tp)
>        break;
>  
>      default:
> -# if HP_TIMING_AVAIL
> -      if (CPUCLOCK_WHICH (clock_id) == CLOCK_PROCESS_CPUTIME_ID
> -	  || CPUCLOCK_WHICH (clock_id) == CLOCK_THREAD_CPUTIME_ID)
> -	retval = hp_timing_settime (clock_id, tp);
> -      else
> -# endif
> -	{
> -	  __set_errno (EINVAL);
> -	  retval = -1;
> -	}
> +      __set_errno (EINVAL);
>        break;
>      }
>  
> 

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

* Re: [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID
  2019-02-18 21:11 ` [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID Adhemerval Zanella
@ 2019-03-19 17:24   ` Adhemerval Zanella
  2019-03-20 11:49   ` Andreas Schwab
  1 sibling, 0 replies; 14+ messages in thread
From: Adhemerval Zanella @ 2019-03-19 17:24 UTC (permalink / raw)
  To: libc-alpha

Ping.

On 18/02/2019 18:11, Adhemerval Zanella wrote:
> Changes from previous version:
> 
>   - Remove ia64 itc drift check and assume kernel handles it correctly.
> 
> ---
> 
> This patch assumes that clock_getres syscall always support
> CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID, so there is no need
> to fallback to hp-timing support for _SC_MONOTONIC_CLOCK.  This allows
> simplify the sysconf support to always use the syscall.
> 
> The ia64 implementation is also simplified and consolidate in one file.
> 
> Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.
> 
> 	* sysdeps/unix/sysv/linux/ia64/has_cpuclock.c: Remove file.
> 	* sysdeps/unix/sysv/linux/ia64/sysconf.c: Likewise.
> 	* sysdeps/unix/sysv/linux/sysconf.c (has_cpuclock): Remove function.
> 	(check_clock_getres): New function.
> 	(__sysconf): Use check_clock_getres instead of has_cpuclock.
> ---
>  sysdeps/unix/sysv/linux/ia64/has_cpuclock.c | 51 ---------------------
>  sysdeps/unix/sysv/linux/ia64/sysconf.c      | 30 ------------
>  sysdeps/unix/sysv/linux/sysconf.c           | 48 ++++++-------------
>  3 files changed, 13 insertions(+), 116 deletions(-)
>  delete mode 100644 sysdeps/unix/sysv/linux/ia64/has_cpuclock.c
>  delete mode 100644 sysdeps/unix/sysv/linux/ia64/sysconf.c
> 
> diff --git a/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c b/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c
> deleted file mode 100644
> index b3afb37f8b..0000000000
> --- a/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c
> +++ /dev/null
> @@ -1,51 +0,0 @@
> -/* 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 <fcntl.h>
> -#include <unistd.h>
> -#include <sys/stat.h>
> -#include <sys/types.h>
> -#include <not-cancel.h>
> -
> -static int itc_usable;
> -
> -static int
> -has_cpuclock (void)
> -{
> -  if (__builtin_expect (itc_usable == 0, 0))
> -    {
> -      int newval = 1;
> -      int fd = __open_nocancel ("/proc/sal/itc_drift", O_RDONLY);
> -      if (__builtin_expect (fd != -1, 1))
> -	{
> -	  char buf[16];
> -	  /* We expect the file to contain a single digit followed by
> -	     a newline.  If the format changes we better not rely on
> -	     the file content.  */
> -	  if (__read_nocancel (fd, buf, sizeof buf) != 2
> -	      || buf[0] != '0' || buf[1] != '\n')
> -	    newval = -1;
> -
> -	  __close_nocancel_nostatus (fd);
> -	}
> -
> -      itc_usable = newval;
> -    }
> -
> -  return itc_usable;
> -}
> diff --git a/sysdeps/unix/sysv/linux/ia64/sysconf.c b/sysdeps/unix/sysv/linux/ia64/sysconf.c
> deleted file mode 100644
> index ef75322f1f..0000000000
> --- a/sysdeps/unix/sysv/linux/ia64/sysconf.c
> +++ /dev/null
> @@ -1,30 +0,0 @@
> -/* Get file-specific information about a file.  Linux/ia64 version.
> -   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 <assert.h>
> -#include <stdbool.h>
> -#include <stdlib.h>
> -#include <unistd.h>
> -
> -
> -#include "has_cpuclock.c"
> -#define HAS_CPUCLOCK(name) (has_cpuclock () ? _POSIX_VERSION : -1)
> -
> -
> -/* Now the generic Linux version.  */
> -#include <sysdeps/unix/sysv/linux/sysconf.c>
> diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
> index 4b297ba35f..2027444488 100644
> --- a/sysdeps/unix/sysv/linux/sysconf.c
> +++ b/sysdeps/unix/sysv/linux/sysconf.c
> @@ -35,33 +35,18 @@
>  static long int posix_sysconf (int name);
>  
>  
> -#ifndef HAS_CPUCLOCK
>  static long int
> -has_cpuclock (int name)
> +check_clock_getres (clockid_t clk_id)
>  {
> -# if defined __NR_clock_getres || HP_TIMING_AVAIL
> -  /* If we have HP_TIMING, we will fall back on that if the system
> -     call does not work, so we support it either way.  */
> -#  if !HP_TIMING_AVAIL
> -  /* Check using the clock_getres system call.  */
>    struct timespec ts;
>    INTERNAL_SYSCALL_DECL (err);
> -  int r = INTERNAL_SYSCALL (clock_getres, err, 2,
> -			    (name == _SC_CPUTIME
> -			     ? CLOCK_PROCESS_CPUTIME_ID
> -			     : CLOCK_THREAD_CPUTIME_ID),
> -			    &ts);
> +  /* Avoid setting errno to we can check whether the kernel supports
> +     the CLK_ID.  */
> +  int r = INTERNAL_SYSCALL_CALL (clock_getres, err, clk_id, &ts);
>    if (INTERNAL_SYSCALL_ERROR_P (r, err))
>      return -1;
> -#  endif
>    return _POSIX_VERSION;
> -# else
> -  return -1;
> -# endif
>  }
> -# define HAS_CPUCLOCK(name) has_cpuclock (name)
> -#endif
> -
>  
>  /* Get the value of the system variable NAME.  */
>  long int
> @@ -71,29 +56,21 @@ __sysconf (int name)
>  
>    switch (name)
>      {
> -      struct rlimit rlimit;
> -#ifdef __NR_clock_getres
>      case _SC_MONOTONIC_CLOCK:
> -      /* Check using the clock_getres system call.  */
> -      {
> -	struct timespec ts;
> -	INTERNAL_SYSCALL_DECL (err);
> -	int r;
> -	r = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
> -	return INTERNAL_SYSCALL_ERROR_P (r, err) ? -1 : _POSIX_VERSION;
> -      }
> -#endif
> -
> +      return check_clock_getres (CLOCK_MONOTONIC);
>      case _SC_CPUTIME:
> +      return check_clock_getres (CLOCK_PROCESS_CPUTIME_ID);
>      case _SC_THREAD_CPUTIME:
> -      return HAS_CPUCLOCK (name);
> +      return check_clock_getres (CLOCK_THREAD_CPUTIME_ID);
>  
> -    case _SC_ARG_MAX:
> +    case _SC_ARG_MAX: {
> +      struct rlimit rlimit;
>        /* Use getrlimit to get the stack limit.  */
>        if (__getrlimit (RLIMIT_STACK, &rlimit) == 0)
>  	return MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4);
>  
>        return legacy_ARG_MAX;
> +    } break;
>  
>      case _SC_NGROUPS_MAX:
>        /* Try to read the information from the /proc/sys/kernel/ngroups_max
> @@ -101,13 +78,14 @@ __sysconf (int name)
>        procfname = "/proc/sys/kernel/ngroups_max";
>        break;
>  
> -    case _SC_SIGQUEUE_MAX:
> +    case _SC_SIGQUEUE_MAX: {
> +      struct rlimit rlimit;
>        if (__getrlimit (RLIMIT_SIGPENDING, &rlimit) == 0)
>  	return rlimit.rlim_cur;
>  
>        /* The /proc/sys/kernel/rtsig-max file contains the answer.  */
>        procfname = "/proc/sys/kernel/rtsig-max";
> -      break;
> +    } break;
>  
>      default:
>        break;
> 

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

* Re: [PATCH v2 3/6] Remove __get_clockfreq
  2019-02-18 21:11 ` [PATCH v2 3/6] Remove __get_clockfreq Adhemerval Zanella
@ 2019-03-19 17:24   ` Adhemerval Zanella
  0 siblings, 0 replies; 14+ messages in thread
From: Adhemerval Zanella @ 2019-03-19 17:24 UTC (permalink / raw)
  To: libc-alpha

Ping.

On 18/02/2019 18:11, Adhemerval Zanella wrote:
> With clock_getres, clock_gettime, and clock_settime refactor to remove the
> generic CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID support through
> hp-timing, there is no usage of internal __get_clockfreq.  This patch removes
> both generic and Linux implementation..
> 
> Checked with a build against aarch64-linux-gnu, i686-linux-gnu, ia64-linux-gnu,
> sparc64-linux-gnu, powerpc-linux-gnu-power4.
> 
> 	* include/libc-internal.h (__get_clockfreq): Remove prototype.
> 	* rt/Makefile (clock-routines): Remove get_clockfreq.
> 	* rt/get_clockfreq.c: Remove file.
> 	* sysdeps/unix/sysv/linux/i386/get_clockfreq.c: Likewise.
> 	* sysdeps/unix/sysv/linux/ia64/get_clockfreq.c: Likewise.
> 	* sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c: Likewise.
> 	* sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c: Move code to ...
> 	* sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c: ... here.
> ---
>  include/libc-internal.h                       |   3 -
>  rt/Makefile                                   |   2 +-
>  rt/get_clockfreq.c                            |  27 --
>  sysdeps/unix/sysv/linux/i386/get_clockfreq.c  |  88 ------
>  sysdeps/unix/sysv/linux/ia64/get_clockfreq.c  |  87 ------
>  .../unix/sysv/linux/powerpc/get_clockfreq.c   | 107 --------
>  .../sysv/linux/powerpc/get_timebase_freq.c    |  81 +++++-
>  .../sysv/linux/sparc/sparc64/get_clockfreq.c  | 250 ------------------
>  8 files changed, 81 insertions(+), 564 deletions(-)
>  delete mode 100644 rt/get_clockfreq.c
>  delete mode 100644 sysdeps/unix/sysv/linux/i386/get_clockfreq.c
>  delete mode 100644 sysdeps/unix/sysv/linux/ia64/get_clockfreq.c
>  delete mode 100644 sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c
>  delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c
> 
> diff --git a/include/libc-internal.h b/include/libc-internal.h
> index 70edd77f81..db4d12432c 100644
> --- a/include/libc-internal.h
> +++ b/include/libc-internal.h
> @@ -36,9 +36,6 @@ libc_hidden_proto (__profile_frequency)
>  extern void __cyg_profile_func_enter (void *this_fn, void *call_site);
>  extern void __cyg_profile_func_exit (void *this_fn, void *call_site);
>  
> -/* Get frequency of the system processor.  */
> -extern hp_timing_t __get_clockfreq (void);
> -
>  /* Free all allocated resources.  */
>  extern void __libc_freeres (void);
>  libc_hidden_proto (__libc_freeres)
> diff --git a/rt/Makefile b/rt/Makefile
> index 0789bb8db7..9ea8394565 100644
> --- a/rt/Makefile
> +++ b/rt/Makefile
> @@ -28,7 +28,7 @@ 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 := get_clockfreq clock_getcpuclockid			\
> +clock-routines := clock_getcpuclockid					\
>  		  clock_getres clock_gettime clock_settime		\
>  		  clock_nanosleep
>  timer-routines := timer_create timer_delete timer_getoverr		\
> diff --git a/rt/get_clockfreq.c b/rt/get_clockfreq.c
> deleted file mode 100644
> index e62a7a5118..0000000000
> --- a/rt/get_clockfreq.c
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -/* Get frequency of the system processor.
> -   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 <libc-internal.h>
> -
> -hp_timing_t
> -__get_clockfreq (void)
> -{
> -  /* There is no generic way to find this out since we have in general
> -     no counter register either.  */
> -  return 0;
> -}
> diff --git a/sysdeps/unix/sysv/linux/i386/get_clockfreq.c b/sysdeps/unix/sysv/linux/i386/get_clockfreq.c
> deleted file mode 100644
> index 621d52491b..0000000000
> --- a/sysdeps/unix/sysv/linux/i386/get_clockfreq.c
> +++ /dev/null
> @@ -1,88 +0,0 @@
> -/* Get frequency of the system processor.  i386/Linux 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 <ctype.h>
> -#include <fcntl.h>
> -#include <string.h>
> -#include <unistd.h>
> -
> -hp_timing_t
> -__get_clockfreq (void)
> -{
> -  /* We read the information from the /proc filesystem.  It contains at
> -     least one line like
> -	cpu MHz         : 497.840237
> -     or also
> -	cpu MHz         : 497.841
> -     We search for this line and convert the number in an integer.  */
> -  static hp_timing_t result;
> -  int fd;
> -
> -  /* If this function was called before, we know the result.  */
> -  if (result != 0)
> -    return result;
> -
> -  fd = __open ("/proc/cpuinfo", O_RDONLY);
> -  if (__glibc_likely (fd != -1))
> -    {
> -      /* XXX AFAIK the /proc filesystem can generate "files" only up
> -         to a size of 4096 bytes.  */
> -      char buf[4096];
> -      ssize_t n;
> -
> -      n = __read (fd, buf, sizeof buf);
> -      if (__builtin_expect (n, 1) > 0)
> -	{
> -	  char *mhz = memmem (buf, n, "cpu MHz", 7);
> -
> -	  if (__glibc_likely (mhz != NULL))
> -	    {
> -	      char *endp = buf + n;
> -	      int seen_decpoint = 0;
> -	      int ndigits = 0;
> -
> -	      /* Search for the beginning of the string.  */
> -	      while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
> -		++mhz;
> -
> -	      while (mhz < endp && *mhz != '\n')
> -		{
> -		  if (*mhz >= '0' && *mhz <= '9')
> -		    {
> -		      result *= 10;
> -		      result += *mhz - '0';
> -		      if (seen_decpoint)
> -			++ndigits;
> -		    }
> -		  else if (*mhz == '.')
> -		    seen_decpoint = 1;
> -
> -		  ++mhz;
> -		}
> -
> -	      /* Compensate for missing digits at the end.  */
> -	      while (ndigits++ < 6)
> -		result *= 10;
> -	    }
> -	}
> -
> -      __close (fd);
> -    }
> -
> -  return result;
> -}
> diff --git a/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c b/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c
> deleted file mode 100644
> index 581f87f3e6..0000000000
> --- a/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c
> +++ /dev/null
> @@ -1,87 +0,0 @@
> -/* Get frequency of the system processor.  IA-64/Linux version.
> -   Copyright (C) 2001-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 <ctype.h>
> -#include <fcntl.h>
> -#include <string.h>
> -#include <unistd.h>
> -
> -
> -hp_timing_t
> -__get_clockfreq (void)
> -{
> -  /* We read the information from the /proc filesystem.  It contains at
> -     least one line like
> -	itc MHz    : 733.390988
> -     We search for this line and convert the number in an integer.  */
> -  static hp_timing_t result;
> -  int fd;
> -
> -  /* If this function was called before, we know the result.  */
> -  if (result != 0)
> -    return result;
> -
> -  fd = __open ("/proc/cpuinfo", O_RDONLY);
> -  if (__builtin_expect (fd != -1, 1))
> -    {
> -      /* XXX AFAIK the /proc filesystem can generate "files" only up
> -         to a size of 4096 bytes.  */
> -      char buf[4096];
> -      ssize_t n;
> -
> -      n = __read (fd, buf, sizeof buf);
> -      if (__builtin_expect (n, 1) > 0)
> -	{
> -	  char *mhz = memmem (buf, n, "itc MHz", 7);
> -
> -	  if (__builtin_expect (mhz != NULL, 1))
> -	    {
> -	      char *endp = buf + n;
> -	      int seen_decpoint = 0;
> -	      int ndigits = 0;
> -
> -	      /* Search for the beginning of the string.  */
> -	      while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
> -		++mhz;
> -
> -	      while (mhz < endp && *mhz != '\n')
> -		{
> -		  if (*mhz >= '0' && *mhz <= '9')
> -		    {
> -		      result *= 10;
> -		      result += *mhz - '0';
> -		      if (seen_decpoint)
> -			++ndigits;
> -		    }
> -		  else if (*mhz == '.')
> -		    seen_decpoint = 1;
> -
> -		  ++mhz;
> -		}
> -
> -	      /* Compensate for missing digits at the end.  */
> -	      while (ndigits++ < 6)
> -		result *= 10;
> -	    }
> -	}
> -
> -      __close (fd);
> -    }
> -
> -  return result;
> -}
> diff --git a/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c b/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c
> deleted file mode 100644
> index 98668fa718..0000000000
> --- a/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c
> +++ /dev/null
> @@ -1,107 +0,0 @@
> -/* Get frequency of the system processor.  powerpc/Linux 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 <ctype.h>
> -#include <fcntl.h>
> -#include <stdint.h>
> -#include <string.h>
> -#include <unistd.h>
> -#include <sysdep.h>
> -#include <libc-vdso.h>
> -#include <not-cancel.h>
> -
> -hp_timing_t
> -__get_clockfreq (void)
> -{
> -  hp_timing_t result = 0L;
> -
> -#ifdef SHARED
> -  /* The vDSO does not return an error (it clear cr0.so on returning).  */
> -  INTERNAL_SYSCALL_DECL (err);
> -  result =
> -    INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, uint64_t, 0);
> -#else
> -  /* We read the information from the /proc filesystem.  /proc/cpuinfo
> -     contains at least one line like:
> -     timebase        : 33333333
> -     We search for this line and convert the number into an integer.  */
> -  int fd = __open_nocancel ("/proc/cpuinfo", O_RDONLY);
> -  if (__glibc_likely (fd != -1))
> -    return result;
> -
> -  /* The timebase will be in the 1st 1024 bytes for systems with up
> -     to 8 processors.  If the first read returns less then 1024
> -     bytes read,  we have the whole cpuinfo and can start the scan.
> -     Otherwise we will have to read more to insure we have the
> -     timebase value in the scan.  */
> -  char buf[1024];
> -  ssize_t n;
> -
> -  n = __read_nocancel (fd, buf, sizeof (buf));
> -  if (n == sizeof (buf))
> -    {
> -      /* We are here because the 1st read returned exactly sizeof
> -         (buf) bytes.  This implies that we are not at EOF and may
> -         not have read the timebase value yet.  So we need to read
> -         more bytes until we know we have EOF.  We copy the lower
> -         half of buf to the upper half and read sizeof (buf)/2
> -         bytes into the lower half of buf and repeat until we
> -         reach EOF.  We can assume that the timebase will be in
> -         the last 512 bytes of cpuinfo, so two 512 byte half_bufs
> -         will be sufficient to contain the timebase and will
> -         handle the case where the timebase spans the half_buf
> -         boundry.  */
> -      const ssize_t half_buf = sizeof (buf) / 2;
> -      while (n >= half_buf)
> -	{
> -	  memcpy (buf, buf + half_buf, half_buf);
> -	  n = __read_nocancel (fd, buf + half_buf, half_buf);
> -	}
> -      if (n >= 0)
> -	n += half_buf;
> -    }
> -  __close_nocancel (fd);
> -
> -  if (__glibc_likely (n > 0))
> -    {
> -      char *mhz = memmem (buf, n, "timebase", 7);
> -
> -      if (__glibc_likely (mhz != NULL))
> -	{
> -	  char *endp = buf + n;
> -
> -	  /* Search for the beginning of the string.  */
> -	  while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
> -	    ++mhz;
> -
> -	  while (mhz < endp && *mhz != '\n')
> -	    {
> -	      if (*mhz >= '0' && *mhz <= '9')
> -		{
> -		  result *= 10;
> -		  result += *mhz - '0';
> -		}
> -
> -	      ++mhz;
> -	    }
> -	}
> -    }
> -#endif
> -
> -  return result;
> -}
> diff --git a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
> index 5903a909e3..23e7694d87 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
> +++ b/sysdeps/unix/sysv/linux/powerpc/get_timebase_freq.c
> @@ -17,11 +17,90 @@
>     <http://www.gnu.org/licenses/>.  */
>  
>  #include <stdint.h>
> +#include <string.h>
> +
>  #include <libc-internal.h>
> +#include <not-cancel.h>
> +#include <libc-vdso.h>
>  
>  uint64_t
>  __get_timebase_freq (void)
>  {
> -  return (uint64_t) __get_clockfreq ();
> +  hp_timing_t result = 0L;
> +
> +#ifdef SHARED
> +  /* The vDSO does not return an error (it clear cr0.so on returning).  */
> +  INTERNAL_SYSCALL_DECL (err);
> +  result =
> +    INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, uint64_t, 0);
> +#else
> +  /* We read the information from the /proc filesystem.  /proc/cpuinfo
> +     contains at least one line like:
> +     timebase        : 33333333
> +     We search for this line and convert the number into an integer.  */
> +  int fd = __open_nocancel ("/proc/cpuinfo", O_RDONLY);
> +  if (__glibc_likely (fd != -1))
> +    return result;
> +
> +  /* The timebase will be in the 1st 1024 bytes for systems with up
> +     to 8 processors.  If the first read returns less then 1024
> +     bytes read,  we have the whole cpuinfo and can start the scan.
> +     Otherwise we will have to read more to insure we have the
> +     timebase value in the scan.  */
> +  char buf[1024];
> +  ssize_t n;
> +
> +  n = __read_nocancel (fd, buf, sizeof (buf));
> +  if (n == sizeof (buf))
> +    {
> +      /* We are here because the 1st read returned exactly sizeof
> +         (buf) bytes.  This implies that we are not at EOF and may
> +         not have read the timebase value yet.  So we need to read
> +         more bytes until we know we have EOF.  We copy the lower
> +         half of buf to the upper half and read sizeof (buf)/2
> +         bytes into the lower half of buf and repeat until we
> +         reach EOF.  We can assume that the timebase will be in
> +         the last 512 bytes of cpuinfo, so two 512 byte half_bufs
> +         will be sufficient to contain the timebase and will
> +         handle the case where the timebase spans the half_buf
> +         boundry.  */
> +      const ssize_t half_buf = sizeof (buf) / 2;
> +      while (n >= half_buf)
> +	{
> +	  memcpy (buf, buf + half_buf, half_buf);
> +	  n = __read_nocancel (fd, buf + half_buf, half_buf);
> +	}
> +      if (n >= 0)
> +	n += half_buf;
> +    }
> +  __close_nocancel (fd);
> +
> +  if (__glibc_likely (n > 0))
> +    {
> +      char *mhz = memmem (buf, n, "timebase", 7);
> +
> +      if (__glibc_likely (mhz != NULL))
> +	{
> +	  char *endp = buf + n;
> +
> +	  /* Search for the beginning of the string.  */
> +	  while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n')
> +	    ++mhz;
> +
> +	  while (mhz < endp && *mhz != '\n')
> +	    {
> +	      if (*mhz >= '0' && *mhz <= '9')
> +		{
> +		  result *= 10;
> +		  result += *mhz - '0';
> +		}
> +
> +	      ++mhz;
> +	    }
> +	}
> +    }
> +#endif
> +
> +  return result;
>  }
>  weak_alias (__get_timebase_freq, __ppc_get_timebase_freq)
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c b/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c
> deleted file mode 100644
> index 87853d6b6e..0000000000
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c
> +++ /dev/null
> @@ -1,250 +0,0 @@
> -/* Get frequency of the system processor.  sparc64 version.
> -   Copyright (C) 2001-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 <ctype.h>
> -#include <fcntl.h>
> -#include <string.h>
> -#include <unistd.h>
> -#include <dirent.h>
> -#include <stdlib.h>
> -#include <inttypes.h>
> -#include <sys/ioctl.h>
> -#include <asm/openpromio.h>
> -
> -static hp_timing_t
> -__get_clockfreq_via_cpuinfo (void)
> -{
> -  hp_timing_t result;
> -  int fd;
> -
> -  result = 0;
> -
> -  fd = __open ("/proc/cpuinfo", O_RDONLY);
> -  if (fd != -1)
> -    {
> -      char buf[8192];
> -      ssize_t n;
> -
> -      n = __read (fd, buf, sizeof buf);
> -      if (n > 0)
> -	{
> -	  char *mhz = memmem (buf, n, "Cpu0ClkTck", 7);
> -
> -	  if (mhz != NULL)
> -	    {
> -	      char *endp = buf + n;
> -
> -	      /* Search for the beginning of the string.  */
> -	      while (mhz < endp
> -		     && (*mhz < '0' || *mhz > '9')
> -		     && (*mhz < 'a' || *mhz > 'f')
> -		     && *mhz != '\n')
> -		++mhz;
> -
> -	      while (mhz < endp && *mhz != '\n')
> -		{
> -		  if ((*mhz >= '0' && *mhz <= '9') ||
> -		      (*mhz >= 'a' && *mhz <= 'f'))
> -		    {
> -		      result <<= 4;
> -		      if (*mhz >= '0' && *mhz <= '9')
> -			result += *mhz - '0';
> -		      else
> -			result += (*mhz - 'a') + 10;
> -		    }
> -		  ++mhz;
> -		}
> -	    }
> -	}
> -
> -      __close (fd);
> -    }
> -
> -  return result;
> -}
> -
> -static hp_timing_t
> -__get_clockfreq_via_proc_openprom (void)
> -{
> -  hp_timing_t result;
> -  int obp_fd;
> -
> -  result = 0;
> -
> -  obp_fd = __open ("/proc/openprom", O_RDONLY);
> -  if (obp_fd != -1)
> -    {
> -      unsigned long int buf[4096 / sizeof (unsigned long int)];
> -      struct dirent64 *dirp = (struct dirent64 *) buf;
> -      ssize_t len;
> -
> -      while ((len = __getdents64 (obp_fd, (char *) dirp, sizeof (buf))) > 0)
> -	{
> -	  struct dirent64 *this_dirp = dirp;
> -
> -	  while (len > 0)
> -	    {
> -	      char node[strlen ("/proc/openprom/")
> -			+ _D_ALLOC_NAMLEN (this_dirp)
> -			+ strlen ("/clock-frequency")];
> -	      char *prop;
> -	      int fd;
> -
> -	      /* Note that
> -		   strlen("/clock-frequency") > strlen("/device_type")
> -	      */
> -	      __stpcpy (prop = __stpcpy (__stpcpy (node, "/proc/openprom/"),
> -					 this_dirp->d_name),
> -			"/device_type");
> -	      fd = __open (node, O_RDONLY);
> -	      if (fd != -1)
> -		{
> -		  char type_string[128];
> -		  int ret;
> -
> -		  ret = __read (fd, type_string, sizeof (type_string));
> -		  if (ret > 0 && strncmp (type_string, "'cpu'", 5) == 0)
> -		    {
> -		      int clkfreq_fd;
> -
> -		      __stpcpy (prop, "/clock-frequency");
> -		      clkfreq_fd = __open (node, O_RDONLY);
> -		      if (clkfreq_fd != -1)
> -			{
> -			  if (__read (clkfreq_fd, type_string,
> -				      sizeof (type_string)) > 0)
> -			    result = (hp_timing_t)
> -			      strtoumax (type_string, NULL, 16);
> -			  __close (clkfreq_fd);
> -			}
> -		    }
> -		  __close (fd);
> -		}
> -
> -	      if (result != 0)
> -		break;
> -
> -	      len -= this_dirp->d_reclen;
> -	      this_dirp = (struct dirent64 *)
> -		((char *) this_dirp + this_dirp->d_reclen);
> -	    }
> -	  if (result != 0)
> -	    break;
> -	}
> -      __close (obp_fd);
> -    }
> -
> -  return result;
> -}
> -
> -static void set_obp_int (struct openpromio *op, int val)
> -{
> -  char *cp = op->oprom_array;
> -  int *ip = (int *) cp;
> -
> -  *ip = val;
> -}
> -
> -static int get_obp_int (struct openpromio *op)
> -{
> -  char *cp = op->oprom_array;
> -  int *ip = (int *) cp;
> -
> -  return *ip;
> -}
> -
> -static hp_timing_t
> -__get_clockfreq_via_dev_openprom (void)
> -{
> -  hp_timing_t result;
> -  int obp_dev_fd;
> -
> -  result = 0;
> -
> -  obp_dev_fd = __open ("/dev/openprom", O_RDONLY);
> -  if (obp_dev_fd != -1)
> -    {
> -      char obp_buf[8192];
> -      struct openpromio *obp_cmd = (struct openpromio *)obp_buf;
> -      int ret;
> -
> -      obp_cmd->oprom_size =
> -	sizeof (obp_buf) - sizeof (unsigned int);
> -      set_obp_int (obp_cmd, 0);
> -      ret = __ioctl (obp_dev_fd, OPROMCHILD, (char *) obp_cmd);
> -      if (ret == 0)
> -	{
> -	  int cur_node = get_obp_int (obp_cmd);
> -
> -	  while (cur_node != 0 && cur_node != -1)
> -	    {
> -	      obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int);
> -	      strcpy (obp_cmd->oprom_array, "device_type");
> -	      ret = __ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd);
> -	      if (ret == 0
> -		  && strncmp (obp_cmd->oprom_array, "cpu", 3) == 0)
> -		{
> -		  obp_cmd->oprom_size = (sizeof (obp_buf)
> -					 - sizeof (unsigned int));
> -		  strcpy (obp_cmd->oprom_array, "clock-frequency");
> -		  ret = __ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd);
> -		  if (ret == 0)
> -		    result = (hp_timing_t) get_obp_int (obp_cmd);
> -		}
> -	      obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int);
> -	      set_obp_int (obp_cmd, cur_node);
> -	      ret = __ioctl (obp_dev_fd, OPROMNEXT, (char *) obp_cmd);
> -	      if (ret < 0)
> -		break;
> -	      cur_node = get_obp_int (obp_cmd);
> -	    }
> -	}
> -    }
> -
> -  return result;
> -}
> -
> -hp_timing_t
> -__get_clockfreq (void)
> -{
> -  static hp_timing_t result;
> -
> -  /* If this function was called before, we know the result.  */
> -  if (result != 0)
> -    return result;
> -
> -  /* We first read the information from the /proc/cpuinfo file.
> -     It contains at least one line like
> -	Cpu0ClkTick         : 000000002cb41780
> -     We search for this line and convert the number in an integer.  */
> -  result = __get_clockfreq_via_cpuinfo ();
> -  if (result != 0)
> -    return result;
> -
> -  /* If that did not work, try to find an OpenPROM node
> -     with device_type equal to 'cpu' using /dev/openprom
> -     and fetch the clock-frequency property from there.  */
> -  result = __get_clockfreq_via_dev_openprom ();
> -  if (result != 0)
> -    return result;
> -
> -  /* Finally, try the same lookup as above but using /proc/openprom.  */
> -  result = __get_clockfreq_via_proc_openprom ();
> -
> -  return result;
> -}
> 

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

* Re: [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime
  2019-02-18 21:11 [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
                   ` (5 preceding siblings ...)
  2019-03-19 17:23 ` [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
@ 2019-03-20 11:32 ` Andreas Schwab
  6 siblings, 0 replies; 14+ messages in thread
From: Andreas Schwab @ 2019-03-20 11:32 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Feb 18 2019, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> 	* nptl/Makefile (libpthread-routines): Remove pthread_clock_gettime and
> 	pthread_clock_settime.
> 	* nptl/pthreadP.h (__find_thread_by_id): Remove prototype.
> 	* elf/dl-support.c [!HP_TIMING_NOAVAIL] (_dl_cpuclock_offset): Remove.
> 	(_dl_non_dynamic_init): Remove _dl_cpuclock_offset setting.
> 	* elf/rtld.c (_dl_start_final): Likewise.
> 	* nptl/allocatestack.c (__find_thread_by_id): Remove function.
> 	* sysdeps/generic/ldsodefs.h [!HP_TIMING_NOAVAIL] (_dl_cpuclock_offset):
> 	Remove.
> 	* sysdeps/mach/hurd/dl-sysdep.c [!HP_TIMING_NOAVAIL]
> 	(_dl_cpuclock_offset): Remove.
> 	* nptl/descr.h (struct pthread): Rename cpuclock_offset to
> 	cpuclock_offset_ununsed.
> 	* nptl/nptl-init.c (__pthread_initialize_minimal_internal): Remove
> 	cpuclock_offset set.
> 	* nptl/pthread_create.c (START_THREAD_DEFN): Likewise.
> 	* sysdeps/nptl/fork.c (__libc_fork): Likewise.
> 	* nptl/pthread_clock_gettime.c: Remove file.
> 	* nptl/pthread_clock_settime.c: Likewise.
> 	* sysdeps/unix/clock_gettime.c (hp_timing_gettime): Remove function.
> 	[HP_TIMING_AVAIL] (realtime_gettime): Remove CLOCK_THREAD_CPUTIME_ID
> 	and CLOCK_PROCESS_CPUTIME_ID support.
> 	* sysdeps/unix/clock_settime.c (hp_timing_gettime): Likewise.
> 	[HP_TIMING_AVAIL] (realtime_gettime): Likewise.
> 	* sysdeps/posix/clock_getres.c (hp_timing_getres): Likewise.
> 	[HP_TIMING_AVAIL] (__clock_getres): Likewise.
> 	* sysdeps/unix/clock_nanosleep.c (CPUCLOCK_P, INVALID_CLOCK_P):
> 	Likewise.
> 	(__clock_nanosleep): Remove CPUCLOCK_P and INVALID_CLOCK_P usage.

Ok.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

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

* Re: [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID
  2019-02-18 21:11 ` [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID Adhemerval Zanella
  2019-03-19 17:24   ` Adhemerval Zanella
@ 2019-03-20 11:49   ` Andreas Schwab
  2019-03-20 14:13     ` Adhemerval Zanella
  1 sibling, 1 reply; 14+ messages in thread
From: Andreas Schwab @ 2019-03-20 11:49 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Feb 18 2019, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> This patch assumes that clock_getres syscall always support
> CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID, so there is no need
> to fallback to hp-timing support for _SC_MONOTONIC_CLOCK.  This allows
> simplify the sysconf support to always use the syscall.

Under which condition can clock_getres return an error for these clocks?

> diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
> index 4b297ba35f..2027444488 100644
> --- a/sysdeps/unix/sysv/linux/sysconf.c
> +++ b/sysdeps/unix/sysv/linux/sysconf.c
> @@ -35,33 +35,18 @@
>  static long int posix_sysconf (int name);
>  
>  
> -#ifndef HAS_CPUCLOCK
>  static long int
> -has_cpuclock (int name)
> +check_clock_getres (clockid_t clk_id)
>  {
> -# if defined __NR_clock_getres || HP_TIMING_AVAIL
> -  /* If we have HP_TIMING, we will fall back on that if the system
> -     call does not work, so we support it either way.  */
> -#  if !HP_TIMING_AVAIL
> -  /* Check using the clock_getres system call.  */
>    struct timespec ts;
>    INTERNAL_SYSCALL_DECL (err);
> -  int r = INTERNAL_SYSCALL (clock_getres, err, 2,
> -			    (name == _SC_CPUTIME
> -			     ? CLOCK_PROCESS_CPUTIME_ID
> -			     : CLOCK_THREAD_CPUTIME_ID),
> -			    &ts);
> +  /* Avoid setting errno to we can check whether the kernel supports

s/to/so/

> +     the CLK_ID.  */
> +  int r = INTERNAL_SYSCALL_CALL (clock_getres, err, clk_id, &ts);
>    if (INTERNAL_SYSCALL_ERROR_P (r, err))
>      return -1;
> -#  endif
>    return _POSIX_VERSION;
> -# else
> -  return -1;
> -# endif
>  }
> -# define HAS_CPUCLOCK(name) has_cpuclock (name)
> -#endif
> -
>  
>  /* Get the value of the system variable NAME.  */
>  long int
> @@ -71,29 +56,21 @@ __sysconf (int name)
>  
>    switch (name)
>      {
> -      struct rlimit rlimit;
> -#ifdef __NR_clock_getres
>      case _SC_MONOTONIC_CLOCK:
> -      /* Check using the clock_getres system call.  */
> -      {
> -	struct timespec ts;
> -	INTERNAL_SYSCALL_DECL (err);
> -	int r;
> -	r = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
> -	return INTERNAL_SYSCALL_ERROR_P (r, err) ? -1 : _POSIX_VERSION;
> -      }
> -#endif
> -
> +      return check_clock_getres (CLOCK_MONOTONIC);
>      case _SC_CPUTIME:
> +      return check_clock_getres (CLOCK_PROCESS_CPUTIME_ID);
>      case _SC_THREAD_CPUTIME:
> -      return HAS_CPUCLOCK (name);
> +      return check_clock_getres (CLOCK_THREAD_CPUTIME_ID);
>  
> -    case _SC_ARG_MAX:
> +    case _SC_ARG_MAX: {

Brace on next line.

> +      struct rlimit rlimit;
>        /* Use getrlimit to get the stack limit.  */
>        if (__getrlimit (RLIMIT_STACK, &rlimit) == 0)
>  	return MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4);
>  
>        return legacy_ARG_MAX;
> +    } break;

No break needed.

>  
>      case _SC_NGROUPS_MAX:
>        /* Try to read the information from the /proc/sys/kernel/ngroups_max
> @@ -101,13 +78,14 @@ __sysconf (int name)
>        procfname = "/proc/sys/kernel/ngroups_max";
>        break;
>  
> -    case _SC_SIGQUEUE_MAX:
> +    case _SC_SIGQUEUE_MAX: {

Brace on next line.

> +      struct rlimit rlimit;
>        if (__getrlimit (RLIMIT_SIGPENDING, &rlimit) == 0)
>  	return rlimit.rlim_cur;
>  
>        /* The /proc/sys/kernel/rtsig-max file contains the answer.  */
>        procfname = "/proc/sys/kernel/rtsig-max";
> -      break;
> +    } break;

Line break after brace.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

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

* Re: [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID
  2019-03-20 11:49   ` Andreas Schwab
@ 2019-03-20 14:13     ` Adhemerval Zanella
  2019-03-20 14:39       ` Andreas Schwab
  0 siblings, 1 reply; 14+ messages in thread
From: Adhemerval Zanella @ 2019-03-20 14:13 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: libc-alpha



On 20/03/2019 08:49, Andreas Schwab wrote:
> On Feb 18 2019, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:
> 
>> This patch assumes that clock_getres syscall always support
>> CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID, so there is no need
>> to fallback to hp-timing support for _SC_MONOTONIC_CLOCK.  This allows
>> simplify the sysconf support to always use the syscall.
> 
> Under which condition can clock_getres return an error for these clocks?

Good question, checking kernel code kernel/posix-cpu-timers.c both
thread_cpu_clock_getres and process_cpu_clock_getres calls
posix_cpu_clock_getres. And it fails on check_clock only if an invalid
clock is used (not the case) or if we pass an invalid the pid/tid in 
29 msb of clock_id (not the case either).

I will just remove the check_clock_getres call.

> 
>> diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
>> index 4b297ba35f..2027444488 100644
>> --- a/sysdeps/unix/sysv/linux/sysconf.c
>> +++ b/sysdeps/unix/sysv/linux/sysconf.c
>> @@ -35,33 +35,18 @@
>>  static long int posix_sysconf (int name);
>>  
>>  
>> -#ifndef HAS_CPUCLOCK
>>  static long int
>> -has_cpuclock (int name)
>> +check_clock_getres (clockid_t clk_id)
>>  {
>> -# if defined __NR_clock_getres || HP_TIMING_AVAIL
>> -  /* If we have HP_TIMING, we will fall back on that if the system
>> -     call does not work, so we support it either way.  */
>> -#  if !HP_TIMING_AVAIL
>> -  /* Check using the clock_getres system call.  */
>>    struct timespec ts;
>>    INTERNAL_SYSCALL_DECL (err);
>> -  int r = INTERNAL_SYSCALL (clock_getres, err, 2,
>> -			    (name == _SC_CPUTIME
>> -			     ? CLOCK_PROCESS_CPUTIME_ID
>> -			     : CLOCK_THREAD_CPUTIME_ID),
>> -			    &ts);
>> +  /* Avoid setting errno to we can check whether the kernel supports
> 
> s/to/so/
> 
>> +     the CLK_ID.  */
>> +  int r = INTERNAL_SYSCALL_CALL (clock_getres, err, clk_id, &ts);
>>    if (INTERNAL_SYSCALL_ERROR_P (r, err))
>>      return -1;
>> -#  endif
>>    return _POSIX_VERSION;
>> -# else
>> -  return -1;
>> -# endif
>>  }
>> -# define HAS_CPUCLOCK(name) has_cpuclock (name)
>> -#endif
>> -
>>  
>>  /* Get the value of the system variable NAME.  */
>>  long int
>> @@ -71,29 +56,21 @@ __sysconf (int name)
>>  
>>    switch (name)
>>      {
>> -      struct rlimit rlimit;
>> -#ifdef __NR_clock_getres
>>      case _SC_MONOTONIC_CLOCK:
>> -      /* Check using the clock_getres system call.  */
>> -      {
>> -	struct timespec ts;
>> -	INTERNAL_SYSCALL_DECL (err);
>> -	int r;
>> -	r = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
>> -	return INTERNAL_SYSCALL_ERROR_P (r, err) ? -1 : _POSIX_VERSION;
>> -      }
>> -#endif
>> -
>> +      return check_clock_getres (CLOCK_MONOTONIC);
>>      case _SC_CPUTIME:
>> +      return check_clock_getres (CLOCK_PROCESS_CPUTIME_ID);
>>      case _SC_THREAD_CPUTIME:
>> -      return HAS_CPUCLOCK (name);
>> +      return check_clock_getres (CLOCK_THREAD_CPUTIME_ID);
>>  
>> -    case _SC_ARG_MAX:
>> +    case _SC_ARG_MAX: {
> 
> Brace on next line.

Ack.

> 
>> +      struct rlimit rlimit;
>>        /* Use getrlimit to get the stack limit.  */
>>        if (__getrlimit (RLIMIT_STACK, &rlimit) == 0)
>>  	return MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4);
>>  
>>        return legacy_ARG_MAX;
>> +    } break;
> 
> No break needed.

Ack.

> 
>>  
>>      case _SC_NGROUPS_MAX:
>>        /* Try to read the information from the /proc/sys/kernel/ngroups_max
>> @@ -101,13 +78,14 @@ __sysconf (int name)
>>        procfname = "/proc/sys/kernel/ngroups_max";
>>        break;
>>  
>> -    case _SC_SIGQUEUE_MAX:
>> +    case _SC_SIGQUEUE_MAX: {
> 
> Brace on next line.

Ack.

> 
>> +      struct rlimit rlimit;
>>        if (__getrlimit (RLIMIT_SIGPENDING, &rlimit) == 0)
>>  	return rlimit.rlim_cur;
>>  
>>        /* The /proc/sys/kernel/rtsig-max file contains the answer.  */
>>        procfname = "/proc/sys/kernel/rtsig-max";
>> -      break;
>> +    } break;
> 
> Line break after brace.

Ack.

> 
> Andreas.
> 

I changed to:

---

For Linux 3.2, the kernel code for clock_getres (kernel/posix-cpu-timers.c)
issued for clock_getres CLOCK_PROCESS_CPUTIME_ID (process_cpu_clock_getres)
and CLOCK_THREAD_CPUTIME_ID (thread_cpu_clock_getres) calls
posix_cpu_clock_getres. And it fails on check_clock only if an invalid
clock is used (not the case) or if we pass an invalid the pid/tid in
29 msb of clock_id (not the case either).

This patch assumes that clock_getres syscall always support
CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID, so there is no need
to fallback to hp-timing support for _SC_MONOTONIC_CLOCK neither to issue
the syscall to certify the clock_id is supported bt the kernel.  This
allows simplify the sysconf support to always use the syscall.

it also removes ia64 itc drift check and assume kernel handles it correctly.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.

	* sysdeps/unix/sysv/linux/ia64/has_cpuclock.c: Remove file.
	* sysdeps/unix/sysv/linux/ia64/sysconf.c: Likewise.
	* sysdeps/unix/sysv/linux/sysconf.c (has_cpuclock): Remove function.
	(__sysconf): Assume kernel support for _SC_MONOTONIC_CLOCK,
	_SC_CPUTIME, and _SC_THREAD_CPUTIME.
---
 sysdeps/unix/sysv/linux/ia64/has_cpuclock.c | 51 ----------------
 sysdeps/unix/sysv/linux/ia64/sysconf.c      | 30 ----------
 sysdeps/unix/sysv/linux/sysconf.c           | 64 +++++----------------
 3 files changed, 15 insertions(+), 130 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/ia64/has_cpuclock.c
 delete mode 100644 sysdeps/unix/sysv/linux/ia64/sysconf.c

diff --git a/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c b/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c
deleted file mode 100644
index b3afb37f8b..0000000000
--- a/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 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 <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <not-cancel.h>
-
-static int itc_usable;
-
-static int
-has_cpuclock (void)
-{
-  if (__builtin_expect (itc_usable == 0, 0))
-    {
-      int newval = 1;
-      int fd = __open_nocancel ("/proc/sal/itc_drift", O_RDONLY);
-      if (__builtin_expect (fd != -1, 1))
-	{
-	  char buf[16];
-	  /* We expect the file to contain a single digit followed by
-	     a newline.  If the format changes we better not rely on
-	     the file content.  */
-	  if (__read_nocancel (fd, buf, sizeof buf) != 2
-	      || buf[0] != '0' || buf[1] != '\n')
-	    newval = -1;
-
-	  __close_nocancel_nostatus (fd);
-	}
-
-      itc_usable = newval;
-    }
-
-  return itc_usable;
-}
diff --git a/sysdeps/unix/sysv/linux/ia64/sysconf.c b/sysdeps/unix/sysv/linux/ia64/sysconf.c
deleted file mode 100644
index ef75322f1f..0000000000
--- a/sysdeps/unix/sysv/linux/ia64/sysconf.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Get file-specific information about a file.  Linux/ia64 version.
-   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 <assert.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-
-#include "has_cpuclock.c"
-#define HAS_CPUCLOCK(name) (has_cpuclock () ? _POSIX_VERSION : -1)
-
-
-/* Now the generic Linux version.  */
-#include <sysdeps/unix/sysv/linux/sysconf.c>
diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
index 4b297ba35f..2492d7a291 100644
--- a/sysdeps/unix/sysv/linux/sysconf.c
+++ b/sysdeps/unix/sysv/linux/sysconf.c
@@ -35,34 +35,6 @@
 static long int posix_sysconf (int name);
 
 
-#ifndef HAS_CPUCLOCK
-static long int
-has_cpuclock (int name)
-{
-# if defined __NR_clock_getres || HP_TIMING_AVAIL
-  /* If we have HP_TIMING, we will fall back on that if the system
-     call does not work, so we support it either way.  */
-#  if !HP_TIMING_AVAIL
-  /* Check using the clock_getres system call.  */
-  struct timespec ts;
-  INTERNAL_SYSCALL_DECL (err);
-  int r = INTERNAL_SYSCALL (clock_getres, err, 2,
-			    (name == _SC_CPUTIME
-			     ? CLOCK_PROCESS_CPUTIME_ID
-			     : CLOCK_THREAD_CPUTIME_ID),
-			    &ts);
-  if (INTERNAL_SYSCALL_ERROR_P (r, err))
-    return -1;
-#  endif
-  return _POSIX_VERSION;
-# else
-  return -1;
-# endif
-}
-# define HAS_CPUCLOCK(name) has_cpuclock (name)
-#endif
-
-
 /* Get the value of the system variable NAME.  */
 long int
 __sysconf (int name)
@@ -71,29 +43,20 @@ __sysconf (int name)
 
   switch (name)
     {
-      struct rlimit rlimit;
-#ifdef __NR_clock_getres
     case _SC_MONOTONIC_CLOCK:
-      /* Check using the clock_getres system call.  */
-      {
-	struct timespec ts;
-	INTERNAL_SYSCALL_DECL (err);
-	int r;
-	r = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
-	return INTERNAL_SYSCALL_ERROR_P (r, err) ? -1 : _POSIX_VERSION;
-      }
-#endif
-
     case _SC_CPUTIME:
     case _SC_THREAD_CPUTIME:
-      return HAS_CPUCLOCK (name);
+      return _POSIX_VERSION;
 
     case _SC_ARG_MAX:
-      /* Use getrlimit to get the stack limit.  */
-      if (__getrlimit (RLIMIT_STACK, &rlimit) == 0)
-	return MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4);
+      {
+        struct rlimit rlimit;
+        /* Use getrlimit to get the stack limit.  */
+        if (__getrlimit (RLIMIT_STACK, &rlimit) == 0)
+	  return MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4);
 
-      return legacy_ARG_MAX;
+        return legacy_ARG_MAX;
+      }
 
     case _SC_NGROUPS_MAX:
       /* Try to read the information from the /proc/sys/kernel/ngroups_max
@@ -102,11 +65,14 @@ __sysconf (int name)
       break;
 
     case _SC_SIGQUEUE_MAX:
-      if (__getrlimit (RLIMIT_SIGPENDING, &rlimit) == 0)
-	return rlimit.rlim_cur;
+      {
+        struct rlimit rlimit;
+        if (__getrlimit (RLIMIT_SIGPENDING, &rlimit) == 0)
+	  return rlimit.rlim_cur;
 
-      /* The /proc/sys/kernel/rtsig-max file contains the answer.  */
-      procfname = "/proc/sys/kernel/rtsig-max";
+        /* The /proc/sys/kernel/rtsig-max file contains the answer.  */
+        procfname = "/proc/sys/kernel/rtsig-max";
+      }
       break;
 
     default:

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

* Re: [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID
  2019-03-20 14:13     ` Adhemerval Zanella
@ 2019-03-20 14:39       ` Andreas Schwab
  0 siblings, 0 replies; 14+ messages in thread
From: Andreas Schwab @ 2019-03-20 14:39 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Mär 20 2019, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> 	* sysdeps/unix/sysv/linux/ia64/has_cpuclock.c: Remove file.
> 	* sysdeps/unix/sysv/linux/ia64/sysconf.c: Likewise.
> 	* sysdeps/unix/sysv/linux/sysconf.c (has_cpuclock): Remove function.
> 	(__sysconf): Assume kernel support for _SC_MONOTONIC_CLOCK,
> 	_SC_CPUTIME, and _SC_THREAD_CPUTIME.

Ok.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

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

* Re: [PATCH v2 3/6] Remove __get_clockfreq
@ 2019-03-20 15:05 Wilco Dijkstra
  0 siblings, 0 replies; 14+ messages in thread
From: Wilco Dijkstra @ 2019-03-20 15:05 UTC (permalink / raw)
  To: libc-alpha@sourceware.org, Adhemerval Zanella; +Cc: nd

Hi,

On 18/02/2019 18:11, Adhemerval Zanella wrote:
> With clock_getres, clock_gettime, and clock_settime refactor to remove the
> generic CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID support through
> hp-timing, there is no usage of internal __get_clockfreq.  This patch removes
> both generic and Linux implementation..
> 
> Checked with a build against aarch64-linux-gnu, i686-linux-gnu, ia64-linux-gnu,
> sparc64-linux-gnu, powerpc-linux-gnu-power4.

LGTM.

Wilco

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

end of thread, other threads:[~2019-03-20 15:05 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-18 21:11 [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
2019-02-18 21:11 ` [PATCH v2 2/6] linux: Assume clock_getres CLOCK_{PROCESS,THREAD}_CPUTIME_ID Adhemerval Zanella
2019-03-19 17:24   ` Adhemerval Zanella
2019-03-20 11:49   ` Andreas Schwab
2019-03-20 14:13     ` Adhemerval Zanella
2019-03-20 14:39       ` Andreas Schwab
2019-02-18 21:11 ` [PATCH v2 3/6] Remove __get_clockfreq Adhemerval Zanella
2019-03-19 17:24   ` Adhemerval Zanella
2019-02-18 21:11 ` [PATCH v2 4/6] Do not use HP_TIMING_NOW for random bits Adhemerval Zanella
2019-02-18 21:11 ` [PATCH v2 5/6] Refactor hp-timing rtld usage Adhemerval Zanella
2019-02-18 21:11 ` [PATCH v2 6/6] Add generic hp-timing support Adhemerval Zanella
2019-03-19 17:23 ` [PATCH v2 1/6] nptl: Remove pthread_clock_gettime pthread_clock_settime Adhemerval Zanella
2019-03-20 11:32 ` Andreas Schwab
  -- strict thread matches above, loose matches on Subject: below --
2019-03-20 15:05 [PATCH v2 3/6] Remove __get_clockfreq Wilco Dijkstra

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