X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fcommon%2Ftiming.c;h=61dd041309f12cdb78291079224c23b1e8532c35;hb=79268f7122ba8f5820658967157b3a9c78ea492a;hp=83f9adf8b2784040b7cb72c5f13346b402acbcd2;hpb=bb9f2e36362333c6635b89f5258171b06c786608;p=libfirm diff --git a/ir/common/timing.c b/ir/common/timing.c index 83f9adf8b..61dd04130 100644 --- a/ir/common/timing.c +++ b/ir/common/timing.c @@ -20,20 +20,15 @@ /** * @file * @brief platform neutral timing utilities - * @version $Id: debug.c 17143 2008-01-02 20:56:33Z beck $ */ #include "config.h" #include #include -#ifndef _WIN32 -#include -#endif - #include "timing.h" -#include "set.h" -#include "hashptr.h" +#include "xmalloc.h" +#include "error.h" #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -48,6 +43,7 @@ typedef union { #else +#include #define HAVE_GETTIMEOFDAY /* @@ -66,66 +62,33 @@ typedef struct timeval ir_timer_val_t; #include -static inline void _time_get(ir_timer_val_t *val); static inline void _time_reset(ir_timer_val_t *val); -static inline unsigned long _time_to_msec(const ir_timer_val_t *val); -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); -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); /** * A timer. */ -struct _ir_timer_t { +struct ir_timer_t { ir_timer_val_t elapsed; /**< the elapsed time so far */ ir_timer_val_t start; /**< the start value of the timer */ - ir_timer_t *link; /**< link to the next entry in the timer stack */ - const char *name; /**< the name of the timer used for identification */ - const char *desc; /**< a description if the timer */ + ir_timer_t *parent; /**< parent of a timer */ + ir_timer_t *displaced; /**< former timer in case of timer_push */ unsigned running : 1; /**< set if this timer is running */ }; -/** - * Compare two timers. - */ -static int ir_timer_cmp(const void *a, const void *b, size_t size) -{ - const ir_timer_t *t1 = a; - const ir_timer_t *t2 = b; - (void) size; - return strcmp(t1->name, t2->name); -} - -/** The set containing all currently registered timers. */ -static set *timers = NULL; - /** The top of the timer stack */ static ir_timer_t *timer_stack; -/** Initialize the timer module. */ -static void timing_init(void) +ir_timer_t *ir_timer_new(void) { - timers = new_set(ir_timer_cmp, 16); - timer_stack = NULL; + ir_timer_t *timer = XMALLOCZ(ir_timer_t); + _time_reset(&timer->elapsed); + _time_reset(&timer->start); + return timer; } -ir_timer_t *ir_timer_register(const char *name, const char *desc) +void ir_timer_free(ir_timer_t *timer) { - unsigned hash = HASH_STR(name, strlen(name)); - ir_timer_t timer; - - _time_reset(&timer.elapsed); - _time_reset(&timer.start); - timer.link = NULL; - timer.name = name; - timer.desc = desc; - timer.running = 0; - - if (!timers) - timing_init(); - - return set_insert(timers, &timer, sizeof(timer), hash); + xfree(timer); } #ifdef HAVE_GETTIMEOFDAY @@ -152,6 +115,11 @@ static inline unsigned long _time_to_usec(const ir_timer_val_t *elapsed) + (unsigned long) elapsed->tv_usec; } +static inline double _time_to_sec(const ir_timer_val_t *elapsed) +{ + return (double)elapsed->tv_sec + (double)elapsed->tv_usec / 1000000.0; +} + 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) { @@ -170,7 +138,7 @@ static inline ir_timer_val_t *_time_sub(ir_timer_val_t *res, static inline void _time_get(ir_timer_val_t *val) { - if(!QueryPerformanceCounter(&val->hi_prec)) + if (!QueryPerformanceCounter(&val->hi_prec)) val->lo_prec = timeGetTime(); } @@ -183,7 +151,7 @@ static inline unsigned long _time_to_msec(const ir_timer_val_t *elapsed) { LARGE_INTEGER freq; - if(!QueryPerformanceFrequency(&freq)) + if (!QueryPerformanceFrequency(&freq)) return (unsigned long) elapsed->lo_prec; return (unsigned long) ((elapsed->hi_prec.QuadPart * 1000) / freq.QuadPart); @@ -193,16 +161,26 @@ static inline unsigned long _time_to_usec(const ir_timer_val_t *elapsed) { LARGE_INTEGER freq; - if(!QueryPerformanceFrequency(&freq)) - return (unsigned long) elapsed->lo_prec; + if (!QueryPerformanceFrequency(&freq)) + return (unsigned long) elapsed->lo_prec * 1000; return (unsigned long) ((elapsed->hi_prec.QuadPart * 1000000) / freq.QuadPart); } +static inline double _time_to_sec(const ir_timer_val_t *elapsed) +{ + LARGE_INTEGER freq; + + if (!QueryPerformanceFrequency(&freq)) + return (double) elapsed->lo_prec / 1000.; + + return (double)elapsed->hi_prec.QuadPart / (double)freq.QuadPart; +} + 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) { LARGE_INTEGER dummy; - if(QueryPerformanceFrequency(&dummy)) + if (QueryPerformanceFrequency(&dummy)) res->hi_prec.QuadPart = lhs->hi_prec.QuadPart + rhs->hi_prec.QuadPart; else res->lo_prec = lhs->lo_prec + rhs->lo_prec; @@ -213,7 +191,7 @@ static inline ir_timer_val_t *_time_add(ir_timer_val_t *res, const ir_timer_val_ 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) { LARGE_INTEGER dummy; - if(QueryPerformanceFrequency(&dummy)) + if (QueryPerformanceFrequency(&dummy)) res->hi_prec.QuadPart = lhs->hi_prec.QuadPart - rhs->hi_prec.QuadPart; else res->lo_prec = lhs->lo_prec - rhs->lo_prec; @@ -238,15 +216,17 @@ int ir_timer_enter_high_priority(void) struct sched_param p; int res, max, algo; - if(!std_sched_param_init) { + if (!std_sched_param_init) { res = sched_getparam(pid, &std_sched_param); + if (res != 0) + return res; std_sched_param_init = 1; } algo = sched_getscheduler(pid); max = sched_get_priority_max(algo); - memcpy(&p, &std_sched_param, sizeof(p)); + p = std_sched_param; p.sched_priority = max; res = sched_setparam(pid, &p); @@ -258,7 +238,7 @@ int ir_timer_leave_high_priority(void) int res = 0; pid_t pid = getpid(); - if(std_sched_param_init) + if (std_sched_param_init) res = sched_setparam(pid, &std_sched_param); return res; @@ -271,7 +251,7 @@ static int initial_priority = THREAD_PRIORITY_NORMAL; int ir_timer_leave_high_priority(void) { int res = 0; - if(!SetThreadPriority(GetCurrentThread(), initial_priority)) { + if (!SetThreadPriority(GetCurrentThread(), initial_priority)) { fprintf(stderr, "Failed to leave high priority (%d)\n", GetLastError()); res = GetLastError(); } @@ -283,7 +263,7 @@ int ir_timer_enter_high_priority(void) { int res = 0; initial_priority = GetThreadPriority(GetCurrentThread()); - if(!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) { + if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) { fprintf(stderr, "Failed to enter high priority (%d)\n", GetLastError()); res = GetLastError(); } @@ -327,7 +307,7 @@ size_t ir_get_heap_used_bytes(void) int heapstatus; size_t res = 0; hinfo._pentry = NULL; - while((heapstatus = _heapwalk(&hinfo)) == _HEAPOK) + while ((heapstatus = _heapwalk(&hinfo)) == _HEAPOK) res += hinfo._useflag == _USEDENTRY ? hinfo._size : 0; return res; } @@ -353,9 +333,19 @@ void ir_timer_reset(ir_timer_t *timer) /* start a timer */ void ir_timer_start(ir_timer_t *timer) { + if (timer->running) + panic("timer started twice"); + _time_reset(&timer->start); _time_get(&timer->start); timer->running = 1; + + if (timer->parent == NULL) { + timer->parent = timer_stack; + } else if (timer->parent != timer_stack) { + panic("timer used at different stack positions"); + } + timer_stack = timer; } void ir_timer_reset_and_start(ir_timer_t *timer) @@ -364,47 +354,72 @@ void ir_timer_reset_and_start(ir_timer_t *timer) ir_timer_start(timer); } -/* stop a running timer */ void ir_timer_stop(ir_timer_t *timer) { - /* If the timer is running stop, measure the time and add it to the - * elapsed time. */ - if(timer->running) { - ir_timer_val_t val; - ir_timer_val_t tgt; + if (!timer->running) + panic("attempting to stop stopped timer"); + if (timer != timer_stack) + panic("timer stack error"); + timer_stack = timer->parent; + + ir_timer_val_t val; + ir_timer_val_t tgt; + + _time_get(&val); + timer->running = 0; + _time_add(&timer->elapsed, &timer->elapsed, _time_sub(&tgt, &val, &timer->start)); +} + +void ir_timer_init_parent(ir_timer_t *timer) +{ + if (timer == NULL) + return; + if (timer->parent != NULL && timer->parent != timer_stack) + panic("timer parent mismatch"); + timer->parent = timer_stack; +} - _time_get(&val); - timer->running = 0; - _time_add(&timer->elapsed, &timer->elapsed, _time_sub(&tgt, &val, &timer->start)); - _time_reset(&timer->start); +void ir_timer_push(ir_timer_t *timer) +{ + if (timer->running) + panic("timer started twice"); + + ir_timer_t *parent = timer->parent; + if (timer->parent == NULL) + panic("pushing timer with unknown parent"); + + timer->displaced = timer_stack; + for (ir_timer_t *t = timer_stack; t != parent; t = t->parent) { + if (t == NULL) + panic("parent timer not on stack"); + ir_timer_stop(t); } + timer_stack = parent; + + ir_timer_start(timer); } -/* push a timer on the stack */ -int ir_timer_push(ir_timer_t *timer) +static void start_stack(ir_timer_t *timer, ir_timer_t *stop) { - if (timer->link) - return 0; - timer->link = timer_stack; - if (timer_stack) - ir_timer_stop(timer_stack); + if (timer == stop) + return; + start_stack(timer->parent, stop); ir_timer_start(timer); - timer_stack = timer; - return 1; } -/* pop a timer from the stack */ -ir_timer_t *ir_timer_pop(void) +void ir_timer_pop(ir_timer_t *timer) { - ir_timer_t *timer = timer_stack; - if (timer) { - ir_timer_stop(timer); - timer_stack = timer->link; - timer->link = NULL; - if (timer_stack) - ir_timer_start(timer_stack); - } - return timer; + if (!timer->running) + panic("attempting to stop stopped timer"); + ir_timer_t *displaced = timer->displaced; + if (displaced == NULL) + panic("timer start/stop/push/pop mismatch"); + + ir_timer_t *parent = timer->parent; + timer->displaced = NULL; + + ir_timer_stop(timer); + start_stack(displaced, parent); } unsigned long ir_timer_elapsed_msec(const ir_timer_t *timer) @@ -412,7 +427,7 @@ unsigned long ir_timer_elapsed_msec(const ir_timer_t *timer) ir_timer_val_t v; const ir_timer_val_t *elapsed = &timer->elapsed; - if(timer->running) { + if (timer->running) { elapsed = &v; _time_get(&v); _time_add(&v, &timer->elapsed, _time_sub(&v, &v, &timer->start)); @@ -425,7 +440,7 @@ unsigned long ir_timer_elapsed_usec(const ir_timer_t *timer) ir_timer_val_t v; const ir_timer_val_t *elapsed = &timer->elapsed; - if(timer->running) { + if (timer->running) { elapsed = &v; _time_get(&v); _time_add(&v, &timer->elapsed, _time_sub(&v, &v, &timer->start)); @@ -433,10 +448,15 @@ unsigned long ir_timer_elapsed_usec(const ir_timer_t *timer) return _time_to_usec(elapsed); } -const char *ir_timer_get_name(const ir_timer_t *timer) { - return timer->name; -} +double ir_timer_elapsed_sec(const ir_timer_t *timer) +{ + ir_timer_val_t v; + const ir_timer_val_t *elapsed = &timer->elapsed; -const char *ir_timer_get_description(const ir_timer_t *timer) { - return timer->desc; + if (timer->running) { + elapsed = &v; + _time_get(&v); + _time_add(&v, &timer->elapsed, _time_sub(&v, &v, &timer->start)); + } + return _time_to_sec(elapsed); }