diff --git a/src/trace/trace.c b/src/trace/trace.c index 472aeeea7..d927953d7 100644 --- a/src/trace/trace.c +++ b/src/trace/trace.c @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include #ifdef HAVE_PTHREAD #include @@ -27,7 +29,22 @@ #include #endif -#define TRACE_BUFFER_SIZE 1000000 +#define DEBUG_MODULE "trace" +#define DEBUG_LEVEL 5 +#include + +#ifndef TRACE_BUFFER_SIZE +#define TRACE_BUFFER_SIZE 100000 +#endif + +#ifndef TRACE_FLUSH_THRESHOLD +#define TRACE_FLUSH_THRESHOLD 1000 +#endif + +#ifndef TRACE_FLUSH_TMR +#define TRACE_FLUSH_TMR 1000 +#endif + struct trace_event { const char *name; @@ -47,15 +64,16 @@ struct trace_event { /** Trace configuration */ static struct { + RE_ATOMIC bool init; int process_id; FILE *f; int event_count; struct trace_event *event_buffer; struct trace_event *event_buffer_flush; mtx_t lock; - bool init; bool new; uint64_t start_time; + struct tmr flush_tmr; } trace = { .init = false }; @@ -90,6 +108,33 @@ static inline int get_process_id(void) } +static int flush_worker(void *arg) +{ + (void)arg; + + mtx_lock(&trace.lock); + if (trace.event_count < TRACE_FLUSH_THRESHOLD) { + mtx_unlock(&trace.lock); + return 0; + } + mtx_unlock(&trace.lock); + + re_trace_flush(); + + return 0; +} + + +static void flush_tmr(void *arg) +{ + (void)arg; + + re_thread_async(flush_worker, NULL, NULL); + + tmr_start(&trace.flush_tmr, TRACE_FLUSH_TMR, flush_tmr, NULL); +} + + /** * Init new trace json file * @@ -108,7 +153,7 @@ int re_trace_init(const char *json_file) if (!json_file) return EINVAL; - if (trace.init) + if (re_atomic_rlx(&trace.init)) return EALREADY; trace.event_buffer = mem_zalloc( @@ -137,12 +182,15 @@ int re_trace_init(const char *json_file) (void)fflush(trace.f); trace.start_time = tmr_jiffies_usec(); - trace.init = true; + re_atomic_rlx_set(&trace.init, true); trace.new = true; + tmr_init(&trace.flush_tmr); + tmr_start(&trace.flush_tmr, TRACE_FLUSH_TMR, flush_tmr, NULL); + out: if (err) { - trace.init = false; + re_atomic_rlx_set(&trace.init, false); mem_deref(trace.event_buffer); mem_deref(trace.event_buffer_flush); } @@ -164,12 +212,13 @@ int re_trace_close(void) return 0; #endif + tmr_cancel(&trace.flush_tmr); re_trace_flush(); + re_atomic_rlx_set(&trace.init, false); trace.event_buffer = mem_deref(trace.event_buffer); trace.event_buffer_flush = mem_deref(trace.event_buffer_flush); mtx_destroy(&trace.lock); - trace.init = false; (void)re_fprintf(trace.f, "\n\t]\n}\n"); if (trace.f) @@ -201,7 +250,7 @@ int re_trace_flush(void) return 0; #endif - if (!trace.init) + if (!re_atomic_rlx(&trace.init)) return 0; mtx_lock(&trace.lock); @@ -266,11 +315,12 @@ void re_trace_event(const char *cat, const char *name, char ph, void *id, return; #endif - if (!trace.init) + if (!re_atomic_rlx(&trace.init)) return; mtx_lock(&trace.lock); if (trace.event_count >= TRACE_BUFFER_SIZE) { + DEBUG_WARNING("Increase TRACE_BUFFER_SIZE\n"); mtx_unlock(&trace.lock); return; }