From 0166aeb5953a83894157224a2fec0b5de3005260 Mon Sep 17 00:00:00 2001 From: compudj Date: Fri, 27 Jan 2006 00:29:34 +0000 Subject: [PATCH] update infos git-svn-id: http://ltt.polymtl.ca/svn@1499 04897980-b3bd-0310-b5e0-8ef037075253 --- usertrace/lttng_usertrace.c | 78 ++++++++++++++++++++++++++----------- usertrace/lttng_usertrace.h | 28 ++++++++++++- 2 files changed, 82 insertions(+), 24 deletions(-) diff --git a/usertrace/lttng_usertrace.c b/usertrace/lttng_usertrace.c index 14e19380..3458e6d5 100644 --- a/usertrace/lttng_usertrace.c +++ b/usertrace/lttng_usertrace.c @@ -18,29 +18,10 @@ #include #include -#include #include "lttng_usertrace.h" #define MAX_TRACES 16 -struct ltt_buf { - void *start; - atomic_t offset; - atomic_t reserve_count; - atomic_t commit_count; - - atomic_t events_lost; -}; - -struct lttng_trace_info { - int active:1; - int filter; - struct { - struct ltt_buf facilities; - struct ltt_buf cpu; - } channel; -}; - /* TLS for the trace info * http://www.dis.com/gnu/gcc/C--98-Thread-Local-Edits.html @@ -57,8 +38,10 @@ struct lttng_trace_info { static __thread struct lttng_trace_info lttng_trace_info[MAX_TRACES] = { [ 0 ... MAX_TRACES-1 ].active = 0, [ 0 ... MAX_TRACES-1 ].filter = 0, + [ 0 ... MAX_TRACES-1 ].nesting = ATOMIC_INIT(0), [ 0 ... MAX_TRACES-1 ].channel = { NULL, + 0, ATOMIC_INIT(0), ATOMIC_INIT(0), ATOMIC_INIT(0), @@ -68,18 +51,60 @@ static __thread struct lttng_trace_info lttng_trace_info[MAX_TRACES] = }; +/* Must be called we sure nobody else is using the info. + * It implies that the trace should have been previously stopped + * and that every writer has finished. + * + * Writers should always check if the trace must be destroyed when they + * finish writing and the nesting level is 0. + */ +void lttng_free_trace_info(struct lttng_trace_info *info) +{ + int ret; + + if(info->active) { + printf( + "LTTng ERROR : lttng_free_trace_info should be called on inactive trace\n"); + exit(1); + } + if(!info->destroy) { + printf( + "LTTng ERROR : lttng_free_trace_info should be called on destroyed trace\n"); + exit(1); + } + if(atomic_read(&info->nesting) > 0) { + printf( + "LTTng ERROR : lttng_free_trace_info should not be nested on tracing\n"); + exit(1); + } + + /* Remove the maps */ + ret = munmap(info->channel.cpu.start, info->channel.cpu.length); + if(ret) { + perror("LTTNG : error in munmap"); + } + ret = munmap(info->channel.facilities.start, info->channel.facilities.length); + if(ret) { + perror("LTTNG : error in munmap"); + } + + /* Zero the structure */ + memset(info, 0, sizeof(struct lttng_trace_info)); +} + + static void lttng_get_new_info(void) { unsigned long cpu_addr, fac_addr; unsigned int i, first_empty; - int active, filter; + int active, filter, destroy; int ret; /* Get all the new traces */ while(1) { cpu_addr = fac_addr = 0; - active = filter = 0; - ret = ltt_update(&cpu_addr, &fac_addr, &active, &filter); + active = filter = destroy = 0; + ret = ltt_update(&cpu_addr, &fac_addr, &active, &filter, &destroy); if(ret) { printf("LTTng : error in ltt_update\n"); exit(1); @@ -96,9 +121,14 @@ static void lttng_get_new_info(void) (unsigned long)lttng_trace_info[i].channel.cpu.start && fac_addr == (unsigned long)lttng_trace_info[i].channel.facilities.start) { - + /* Found */ lttng_trace_info[i].filter = filter; lttng_trace_info[i].active = active; + lttng_trace_info[i].destroy = destroy; + if(destroy && !atomic_read(<tng_trace_info[i].nesting)) { + lttng_free_trace_info(<tng_trace_info[i]); + } + break; } } @@ -112,8 +142,10 @@ static void lttng_get_new_info(void) } else { lttng_trace_info[first_empty].channel.cpu.start = (void*)cpu_addr; + lttng_trace_info[first_empty].channel.cpu.length = PAGE_SIZE; lttng_trace_info[first_empty].channel.facilities.start = (void*)fac_addr; + lttng_trace_info[first_empty].channel.facilities.length = PAGE_SIZE; lttng_trace_info[first_empty].filter = filter; lttng_trace_info[first_empty].active = active; } diff --git a/usertrace/lttng_usertrace.h b/usertrace/lttng_usertrace.h index 079a85a9..600be4ff 100644 --- a/usertrace/lttng_usertrace.h +++ b/usertrace/lttng_usertrace.h @@ -11,6 +11,8 @@ #include #include +#include + //Put in asm-i486/unistd.h #define __NR_ltt_update 294 #define __NR_ltt_switch 295 @@ -24,12 +26,36 @@ #define SYS_ltt_switch __NR_ltt_switch #endif +struct ltt_buf { + void *start; + size_t length; + atomic_t offset; + atomic_t reserve_count; + atomic_t commit_count; + + atomic_t events_lost; +}; + +struct lttng_trace_info { + int active:1; + int destroy:1; + int filter; + atomic_t nesting; + struct { + struct ltt_buf facilities; + struct ltt_buf cpu; + } channel; +}; + + void __lttng_sig_trace_handler(int signo); /* Call this at the beginning of a new thread, except for the main() */ void lttng_thread_init(void); +void lttng_free_trace_info(struct lttng_trace_info *info); + static inline _syscall1(int, ltt_switch, unsigned long, addr) -static inline _syscall4(int, ltt_update, unsigned long *, cpu_addr, unsigned long *, fac_addr, int *, active, int *, filter) +static inline _syscall5(int, ltt_update, unsigned long *, cpu_addr, unsigned long *, fac_addr, int *, active, int *, filter, int *, destroy) #endif //_LTTNG_USERTRACE_H -- 2.34.1