11 //#ifdef HAVE_SYS_TIME_H
18 #if defined(__APPLE__)
19 #include <mach/mach_time.h>
22 static mach_timebase_info_data_t timebase_info;
26 #define MAP_ANONYMOUS MAP_ANON
29 #define TICKS_PER_SEC 1000000000LL
32 unsigned int timer_count;
39 static __thread TlsData tls_data;
40 #define DECL_TLS_DATA TlsData *tls = &tls_data
43 static pthread_key_t tls_data;
44 #define DECL_TLS_DATA TlsData *tls; tls = (TlsData *) pthread_getspecific (tls_data); if (tls == NULL) { tls = (TlsData *) malloc (sizeof (TlsData)); pthread_setspecific (tls_data, tls); }
45 #define TLS_INIT(x) pthread_key_create(&x, NULL)
48 static pthread_mutex_t log_lock = PTHREAD_MUTEX_INITIALIZER;
50 static uint64_t time_inc = 0;
51 typedef uint64_t (*TimeFunc)(void);
53 static TimeFunc time_func;
58 #if defined(__APPLE__)
59 uint64_t time = mach_absolute_time ();
66 struct timespec tspec;
67 clock_gettime (CLOCK_MONOTONIC, &tspec);
68 return ((uint64_t)tspec.tv_sec * TICKS_PER_SEC + tspec.tv_nsec);
72 /* must be power of two */
76 fast_current_time (void)
79 if (tls->timer_count++ & (TIME_ADJ - 1)) {
80 tls->last_time += time_inc;
81 return tls->last_time;
83 tls->last_time = clock_time ();
84 return tls->last_time;
87 #define rdtsc(low,high) \
88 __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
90 #if !defined(__APPLE__)
94 unsigned int low, high;
95 int c1 = sched_getcpu ();
104 return (((uint64_t) high) << 32) + (uint64_t)low;
107 static double cpu_freq;
117 if (!(cpuinfo = fopen ("/proc/cpuinfo", "r")))
119 while (fgets (buf, sizeof(buf), cpuinfo)) {
120 if (sscanf (buf, "cpu MHz : %f", &val) == 1) {
121 /*printf ("got mh: %f\n", val);*/
123 cpu_freq = val * 1000000;
125 if (strncmp (buf, "flags :", 5) == 0) {
126 if (strstr (buf, "constant_tsc")) {
128 /*printf ("have tsc\n");*/
133 return have_flag? have_freq: 0;
137 rdtsc_current_time (void)
140 if (tls->timer_count++ & (TIME_ADJ*8 - 1)) {
142 uint64_t tsc = safe_rdtsc (&cpu);
143 if (cpu != -1 && cpu == tls->last_cpu) {
144 int64_t diff = tsc - tls->last_rdtsc;
147 nsecs = (double)diff/cpu_freq;
148 //printf ("%llu cycles: %llu nsecs\n", diff, nsecs);
149 return tls->last_time + nsecs;
151 printf ("tsc went backwards\n");
154 //printf ("wrong cpu: %d\n", cpu);
157 tls->last_time = clock_time ();
158 tls->last_rdtsc = safe_rdtsc (&tls->last_cpu);
159 return tls->last_time;
166 static uint64_t timer = 0;
171 utils_init (int fast_time)
176 time_func = null_time;
177 } else if (fast_time) {
178 #if defined (__APPLE__)
179 mach_timebase_info (&timebase_info);
180 time_func = fast_current_time;
184 int cpu = sched_getcpu ();
186 timea = clock_time ();
187 timeb = clock_time ();
188 time_inc = (timeb - timea) / TIME_ADJ;
189 /*printf ("time inc: %llu, timea: %llu, timeb: %llu, diff: %llu\n", time_inc, timea, timeb, timec-timeb);*/
190 if (cpu != -1 && have_rdtsc ())
191 time_func = rdtsc_current_time;
193 time_func = fast_current_time;
196 time_func = clock_time;
207 alloc_buffer (int size)
210 ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
211 if (ptr == (void*)-1)
217 free_buffer (void *buf, int size)
225 pthread_mutex_lock (&log_lock);
231 pthread_mutex_unlock (&log_lock);
235 encode_uleb128 (uint64_t value, uint8_t *buf, uint8_t **endbuf)
240 uint8_t b = value & 0x7f;
242 if (value != 0) /* more bytes to come */
250 /* FIXME: make sure this works for 64 bit systems/values */
252 encode_sleb128 (intptr_t value, uint8_t *buf, uint8_t **endbuf)
255 int negative = (value < 0);
256 unsigned int size = 32;
263 /* the following is unnecessary if the
264 * implementation of >>= uses an arithmetic rather
265 * than logical shift for a signed left operand
269 value |= - (1 <<(size - 7));
270 /* sign bit of byte is second high order bit (0x40) */
271 if ((value == 0 && !(byte & 0x40)) ||
272 (value == -1 && (byte & 0x40)))
283 decode_uleb128 (uint8_t *buf, uint8_t **endbuf)
291 res |= (((uint64_t)(b & 0x7f)) << shift);
303 decode_sleb128 (uint8_t *buf, uint8_t **endbuf)
313 res = res | (((int)(b & 0x7f)) << shift);
316 if (shift < 32 && (b & 0x40))
317 res |= - (1 << shift);
330 return (uintptr_t)pthread_self ();