Blame sysdeps/posix/clock_getres.c

Packit Service 82fcde
/* clock_getres -- Get the resolution of a POSIX clockid_t.
Packit Service 82fcde
   Copyright (C) 1999-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <stdint.h>
Packit Service 82fcde
#include <time.h>
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
#include <sys/param.h>
Packit Service 82fcde
#include <libc-internal.h>
Packit Service 1c5418
Packit Service 1c5418
Packit Service 1c5418
#if HP_TIMING_AVAIL
Packit Service 1c5418
static long int nsec;		/* Clock frequency of the processor.  */
Packit Service 1c5418
Packit Service 1c5418
static int
Packit Service 1c5418
hp_timing_getres (struct timespec *res)
Packit Service 1c5418
{
Packit Service 1c5418
  if (__glibc_unlikely (nsec == 0))
Packit Service 1c5418
    {
Packit Service 1c5418
      hp_timing_t freq;
Packit Service 1c5418
Packit Service 1c5418
      /* This can only happen if we haven't initialized the `nsec'
Packit Service 1c5418
	 variable yet.  Do this now.  We don't have to protect this
Packit Service 1c5418
	 code against multiple execution since all of them should
Packit Service 1c5418
	 lead to the same result.  */
Packit Service 1c5418
      freq = __get_clockfreq ();
Packit Service 1c5418
      if (__glibc_unlikely (freq == 0))
Packit Service 1c5418
	/* Something went wrong.  */
Packit Service 1c5418
	return -1;
Packit Service 1c5418
Packit Service 1c5418
      nsec = MAX (UINT64_C (1000000000) / freq, 1);
Packit Service 1c5418
    }
Packit Service 1c5418
Packit Service 1c5418
  /* Fill in the values.
Packit Service 1c5418
     The seconds are always zero (unless we have a 1Hz machine).  */
Packit Service 1c5418
  res->tv_sec = 0;
Packit Service 1c5418
  res->tv_nsec = nsec;
Packit Service 1c5418
Packit Service 1c5418
  return 0;
Packit Service 1c5418
}
Packit Service 1c5418
#endif
Packit Service 82fcde
Packit Service 82fcde
static inline int
Packit Service 82fcde
realtime_getres (struct timespec *res)
Packit Service 82fcde
{
Packit Service 82fcde
  long int clk_tck = __sysconf (_SC_CLK_TCK);
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_likely (clk_tck != -1))
Packit Service 82fcde
    {
Packit Service 82fcde
      /* This implementation assumes that the realtime clock has a
Packit Service 82fcde
	 resolution higher than 1 second.  This is the case for any
Packit Service 82fcde
	 reasonable implementation.  */
Packit Service 82fcde
      res->tv_sec = 0;
Packit Service 82fcde
      res->tv_nsec = 1000000000 / clk_tck;
Packit Service 82fcde
      return 0;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return -1;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Get resolution of clock.  */
Packit Service 82fcde
int
Packit Service 82fcde
__clock_getres (clockid_t clock_id, struct timespec *res)
Packit Service 82fcde
{
Packit Service 82fcde
  int retval = -1;
Packit Service 82fcde
Packit Service 82fcde
  switch (clock_id)
Packit Service 82fcde
    {
Packit Service 1c5418
#ifdef SYSDEP_GETRES
Packit Service 1c5418
      SYSDEP_GETRES;
Packit Service 1c5418
#endif
Packit Service 1c5418
Packit Service 1c5418
#ifndef HANDLED_REALTIME
Packit Service 82fcde
    case CLOCK_REALTIME:
Packit Service 82fcde
      retval = realtime_getres (res);
Packit Service 82fcde
      break;
Packit Service 1c5418
#endif	/* handled REALTIME */
Packit Service 82fcde
Packit Service 82fcde
    default:
Packit Service 1c5418
#ifdef SYSDEP_GETRES_CPU
Packit Service 1c5418
      SYSDEP_GETRES_CPU;
Packit Service 1c5418
#endif
Packit Service 1c5418
#if HP_TIMING_AVAIL
Packit Service 1c5418
      if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
Packit Service 1c5418
	  == CLOCK_THREAD_CPUTIME_ID)
Packit Service 1c5418
	retval = hp_timing_getres (res);
Packit Service 1c5418
      else
Packit Service 1c5418
#endif
Packit Service 1c5418
	__set_errno (EINVAL);
Packit Service 82fcde
      break;
Packit Service 1c5418
Packit Service 1c5418
#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
Packit Service 1c5418
    case CLOCK_PROCESS_CPUTIME_ID:
Packit Service 1c5418
    case CLOCK_THREAD_CPUTIME_ID:
Packit Service 1c5418
      retval = hp_timing_getres (res);
Packit Service 1c5418
      break;
Packit Service 1c5418
#endif
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return retval;
Packit Service 82fcde
}
Packit Service 1c5418
weak_alias (__clock_getres, clock_getres)