Back to index

glibc  2.9
clock_gettime.c
Go to the documentation of this file.
00001 /* clock_gettime -- Get the current time from a POSIX clockid_t.  Unix version.
00002    Copyright (C) 1999-2004, 2005, 2007 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 <sys/time.h>
00024 #include <libc-internal.h>
00025 #include <ldsodefs.h>
00026 
00027 
00028 #if HP_TIMING_AVAIL
00029 /* Clock frequency of the processor.  We make it a 64-bit variable
00030    because some jokers are already playing with processors with more
00031    than 4GHz.  */
00032 static hp_timing_t freq;
00033 
00034 
00035 /* This function is defined in the thread library.  */
00036 extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
00037                                 struct timespec *tp)
00038      __attribute__ ((__weak__));
00039 
00040 static int
00041 hp_timing_gettime (clockid_t clock_id, struct timespec *tp)
00042 {
00043   hp_timing_t tsc;
00044 
00045   if (__builtin_expect (freq == 0, 0))
00046     {
00047       /* This can only happen if we haven't initialized the `freq'
00048         variable yet.  Do this now. We don't have to protect this
00049         code against multiple execution since all of them should
00050         lead to the same result.  */
00051       freq = __get_clockfreq ();
00052       if (__builtin_expect (freq == 0, 0))
00053        /* Something went wrong.  */
00054        return -1;
00055     }
00056 
00057   if (clock_id != CLOCK_PROCESS_CPUTIME_ID
00058       && __pthread_clock_gettime != NULL)
00059     return __pthread_clock_gettime (clock_id, freq, tp);
00060 
00061   /* Get the current counter.  */
00062   HP_TIMING_NOW (tsc);
00063 
00064   /* Compute the offset since the start time of the process.  */
00065   tsc -= GL(dl_cpuclock_offset);
00066 
00067   /* Compute the seconds.  */
00068   tp->tv_sec = tsc / freq;
00069 
00070   /* And the nanoseconds.  This computation should be stable until
00071      we get machines with about 16GHz frequency.  */
00072   tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq;
00073 
00074   return 0;
00075 }
00076 #endif
00077 
00078 
00079 static inline int
00080 realtime_gettime (struct timespec *tp)
00081 {
00082   struct timeval tv;
00083   int retval = gettimeofday (&tv, NULL);
00084   if (retval == 0)
00085     /* Convert into `timespec'.  */
00086     TIMEVAL_TO_TIMESPEC (&tv, tp);
00087   return retval;
00088 }
00089 
00090 
00091 /* Get current value of CLOCK and store it in TP.  */
00092 int
00093 clock_gettime (clockid_t clock_id, struct timespec *tp)
00094 {
00095   int retval = -1;
00096 
00097   switch (clock_id)
00098     {
00099 #ifdef SYSDEP_GETTIME
00100       SYSDEP_GETTIME;
00101 #endif
00102 
00103 #ifndef HANDLED_REALTIME
00104     case CLOCK_REALTIME:
00105       {
00106        struct timeval tv;
00107        retval = gettimeofday (&tv, NULL);
00108        if (retval == 0)
00109          TIMEVAL_TO_TIMESPEC (&tv, tp);
00110       }
00111       break;
00112 #endif
00113 
00114     default:
00115 #ifdef SYSDEP_GETTIME_CPU
00116       SYSDEP_GETTIME_CPU;
00117 #endif
00118 #if HP_TIMING_AVAIL
00119       if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
00120          == CLOCK_THREAD_CPUTIME_ID)
00121        retval = hp_timing_gettime (clock_id, tp);
00122       else
00123 #endif
00124        __set_errno (EINVAL);
00125       break;
00126 
00127 #if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
00128     case CLOCK_PROCESS_CPUTIME_ID:
00129       retval = hp_timing_gettime (clock_id, tp);
00130       break;
00131 #endif
00132     }
00133 
00134   return retval;
00135 }
00136 librt_hidden_def (clock_gettime)