add usertrace-fast
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Tue, 7 Mar 2006 15:39:33 +0000 (15:39 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Tue, 7 Mar 2006 15:39:33 +0000 (15:39 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@1604 04897980-b3bd-0310-b5e0-8ef037075253

usertrace-fast/lttng_usertrace.c
usertrace-fast/lttng_usertrace.h
usertrace-fast/test.c

index 5e32b0cd4e640df69e2fe66b62de04fd1d4da1bf..9b4b3036d4abd295b6e902bfd37ea65dd08245f5 100644 (file)
 
 #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
  *     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;i<MAX_TRACES;i++) {
-               if(i<*first_empty && !lttng_trace_info[i].channel.cpu.start)
-                       *first_empty = i;
-               if(cpu_addr == 
-                               (unsigned long)lttng_trace_info[i].channel.cpu.start &&
-                        fac_addr == 
-                               (unsigned long)lttng_trace_info[i].channel.facilities.start) {
-                       /* Found */
-                       found = &lttng_trace_info[i];
-                       break;
-               }
-       }
-       return found;
-}
-
+       /* Flush the data in the lttng_trace_info */
 
-static void lttng_get_new_info(void)
-{
-       unsigned long cpu_addr, fac_addr;
-       unsigned int i, first_empty;
-       int active, filter, destroy;
-       int ret;
-       struct lttng_trace_info *info;
-       sigset_t set, oldset;
-
-       /* Disable signals */
-       ret = sigfillset(&set);
-       if(ret) {
-               printf("Error in sigfillset\n");
-               exit(1);
-       }
-       
-       ret = pthread_sigmask(SIG_BLOCK, &set, &oldset);
-       if(ret) {
-               printf("Error in sigprocmask\n");
-               exit(1);
-       }
-
-       /* Get all the new traces */
-       while(1) {
-               cpu_addr = fac_addr = 0;
-               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);
-               }
-               
-               if(!cpu_addr || !fac_addr) break;
-               
-               info = find_info(cpu_addr, fac_addr, &first_empty);
-               if(info) {
-                       info->filter = 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 = &lttng_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(&lttng_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();
 }
 
-
index 600be4ffbb5915464e7874eab64b037cc7a6f95e..51d0767b57b01a00d55d80750f4a628ea78cff87 100644 (file)
@@ -9,26 +9,17 @@
 #define _LTTNG_USERTRACE_H
 
 #include <errno.h>
-#include <syscall.h>
-
 #include <asm/atomic.h>
 
-//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
index a0509a277bfc63561e004d34d8973519ba8dc842..33937f3bef418daa8a4b6e18df5d6ae50c3bd810 100644 (file)
@@ -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);
This page took 0.027701 seconds and 4 git commands to generate.