2.9
[glibc/nacl-glibc.git] / sysdeps / unix / clock_gettime.c
blobfbaaf301e4c39439b35cea3ef101a86aba14f643
1 /* clock_gettime -- Get the current time from a POSIX clockid_t. Unix version.
2 Copyright (C) 1999-2004, 2005, 2007 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include <errno.h>
21 #include <stdint.h>
22 #include <time.h>
23 #include <sys/time.h>
24 #include <libc-internal.h>
25 #include <ldsodefs.h>
28 #if HP_TIMING_AVAIL
29 /* Clock frequency of the processor. We make it a 64-bit variable
30 because some jokers are already playing with processors with more
31 than 4GHz. */
32 static hp_timing_t freq;
35 /* This function is defined in the thread library. */
36 extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
37 struct timespec *tp)
38 __attribute__ ((__weak__));
40 static int
41 hp_timing_gettime (clockid_t clock_id, struct timespec *tp)
43 hp_timing_t tsc;
45 if (__builtin_expect (freq == 0, 0))
47 /* This can only happen if we haven't initialized the `freq'
48 variable yet. Do this now. We don't have to protect this
49 code against multiple execution since all of them should
50 lead to the same result. */
51 freq = __get_clockfreq ();
52 if (__builtin_expect (freq == 0, 0))
53 /* Something went wrong. */
54 return -1;
57 if (clock_id != CLOCK_PROCESS_CPUTIME_ID
58 && __pthread_clock_gettime != NULL)
59 return __pthread_clock_gettime (clock_id, freq, tp);
61 /* Get the current counter. */
62 HP_TIMING_NOW (tsc);
64 /* Compute the offset since the start time of the process. */
65 tsc -= GL(dl_cpuclock_offset);
67 /* Compute the seconds. */
68 tp->tv_sec = tsc / freq;
70 /* And the nanoseconds. This computation should be stable until
71 we get machines with about 16GHz frequency. */
72 tp->tv_nsec = ((tsc % freq) * UINT64_C (1000000000)) / freq;
74 return 0;
76 #endif
79 static inline int
80 realtime_gettime (struct timespec *tp)
82 struct timeval tv;
83 int retval = gettimeofday (&tv, NULL);
84 if (retval == 0)
85 /* Convert into `timespec'. */
86 TIMEVAL_TO_TIMESPEC (&tv, tp);
87 return retval;
91 /* Get current value of CLOCK and store it in TP. */
92 int
93 clock_gettime (clockid_t clock_id, struct timespec *tp)
95 int retval = -1;
97 switch (clock_id)
99 #ifdef SYSDEP_GETTIME
100 SYSDEP_GETTIME;
101 #endif
103 #ifndef HANDLED_REALTIME
104 case CLOCK_REALTIME:
106 struct timeval tv;
107 retval = gettimeofday (&tv, NULL);
108 if (retval == 0)
109 TIMEVAL_TO_TIMESPEC (&tv, tp);
111 break;
112 #endif
114 default:
115 #ifdef SYSDEP_GETTIME_CPU
116 SYSDEP_GETTIME_CPU;
117 #endif
118 #if HP_TIMING_AVAIL
119 if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
120 == CLOCK_THREAD_CPUTIME_ID)
121 retval = hp_timing_gettime (clock_id, tp);
122 else
123 #endif
124 __set_errno (EINVAL);
125 break;
127 #if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
128 case CLOCK_PROCESS_CPUTIME_ID:
129 retval = hp_timing_gettime (clock_id, tp);
130 break;
131 #endif
134 return retval;
136 librt_hidden_def (clock_gettime)