create directories branches, tags, trunk
[lttv.git] / ltt-usertrace / ltt-usertrace-fast.c
index a0544b67d57b407e7ddc985fa317346ae3a3d432..f97e941e5e12b2d97e80c9abb52602ee393a656e 100644 (file)
@@ -46,8 +46,6 @@
 #define _GNU_SOURCE
 #define LTT_TRACE
 #define LTT_TRACE_FAST
-#include <sys/types.h>
-#include <sys/wait.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <pthread.h>
 #include <malloc.h>
 #include <string.h>
-#include <sys/mman.h>
 #include <signal.h>
-#include <sys/stat.h>
 #include <fcntl.h>
 #include <stdlib.h>
+#include <errno.h>
 #include <sys/param.h>
 #include <sys/time.h>
-#include <errno.h>
-
-#include <asm/atomic.h>
-#include <asm/timex.h> //for get_cycles()
-
-_syscall0(pid_t,gettid)
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/syscall.h>
 
 #include <ltt/ltt-usertrace.h>
 
+#define gettid() syscall(__NR_gettid)
+
 #ifdef LTT_SHOW_DEBUG
 #define dbg_printf(...) printf(__VA_ARGS__)
 #else
@@ -109,6 +108,9 @@ static void ltt_usertrace_fast_cleanup(void *arg)
 static pid_t traced_pid = 0;
 static pid_t traced_tid = 0;
 static int parent_exited = 0;
+static int fd_process = -1;
+static char outfile_name[PATH_MAX];
+static char identifier_name[PATH_MAX];
 
 /* signal handling */
 static void handler_sigusr1(int signo)
@@ -202,7 +204,7 @@ static void flush_buffer(struct ltt_buf *ltt_buf, enum force_switch_mode mode)
                                 index in the buffer being the one which will win this loop. */
                        /* If the buffer is not in overwrite mode, pushing the reader only
                                 happen if a sub-buffer is corrupted */
-                       if((SUBBUF_TRUNC(offset_end, ltt_buf) 
+                       if((SUBBUF_TRUNC(offset_end-1, ltt_buf) 
                                        - SUBBUF_TRUNC(consumed_old, ltt_buf)) 
                                                        >= ltt_buf->alloc_size)
                                consumed_new = SUBBUF_ALIGN(consumed_old, ltt_buf);
@@ -284,6 +286,45 @@ static void flush_buffer(struct ltt_buf *ltt_buf, enum force_switch_mode mode)
 
 }
 
+
+static int open_output_files(void)
+{
+       int ret;
+       int fd;
+       /* Open output files */
+       umask(00000);
+       ret = mkdir(LTT_USERTRACE_ROOT, 0777);
+       if(ret < 0 && errno != EEXIST) {
+               perror("LTT Error in creating output (mkdir)");
+               exit(-1);
+       }
+       ret = chdir(LTT_USERTRACE_ROOT);
+       if(ret < 0) {
+               perror("LTT Error in creating output (chdir)");
+               exit(-1);
+       }
+       snprintf(identifier_name, PATH_MAX-1,   "%lu.%lu.%llu",
+                       traced_tid, traced_pid, get_cycles());
+       snprintf(outfile_name, PATH_MAX-1,      "process-%s", identifier_name);
+
+#ifndef LTT_NULL_OUTPUT_TEST
+       fd = creat(outfile_name, 0644);
+#else
+       /* NULL test */
+       ret = symlink("/dev/null", outfile_name);
+       if(ret < 0) {
+               perror("error in symlink");
+               exit(-1);
+       }
+       fd = open(outfile_name, O_WRONLY);
+       if(fd_process < 0) {
+               perror("Error in open");
+               exit(-1);
+       }
+#endif //LTT_NULL_OUTPUT_TEST
+       return fd;
+}
+
 static inline int ltt_buffer_get(struct ltt_buf *ltt_buf,
                unsigned int *offset)
 {
@@ -320,11 +361,14 @@ static inline int ltt_buffer_put(struct ltt_buf *ltt_buf,
                 * It can also happen if this is a buffer we never got. */
                return -EIO;
        } else {
+               if(traced_pid == 0 || parent_exited) return 0;
+
                ret = sem_post(&ltt_buf->writer_sem);
                if(ret < 0) {
                        printf("error in sem_post");
                }
        }
+       return ret;
 }
 
 static int read_subbuffer(struct ltt_buf *ltt_buf, int fd)
@@ -339,6 +383,9 @@ static int read_subbuffer(struct ltt_buf *ltt_buf, int fd)
                if(err != -EAGAIN) dbg_printf("LTT Reserving sub buffer failed\n");
                goto get_error;
        }
