From 51bf1553318c4f651135e0b75c79111a07544ac8 Mon Sep 17 00:00:00 2001 From: compudj Date: Tue, 7 Mar 2006 15:39:33 +0000 Subject: [PATCH 1/1] add usertrace-fast git-svn-id: http://ltt.polymtl.ca/svn@1604 04897980-b3bd-0310-b5e0-8ef037075253 --- usertrace-fast/lttng_usertrace.c | 213 +++---------------------------- usertrace-fast/lttng_usertrace.h | 37 ++---- usertrace-fast/test.c | 3 - 3 files changed, 30 insertions(+), 223 deletions(-) diff --git a/usertrace-fast/lttng_usertrace.c b/usertrace-fast/lttng_usertrace.c index 5e32b0cd..9b4b3036 100644 --- a/usertrace-fast/lttng_usertrace.c +++ b/usertrace-fast/lttng_usertrace.c @@ -20,21 +20,7 @@ #include "lttng_usertrace.h" -#define MAX_TRACES 16 - - -/* - * Notes : - * - * ltt_update : - * - * it should send the information on the traces that has their status MODIFIED. - * It's a necessary assumption to have a correct lttng_free_trace_info, which - * would not be reentrant otherwise. - */ - - -/* TLS for the trace info +/* TLS for the trace buffer * http://www.dis.com/gnu/gcc/C--98-Thread-Local-Edits.html * * Add after paragraph 4 @@ -43,210 +29,49 @@ * initialized before the first statement of the thread startup function. An * object of thread storage duration shall not require dynamic * initialization. - * GCC extention permits init of a range. */ -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 ].destroy = 0, - [ 0 ... MAX_TRACES-1 ].nesting = ATOMIC_INIT(0), - [ 0 ... MAX_TRACES-1 ].channel = - { NULL, - 0, +__thread struct lttng_trace_info lttng_trace_info = +{ + .init = 0, + .filter = 0, + .nesting = ATOMIC_INIT(0), + .channel.facilities = + { ATOMIC_INIT(0), ATOMIC_INIT(0), ATOMIC_INIT(0), + ATOMIC_INIT(0) + }, + .channel.cpu = + { ATOMIC_INIT(0), ATOMIC_INIT(0), ATOMIC_INIT(0), ATOMIC_INIT(0) - } + }, }; -/* 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 struct lttng_trace_info* find_info(unsigned long cpu_addr, - unsigned long fac_addr, unsigned int *first_empty) +static void ltt_cleanup_thread(void *arg) { - struct lttng_trace_info *found = NULL; - unsigned int i; - - *first_empty = MAX_TRACES; - - /* Try to find the trace */ - for(i=0;ifilter = filter; - info->active = active; - info->destroy = destroy; - if(destroy && !atomic_read(&info->nesting)) - lttng_free_trace_info(info); - } else { - /* Not found. Must take an empty slot */ - if(first_empty == MAX_TRACES) { - printf( - "LTTng WARNING : too many traces requested for pid %d by the kernel.\n" - " Compilation defined maximum is %u\n", - getpid(), MAX_TRACES); - - } else { - info = <tng_trace_info[first_empty]; - info->channel.cpu.start = (void*)cpu_addr; - info->channel.cpu.length = PAGE_SIZE; - info->channel.facilities.start = (void*)fac_addr; - info->channel.facilities.length = PAGE_SIZE; - info->filter = filter; - info->active = active; - info->destroy = destroy; - if(destroy && !atomic_read(&info->nesting)) - lttng_free_trace_info(info); - } - } - } - - /* Enable signals */ - ret = pthread_sigmask(SIG_SETMASK, &oldset, NULL); - if(ret) { - printf("Error in sigprocmask\n"); - exit(1); - } } -/* signal handler */ -void __lttng_sig_trace_handler(int signo) +void ltt_thread_init(void) { - printf("LTTng signal handler : thread id : %lu, pid %lu\n", pthread_self(), getpid()); - lttng_get_new_info(); + _pthread_cleanup_push(<tng_trace_info.cleanup, + ltt_cleanup_thread, NULL); } -static void thread_init(void) -{ - int err; - lttng_get_new_info(); - - /* Make some ltt_switch syscalls */ - err = ltt_switch((unsigned long)NULL); - if(err) { - printf("Error in ltt_switch system call\n"); - exit(1); - } -} - void __attribute__((constructor)) __lttng_user_init(void) { - static struct sigaction act; int err; - printf("LTTng user init\n"); - - /* Activate the signal */ - act.sa_handler = __lttng_sig_trace_handler; - err = sigemptyset(&(act.sa_mask)); - if(err) perror("Error with sigemptyset"); - err = sigaddset(&(act.sa_mask), SIGRTMIN+3); - if(err) perror("Error with sigaddset"); - err = sigaction(SIGRTMIN+3, &act, NULL); - if(err) perror("Error with sigaction"); + printf("LTTng usertrace-fast init\n"); - thread_init(); -} -void lttng_thread_init(void) -{ - thread_init(); } - diff --git a/usertrace-fast/lttng_usertrace.h b/usertrace-fast/lttng_usertrace.h index 600be4ff..51d0767b 100644 --- a/usertrace-fast/lttng_usertrace.h +++ b/usertrace-fast/lttng_usertrace.h @@ -9,26 +9,17 @@ #define _LTTNG_USERTRACE_H #include -#include - #include -//Put in asm-i486/unistd.h -#define __NR_ltt_update 294 -#define __NR_ltt_switch 295 - -#undef NR_syscalls -#define NR_syscalls 296 +#ifndef LTT_BUF_SIZE_CPU +#define LTT_BUF_SIZE_CPU 1048576 +#endif //LTT_BUF_SIZE_CPU -#ifndef _LIBC -// Put in bits/syscall.h -#define SYS_ltt_update __NR_ltt_update -#define SYS_ltt_switch __NR_ltt_switch -#endif +#ifndef LTT_BUF_SIZE_FACILITIES +#define LTT_BUF_SIZE_FACILITIES 4096 +#endif //LTT_BUF_SIZE_FACILITIES struct ltt_buf { - void *start; - size_t length; atomic_t offset; atomic_t reserve_count; atomic_t commit_count; @@ -37,25 +28,19 @@ struct ltt_buf { }; struct lttng_trace_info { - int active:1; - int destroy:1; + struct _pthread_cleanup_buffer cleanup; int filter; atomic_t nesting; struct { struct ltt_buf facilities; + char facilities_buf[LTT_BUF_SIZE_FACILITIES] __attribute__ ((aligned (8))); struct ltt_buf cpu; + char cpu_buf[LTT_BUF_SIZE_CPU] __attribute__ ((aligned (8))); } channel; }; +extern __thread struct lttng_trace_info lttng_trace_info; -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 _syscall5(int, ltt_update, unsigned long *, cpu_addr, unsigned long *, fac_addr, int *, active, int *, filter, int *, destroy) +void ltt_thread_init(void); #endif //_LTTNG_USERTRACE_H diff --git a/usertrace-fast/test.c b/usertrace-fast/test.c index a0509a27..33937f3b 100644 --- a/usertrace-fast/test.c +++ b/usertrace-fast/test.c @@ -10,7 +10,6 @@ void *thr1(void *arg) { - lttng_thread_init(); printf("thread 1, thread id : %lu, pid %lu\n", pthread_self(), getpid()); while(1) {} @@ -21,8 +20,6 @@ void *thr1(void *arg) void *thr2(void *arg) { - lttng_thread_init(); - while(1) { printf("thread 2, thread id : %lu, pid %lu\n", pthread_self(), getpid()); sleep(2); -- 2.34.1