2 * Copyright (C) 1995-2007 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 Statistic events.
23 * @author Sebastian Hack
36 #include <libcore/lc_timing.h>
51 static ctx_t ctx_stack[MAX_CTX];
53 static unsigned long time_in_ev = 0;
54 static int ctx_sp = -1;
55 static FILE *file_ev = NULL;
57 static lc_timer_t *timer = NULL;
59 int stat_ev_enabled = 0;
61 typedef struct print_ev_t {
63 struct print_ev_t *next;
66 static print_ev_t *print_events = NULL;
67 static int ctx_switch_since_last_print = 0;
69 #define get_time() lc_timer_elapsed_usec(timer)
71 void stat_ev_ctx_push(const char *key, const char *value)
74 unsigned long start = get_time();
75 ctx_t *ctx = &ctx_stack[ctx_sp + 1];
76 unsigned hash = firm_fnv_hash_str(key);
78 hash = HASH_COMBINE(hash, firm_fnv_hash_str(value));
80 hash = HASH_COMBINE(hash, ctx_stack[ctx_sp].hash);
82 snprintf(ctx->key, array_size(ctx->key), "%s", key);
83 snprintf(ctx->value, array_size(ctx->value), "%s", value);
87 fprintf(file_ev, "P %10x %30s %30s\n", ctx->hash, ctx->key, ctx->value);
89 ctx_switch_since_last_print = 1;
91 time_in_ev += get_time() - start;
95 void stat_ev_ctx_push_fobj(const char *key, const void *firm_object)
99 ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
100 stat_ev_ctx_push(key, buf);
104 void stat_ev_ctx_pop(void)
108 fprintf(file_ev, "O %10x\n", ctx_stack[ctx_sp].hash);
109 ctx_switch_since_last_print = 1;
115 static void maybe_print_context(void)
119 if(!ctx_switch_since_last_print)
122 for(i = 0; i <= ctx_sp; ++i) {
125 fputs(ctx_stack[i].value, stderr);
128 ctx_switch_since_last_print = 0;
131 void stat_ev_emit(const char *name, double value)
134 unsigned long start = get_time();
135 unsigned id = ctx_sp >= 0 ? ctx_stack[ctx_sp].hash : 0;
137 fprintf(file_ev, "E %10x %30s %30f %10ld %10ld\n", id, name, value, start, time_in_ev);
139 if(print_events != NULL) {
140 print_ev_t *print_ev = print_events;
141 while(print_ev != NULL) {
142 /* maybe wanna use regexes instead of strcmp? */
143 if(strstr(name, print_ev->filter) != NULL) {
144 maybe_print_context();
145 fprintf(stderr, "\t%20s %30f\n", name, value);
148 print_ev = print_ev->next;
152 time_in_ev += get_time() - start;
156 void stat_ev_begin(const char *prefix)
160 snprintf(buf, sizeof(buf), "%s.ev", prefix);
166 file_ev = fopen(buf, "wt");
167 timer = lc_timer_register("stat_ev", "firm stat event timer");
169 lc_timer_start(timer);
172 void stat_ev_end(void)
174 print_ev_t *print_ev, *next;
177 lc_timer_stop(timer);
181 for (print_ev = print_events; print_ev != NULL; print_ev = next) {
182 next = print_ev->next;
187 void stat_ev_flush(void)
189 unsigned long start = get_time();
192 time_in_ev += get_time() - start;
195 void stat_ev_print(const char *filter)
198 print_ev_t *print_ev = xmalloc(sizeof(print_ev[0]));
200 memset(print_ev, 0, sizeof(print_ev[0]));
202 len = strlen(filter) + 1;
203 if (len >= sizeof(print_ev->filter)) {
204 fprintf(stderr, "Warning: capping event filter (too long)");
205 len = sizeof(print_ev->filter);
207 memcpy(print_ev->filter, filter, len);
208 print_ev->filter[len-1] = 0;
210 print_ev->next = print_events;
211 print_events = print_ev;