+       if(fd_process == -1) {
+               fd_process = fd = open_output_files();
+       }
 
        err = TEMP_FAILURE_RETRY(write(fd,
                                ltt_buf->start 
@@ -378,9 +425,6 @@ static void ltt_usertrace_fast_daemon(struct ltt_trace_info *shared_trace_info,
 {
        struct sigaction act;
        int ret;
-       int fd_process;
-       char outfile_name[PATH_MAX];
-       char identifier_name[PATH_MAX];
 
        traced_pid = l_traced_pid;
        traced_tid = l_traced_tid;
@@ -408,44 +452,11 @@ static void ltt_usertrace_fast_daemon(struct ltt_trace_info *shared_trace_info,
 
        alarm(3);
 
-       /* Open output files */
-       umask(00000);
-       ret = mkdir(LTT_USERTRACE_ROOT, 0777);
-       if(ret < 0 && errno != EEXIST) {
-               perror("LTT Error in creating output (mkdir)");
-               exit(-1);
-       }
-       ret = chdir(LTT_USERTRACE_ROOT);
-       if(ret < 0) {
-               perror("LTT Error in creating output (chdir)");
-               exit(-1);
-       }
-       snprintf(identifier_name, PATH_MAX-1,   "%lu.%lu.%llu",
-                       traced_tid, traced_pid, get_cycles());
-       snprintf(outfile_name, PATH_MAX-1,      "process-%s", identifier_name);
-
-       /* Wait for the first signal before creating files */
-       ret = sigsuspend(&oldset);
-       if(ret != -1) {
-               perror("LTT Error in sigsuspend\n");
-       }
-       if((traced_pid == 0) || parent_exited) goto dead_parent;
-
-#ifndef LTT_NULL_OUTPUT_TEST
-       fd_process = creat(outfile_name, 0644);
-#else
-       /* NULL test */
-       ret = symlink("/dev/null", outfile_name);
-       if(ret < 0) {
-               perror("error in symlink");
-       }
-       fd_process = open(outfile_name, O_WRONLY);
-       if(fd_process < 0) {
-               perror("Error in open");
-       }
-#endif //LTT_NULL_OUTPUT_TEST
-       
        while(1) {
+               ret = sigsuspend(&oldset);
+               if(ret != -1) {
+                       perror("LTT Error in sigsuspend\n");
+               }
                if(traced_pid == 0) break; /* parent died */
                if(parent_exited) break;
                dbg_printf("LTT Doing a buffer switch read. pid is : %lu\n", getpid());
@@ -453,13 +464,7 @@ static void ltt_usertrace_fast_daemon(struct ltt_trace_info *shared_trace_info,
                do {
                        ret = read_subbuffer(&shared_trace_info->channel.process, fd_process);
                } while(ret == 0);
-
-               ret = sigsuspend(&oldset);
-               if(ret != -1) {
-                       perror("LTT Error in sigsuspend\n");
-               }
        }
-dead_parent:
        /* The parent thread is dead and we have finished with the buffer */
 
        /* Buffer force switch (flush). Using FLUSH instead of ACTIVE because we know
@@ -469,8 +474,8 @@ dead_parent:
                ret = read_subbuffer(&shared_trace_info->channel.process, fd_process);
        } while(ret == 0);
 
-
-       close(fd_process);
+       if(fd_process != -1)
+               close(fd_process);
        
        ret = sem_destroy(&shared_trace_info->channel.process.writer_sem);
        if(ret < 0) {
This page took 0.024692 seconds and 4 git commands to generate.