7 #include <sys/unistd.h>
10 #include "gettimeofdayex.h"
12 #if defined(__linux) && !defined(ALPHA)
15 #define rdtsc(low, high) \
16 asm volatile("rdtsc":"=a" (low), "=d" (high))
18 /* get cycle counts */
23 unsigned long __cc_low__,__cc_high__; \
24 rdtsc(__cc_low__,__cc_high__); \
26 cc = (cc << 32) + __cc_low__; \
30 /*-------------------------------------------------------------------------*/
32 get_cpu_speed(double* cpu_speed)
40 if (cpu_speed == NULL)
43 if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
46 while ((num = getline(&line, &len, fp)) != -1) {
47 ptr = strtok(line, ":\n");
48 if (ptr && strstr(ptr, "cpu MHz")) {
49 ptr = strtok(0," \r\t\n");
50 *cpu_speed = strtod(ptr, 0);
58 return (*cpu_speed == 0) ? -1 : 0;
61 /*--------------------------------------------------------------------------*/
63 gettimeofdayex(struct timeval *tv, struct timezone *tz)
65 #define MAX_64_BIT_NUM ((unsigned long long)(-1))
67 /* TO DO: timezone adjustment */
68 static int first = 1, impossible = 0;
69 static double cpu_speed;
70 static struct timeval start;
71 static unsigned long long cc_start;
72 unsigned long long cc_now, cc_diff, usec;
74 /* initialize : get the current time
75 and fix it as a starting point */
77 if (get_cpu_speed(&cpu_speed) < 0)
81 gettimeofday(&start, 0);
88 /* if it's impossible to get cycle counts,
89 then use original gettimeofday() */
91 return gettimeofday(tv, tz);
96 /* when overflow happens, we need to take care of the carry bit,
97 otherwise we get wrong result since we are using unsigned variables.
98 assuming cycle counter starts from zero at time zero,
99 this would happen after 136 years on 4GHz CPU.
100 however, lets just play on the safer side.
103 cc_diff = (cc_now < cc_start) ? cc_now + (MAX_64_BIT_NUM - cc_start)
105 usec = (unsigned long long)(cc_diff / cpu_speed);
108 tv->tv_sec += (usec / 1000000);
109 tv->tv_usec += (usec % 1000000);
111 if (tv->tv_usec >= 1000000) {
113 tv->tv_usec -= 1000000;
120 /*--------------------------------------------------------------------------*/
124 /* simple version of time() */
127 gettimeofdayex(&s, NULL);
129 *t = (time_t)s.tv_sec;
131 return (time_t)s.tv_sec;
136 /*--------------------------------------------------------------------------*/
138 gettimeofdayex(struct timeval *tv, struct timezone *tz)
140 return(gettimeofday(tv, tz));
142 /*--------------------------------------------------------------------------*/
148 /*--------------------------------------------------------------------------*/