2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief platform neutral timing utilities
23 * @version $Id: debug.c 17143 2008-01-02 20:56:33Z beck $
34 #define WIN32_LEAN_AND_MEAN
38 /* Win32 timer value. */
40 unsigned lo_prec; /**< 32bit low precision time in milli seconds */
41 LARGE_INTEGER hi_prec; /**< 64bit high precision time in micro seconds */
47 #define HAVE_GETTIMEOFDAY
50 * Just, if we have gettimeofday()
51 * Someday, we will have a check here.
58 /* Linux timer value. */
59 typedef struct timeval ir_timer_val_t;
65 static inline void _time_get(ir_timer_val_t *val);
66 static inline void _time_reset(ir_timer_val_t *val);
67 static inline unsigned long _time_to_msec(const ir_timer_val_t *val);
68 static inline ir_timer_val_t *_time_add(ir_timer_val_t *res,
69 const ir_timer_val_t *lhs, const ir_timer_val_t *rhs);
70 static inline ir_timer_val_t *_time_sub(ir_timer_val_t *res,
71 const ir_timer_val_t *lhs, const ir_timer_val_t *rhs);
77 ir_timer_val_t elapsed; /**< the elapsed time so far */
78 ir_timer_val_t start; /**< the start value of the timer */
79 ir_timer_t *link; /**< link to the next entry in the timer stack */
80 unsigned running : 1; /**< set if this timer is running */
83 /** The top of the timer stack */
84 static ir_timer_t *timer_stack;
86 ir_timer_t *ir_timer_new(void)
88 ir_timer_t *timer = XMALLOCZ(ir_timer_t);
90 _time_reset(&timer->elapsed);
91 _time_reset(&timer->start);
98 void ir_timer_free(ir_timer_t *timer)
103 #ifdef HAVE_GETTIMEOFDAY
105 static inline void _time_get(ir_timer_val_t *val)
107 gettimeofday(val, NULL);
110 static inline void _time_reset(ir_timer_val_t *val)
115 static inline unsigned long _time_to_msec(const ir_timer_val_t *elapsed)
117 return (unsigned long) elapsed->tv_sec * 1000UL
118 + (unsigned long) elapsed->tv_usec / 1000UL;
121 static inline unsigned long _time_to_usec(const ir_timer_val_t *elapsed)
123 return (unsigned long) elapsed->tv_sec * 1000000UL
124 + (unsigned long) elapsed->tv_usec;
127 static inline ir_timer_val_t *_time_add(ir_timer_val_t *res,
128 const ir_timer_val_t *lhs, const ir_timer_val_t *rhs)
130 timeradd(lhs, rhs, res);
134 static inline ir_timer_val_t *_time_sub(ir_timer_val_t *res,
135 const ir_timer_val_t *lhs, const ir_timer_val_t *rhs)
137 timersub(lhs, rhs, res);
141 #elif defined(_WIN32)
143 static inline void _time_get(ir_timer_val_t *val)
145 if(!QueryPerformanceCounter(&val->hi_prec))
146 val->lo_prec = timeGetTime();
149 static inline void _time_reset(ir_timer_val_t *val)
151 memset(val, 0, sizeof(val[0]));
154 static inline unsigned long _time_to_msec(const ir_timer_val_t *elapsed)
158 if(!QueryPerformanceFrequency(&freq))
159 return (unsigned long) elapsed->lo_prec;
161 return (unsigned long) ((elapsed->hi_prec.QuadPart * 1000) / freq.QuadPart);
164 static inline unsigned long _time_to_usec(const ir_timer_val_t *elapsed)
168 if(!QueryPerformanceFrequency(&freq))
169 return (unsigned long) elapsed->lo_prec;
171 return (unsigned long) ((elapsed->hi_prec.QuadPart * 1000000) / freq.QuadPart);
174 static inline ir_timer_val_t *_time_add(ir_timer_val_t *res, const ir_timer_val_t *lhs, const ir_timer_val_t *rhs)
177 if(QueryPerformanceFrequency(&dummy))
178 res->hi_prec.QuadPart = lhs->hi_prec.QuadPart + rhs->hi_prec.QuadPart;
180 res->lo_prec = lhs->lo_prec + rhs->lo_prec;
185 static inline ir_timer_val_t *_time_sub(ir_timer_val_t *res, const ir_timer_val_t *lhs, const ir_timer_val_t *rhs)
188 if(QueryPerformanceFrequency(&dummy))
189 res->hi_prec.QuadPart = lhs->hi_prec.QuadPart - rhs->hi_prec.QuadPart;
191 res->lo_prec = lhs->lo_prec - rhs->lo_prec;
198 #if defined(_XOPEN_REALTIME) && _XOPEN_REALTIME != -1
200 #include <sys/types.h>
203 static struct sched_param std_sched_param;
204 static int std_sched_param_init = 0;
206 int ir_timer_enter_high_priority(void)
208 pid_t pid = getpid();
210 struct sched_param p;
213 if(!std_sched_param_init) {
214 res = sched_getparam(pid, &std_sched_param);
215 std_sched_param_init = 1;
218 algo = sched_getscheduler(pid);
219 max = sched_get_priority_max(algo);
221 memcpy(&p, &std_sched_param, sizeof(p));
222 p.sched_priority = max;
223 res = sched_setparam(pid, &p);
228 int ir_timer_leave_high_priority(void)
231 pid_t pid = getpid();
233 if(std_sched_param_init)
234 res = sched_setparam(pid, &std_sched_param);
239 #elif defined(_WIN32)
241 static int initial_priority = THREAD_PRIORITY_NORMAL;
243 int ir_timer_leave_high_priority(void)
246 if(!SetThreadPriority(GetCurrentThread(), initial_priority)) {
247 fprintf(stderr, "Failed to leave high priority (%d)\n", GetLastError());
248 res = GetLastError();
254 int ir_timer_enter_high_priority(void)
257 initial_priority = GetThreadPriority(GetCurrentThread());
258 if(!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) {
259 fprintf(stderr, "Failed to enter high priority (%d)\n", GetLastError());
260 res = GetLastError();
269 int ir_timer_enter_high_priority(void)
271 fprintf(stderr, "POSIX scheduling API not present\n");
275 int ir_timer_leave_high_priority(void)
286 size_t ir_get_heap_used_bytes(void)
288 struct mallinfo mi = mallinfo();
292 #elif defined(_WIN32) /* __linux__ */
296 size_t ir_get_heap_used_bytes(void)
301 hinfo._pentry = NULL;
302 while((heapstatus = _heapwalk(&hinfo)) == _HEAPOK)
303 res += hinfo._useflag == _USEDENTRY ? hinfo._size : 0;
309 size_t ir_get_heap_used_bytes(void)
311 fprintf(stderr, "function not implemented\n");
318 void ir_timer_reset(ir_timer_t *timer)
320 _time_reset(&timer->elapsed);
321 _time_reset(&timer->start);
326 void ir_timer_start(ir_timer_t *timer)
328 _time_reset(&timer->start);
329 _time_get(&timer->start);
333 void ir_timer_reset_and_start(ir_timer_t *timer)
335 _time_reset(&timer->elapsed);
336 ir_timer_start(timer);
339 /* stop a running timer */
340 void ir_timer_stop(ir_timer_t *timer)
342 /* If the timer is running stop, measure the time and add it to the
350 _time_add(&timer->elapsed, &timer->elapsed, _time_sub(&tgt, &val, &timer->start));
351 _time_reset(&timer->start);
355 /* push a timer on the stack */
356 int ir_timer_push(ir_timer_t *timer)
360 timer->link = timer_stack;
362 ir_timer_stop(timer_stack);
363 ir_timer_start(timer);
368 /* pop a timer from the stack */
369 ir_timer_t *ir_timer_pop(void)
371 ir_timer_t *timer = timer_stack;
373 ir_timer_stop(timer);
374 timer_stack = timer->link;
377 ir_timer_start(timer_stack);
382 unsigned long ir_timer_elapsed_msec(const ir_timer_t *timer)
385 const ir_timer_val_t *elapsed = &timer->elapsed;
390 _time_add(&v, &timer->elapsed, _time_sub(&v, &v, &timer->start));
392 return _time_to_msec(elapsed);
395 unsigned long ir_timer_elapsed_usec(const ir_timer_t *timer)
398 const ir_timer_val_t *elapsed = &timer->elapsed;
403 _time_add(&v, &timer->elapsed, _time_sub(&v, &v, &timer->start));
405 return _time_to_usec(elapsed);