Back to index

glibc  2.9
clock_getres.c
Go to the documentation of this file.
00001 /* clock_getres -- Get the resolution of a POSIX clockid_t.
00002    Copyright (C) 1999,2000,2001,2003,2004,2008 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <errno.h>
00021 #include <stdint.h>
00022 #include <time.h>
00023 #include <unistd.h>
00024 #include <sys/param.h>
00025 #include <libc-internal.h>
00026 
00027 
00028 #if HP_TIMING_AVAIL
00029 static long int nsec;              /* Clock frequency of the processor.  */
00030 
00031 static int
00032 hp_timing_getres (struct timespec *res)
00033 {
00034   if (__builtin_expect (nsec == 0, 0))
00035     {
00036       hp_timing_t freq;
00037 
00038       /* This can only happen if we haven't initialized the `nsec'
00039         variable yet.  Do this now.  We don't have to protect this
00040         code against multiple execution since all of them should
00041         lead to the same result.  */
00042       freq = __get_clockfreq ();
00043       if (__builtin_expect (freq == 0, 0))
00044        /* Something went wrong.  */
00045        return -1;
00046 
00047       nsec = MAX (UINT64_C (1000000000) / freq, 1);
00048     }
00049 
00050   /* Fill in the values.
00051      The seconds are always zero (unless we have a 1Hz machine).  */
00052   res->tv_sec = 0;
00053   res->tv_nsec = nsec;
00054 
00055   return 0;
00056 }
00057 #endif
00058 
00059 static inline int
00060 realtime_getres (struct timespec *res)
00061 {
00062   long int clk_tck = sysconf (_SC_CLK_TCK);
00063 
00064   if (__builtin_expect (clk_tck != -1, 1))
00065     {
00066       /* This implementation assumes that the realtime clock has a
00067         resolution higher than 1 second.  This is the case for any
00068         reasonable implementation.  */
00069       res->tv_sec = 0;
00070       res->tv_nsec = 1000000000 / clk_tck;
00071       return 0;
00072     }
00073 
00074   return -1;
00075 }
00076 
00077 
00078 /* Get resolution of clock.  */
00079 int
00080 clock_getres (clockid_t clock_id, struct timespec *res)
00081 {
00082   int retval = -1;
00083 
00084   switch (clock_id)
00085     {
00086 #ifdef SYSDEP_GETRES
00087       SYSDEP_GETRES;
00088 #endif
00089 
00090 #ifndef HANDLED_REALTIME
00091     case CLOCK_REALTIME:
00092       retval = realtime_getres (res);
00093       break;
00094 #endif /* handled REALTIME */
00095 
00096     default:
00097 #ifdef SYSDEP_GETRES_CPU
00098       SYSDEP_GETRES_CPU;
00099 #endif
00100 #if HP_TIMING_AVAIL
00101       if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
00102          == CLOCK_THREAD_CPUTIME_ID)
00103        retval = hp_timing_getres (res);
00104       else
00105 #endif
00106        __set_errno (EINVAL);
00107       break;
00108 
00109 #if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
00110     case CLOCK_PROCESS_CPUTIME_ID:
00111     case CLOCK_THREAD_CPUTIME_ID:
00112       retval = hp_timing_getres (res);
00113       break;
00114 #endif
00115     }
00116 
00117   return retval;
00118 }