11 //#ifdef HAVE_SYS_TIME_H
18 #define TICKS_PER_SEC 1000000000LL
21 unsigned int timer_count;
27 static __thread TlsData tls_data;
28 #define DECL_TLS_DATA TlsData *tls = &tls_data
30 static pthread_mutex_t log_lock = PTHREAD_MUTEX_INITIALIZER;
32 static uint64_t time_inc = 0;
33 typedef uint64_t (*TimeFunc)(void);
35 static TimeFunc time_func;
40 struct timespec tspec;
41 clock_gettime (CLOCK_MONOTONIC, &tspec);
42 return ((uint64_t)tspec.tv_sec * TICKS_PER_SEC + tspec.tv_nsec);
45 /* must be power of two */
49 fast_current_time (void)
52 if (tls->timer_count++ & (TIME_ADJ - 1)) {
53 tls->last_time += time_inc;
54 return tls->last_time;
56 tls->last_time = clock_time ();
57 return tls->last_time;
60 #define rdtsc(low,high) \
61 __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
66 unsigned int low, high;
67 int c1 = sched_getcpu ();
76 return (((uint64_t) high) << 32) + (uint64_t)low;
79 static double cpu_freq;
89 if (!(cpuinfo = fopen ("/proc/cpuinfo", "r")))
91 while (fgets (buf, sizeof(buf), cpuinfo)) {
92 if (sscanf (buf, "cpu MHz : %f", &val) == 1) {
93 /*printf ("got mh: %f\n", val);*/
95 cpu_freq = val * 1000000;
97 if (strncmp (buf, "flags :", 5) == 0) {
98 if (strstr (buf, "constant_tsc")) {
100 /*printf ("have tsc\n");*/
105 return have_flag? have_freq: 0;
109 rdtsc_current_time (void)
112 if (tls->timer_count++ & (TIME_ADJ*8 - 1)) {
114 uint64_t tsc = safe_rdtsc (&cpu);
115 if (cpu != -1 && cpu == tls->last_cpu) {
116 int64_t diff = tsc - tls->last_rdtsc;
119 nsecs = (double)diff/cpu_freq;
120 //printf ("%llu cycles: %llu nsecs\n", diff, nsecs);
121 return tls->last_time + nsecs;
123 printf ("tsc went backwards\n");
126 //printf ("wrong cpu: %d\n", cpu);
129 tls->last_time = clock_time ();
130 tls->last_rdtsc = safe_rdtsc (&tls->last_cpu);
131 return tls->last_time;
137 static uint64_t timer = 0;
142 utils_init (int fast_time)
145 time_func = null_time;
146 } else if (fast_time) {
149 int cpu = sched_getcpu ();
151 timea = clock_time ();
152 timeb = clock_time ();
153 time_inc = (timeb - timea) / TIME_ADJ;
154 /*printf ("time inc: %llu, timea: %llu, timeb: %llu, diff: %llu\n", time_inc, timea, timeb, timec-timeb);*/
155 if (cpu != -1 && have_rdtsc ())
156 time_func = rdtsc_current_time;
158 time_func = fast_current_time;
160 time_func = clock_time;
171 alloc_buffer (int size)
174 ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
175 if (ptr == (void*)-1)
181 free_buffer (void *buf, int size)
189 pthread_mutex_lock (&log_lock);
195 pthread_mutex_unlock (&log_lock);
199 encode_uleb128 (uint64_t value, uint8_t *buf, uint8_t **endbuf)
204 uint8_t b = value & 0x7f;
206 if (value != 0) /* more bytes to come */
214 /* FIXME: make sure this works for 64 bit systems/values */
216 encode_sleb128 (intptr_t value, uint8_t *buf, uint8_t **endbuf)
219 int negative = (value < 0);
220 unsigned int size = 32;
227 /* the following is unnecessary if the
228 * implementation of >>= uses an arithmetic rather
229 * than logical shift for a signed left operand
233 value |= - (1 <<(size - 7));
234 /* sign bit of byte is second high order bit (0x40) */
235 if ((value == 0 && !(byte & 0x40)) ||
236 (value == -1 && (byte & 0x40)))
247 decode_uleb128 (uint8_t *buf, uint8_t **endbuf)
255 res |= (((uint64_t)(b & 0x7f)) << shift);
267 decode_sleb128 (uint8_t *buf, uint8_t **endbuf)
277 res = res | (((int)(b & 0x7f)) << shift);
280 if (shift < 32 && (b & 0x40))
281 res |= - (1 << shift);
294 return (uintptr_t)pthread_self ();