fix futex
authorroot <root@04897980-b3bd-0310-b5e0-8ef037075253>
Thu, 9 Mar 2006 13:39:23 +0000 (13:39 +0000)
committerroot <root@04897980-b3bd-0310-b5e0-8ef037075253>
Thu, 9 Mar 2006 13:39:23 +0000 (13:39 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@1625 04897980-b3bd-0310-b5e0-8ef037075253

usertrace-fast/Makefile
usertrace-fast/ltt-usertrace-fast.c
usertrace-fast/ltt/ltt-usertrace-fast.h

index 2dafe00219d106201d05552d4c035f24f57cafc9..7430a3b45589cdaf70a2415d2d766862a241a30a 100644 (file)
@@ -6,9 +6,10 @@ RANLIB=ranlib
 
 CC=gcc
 CFLAGS=-I. -O3
-CFLAGS+=-DLTT_SUBBUF_SIZE_CPU=134217728
+#CFLAGS+=-DLTT_SUBBUF_SIZE_CPU=134217728
+CFLAGS+=-DLTT_NULL_OUTPUT_TEST
 
-all: test sample-instrument-fct libltt-instrument-functions.a libltt-instrument-functions.so.0
+all: test sample-instrument-fct libltt-instrument-functions.a libltt-instrument-functions.so.0 sample-loop
 
 test: test.c ltt-usertrace-fast.c
        $(CC) $(CFLAGS) -I. -lpthread -o $@ $^
@@ -17,6 +18,9 @@ test: test.c ltt-usertrace-fast.c
 sample-instrument-fct: sample-instrument-fct.c
        $(CC) $(CFLAGS) -L. -g -finstrument-functions -lltt-instrument-functions -o $@ $^
 
+sample-loop: sample-loop.c ltt-usertrace-fast.o ltt-facility-loader-user_generic.o
+       $(CC) $(CFLAGS) -L. -lpthread -g -o $@ $^
+
 libltt-instrument-functions.a: ltt-instrument-functions.o ltt-facility-loader-user_generic.o ltt-usertrace-fast.o
        @rm -f libltt-instrument-functions.a
        $(AR) rc $@ $^
index 159c00df9f8a83752bda37204765b758a1a3a97a..d722460b10e1f4a98d4048feed7e46ea57b408c2 100644 (file)
@@ -319,14 +319,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(atomic_read(&ltt_buf->full) == 1) {
+               if(atomic_inc_return(&ltt_buf->writer_futex) <= 0) {
+                       atomic_set(&ltt_buf->writer_futex, 1);
                        /* tell the client that buffer is now unfull */
-                       ret = futex((unsigned long)&ltt_buf->full,
+                       ret = futex((unsigned long)&ltt_buf->writer_futex,
                                        FUTEX_WAKE, 1, 0, 0, 0);
                        if(ret != 1) {
                                dbg_printf("LTT warning : race condition : writer not waiting or too many writers\n");
                        }
-                       atomic_set(&ltt_buf->full, 0);
                }
        }
 }
@@ -382,8 +382,7 @@ static void ltt_usertrace_fast_daemon(struct ltt_trace_info *shared_trace_info,
 {
        struct sigaction act;
        int ret;
-       int fd_fac;
-       int fd_cpu;
+       int fd_process;
        char outfile_name[PATH_MAX];
        char identifier_name[PATH_MAX];
 
@@ -434,12 +433,20 @@ static void ltt_usertrace_fast_daemon(struct ltt_trace_info *shared_trace_info,
        }
        snprintf(identifier_name, PATH_MAX-1,   "%lu.%lu.%llu",
                        traced_tid, traced_pid, get_cycles());
-       snprintf(outfile_name, PATH_MAX-1,      "facilities-%s", identifier_name);
-       fd_fac = creat(outfile_name, 0644);
-
-       snprintf(outfile_name, PATH_MAX-1,      "cpu-%s", identifier_name);
-       fd_cpu = creat(outfile_name, 0644);
-       
+       snprintf(outfile_name, PATH_MAX-1,      "process-%s", identifier_name);
+#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) {
                pause();
@@ -448,11 +455,7 @@ static void ltt_usertrace_fast_daemon(struct ltt_trace_info *shared_trace_info,
                dbg_printf("LTT Doing a buffer switch read. pid is : %lu\n", getpid());
        
                do {
-                       ret = read_subbuffer(&shared_trace_info->channel.cpu, fd_cpu);
-               } while(ret == 0);
-
-               do {
-                       ret = read_subbuffer(&shared_trace_info->channel.facilities, fd_fac);
+                       ret = read_subbuffer(&shared_trace_info->channel.process, fd_process);
                } while(ret == 0);
        }
 
@@ -460,19 +463,13 @@ static void ltt_usertrace_fast_daemon(struct ltt_trace_info *shared_trace_info,
 
        /* Buffer force switch (flush). Using FLUSH instead of ACTIVE because we know
         * there is no writer. */
-       flush_buffer(&shared_trace_info->channel.cpu, FORCE_FLUSH);
+       flush_buffer(&shared_trace_info->channel.process, FORCE_FLUSH);
        do {
-               ret = read_subbuffer(&shared_trace_info->channel.cpu, fd_cpu);
+               ret = read_subbuffer(&shared_trace_info->channel.process, fd_process);
        } while(ret == 0);
 
 
-       flush_buffer(&shared_trace_info->channel.facilities, FORCE_FLUSH);
-       do {
-               ret = read_subbuffer(&shared_trace_info->channel.facilities, fd_fac);
-       } while(ret == 0);
-
-       close(fd_fac);
-       close(fd_cpu);
+       close(fd_process);
        
        munmap(shared_trace_info, sizeof(*shared_trace_info));
        
@@ -502,25 +499,16 @@ void ltt_rw_init(void)
        shared_trace_info->filter=0;
        shared_trace_info->daemon_id=0;
        shared_trace_info->nesting=0;
-       memset(&shared_trace_info->channel.facilities, 0,
-                       sizeof(shared_trace_info->channel.facilities));
-       memset(&shared_trace_info->channel.cpu, 0,
-                       sizeof(shared_trace_info->channel.cpu));
+       memset(&shared_trace_info->channel.process, 0,
+                       sizeof(shared_trace_info->channel.process));
        /* Tricky semaphore : is in a shared memory space, so it's ok for a fast
         * mutex (futex). */
-       atomic_set(&shared_trace_info->channel.facilities.full, 0);
-       shared_trace_info->channel.facilities.alloc_size = LTT_BUF_SIZE_FACILITIES;
-       shared_trace_info->channel.facilities.subbuf_size = LTT_SUBBUF_SIZE_FACILITIES;
-       shared_trace_info->channel.facilities.start =
-               shared_trace_info->channel.facilities_buf;
-       ltt_buffer_begin_callback(&shared_trace_info->channel.facilities,
-                       ltt_get_timestamp(), 0);
-
-       atomic_set(&shared_trace_info->channel.cpu.full, 0);
-       shared_trace_info->channel.cpu.alloc_size = LTT_BUF_SIZE_CPU;
-       shared_trace_info->channel.cpu.subbuf_size = LTT_SUBBUF_SIZE_CPU;
-       shared_trace_info->channel.cpu.start = shared_trace_info->channel.cpu_buf;
-       ltt_buffer_begin_callback(&shared_trace_info->channel.cpu,
+       atomic_set(&shared_trace_info->channel.process.writer_futex, LTT_N_SUBBUFS);
+       shared_trace_info->channel.process.alloc_size = LTT_BUF_SIZE_PROCESS;
+       shared_trace_info->channel.process.subbuf_size = LTT_SUBBUF_SIZE_PROCESS;
+       shared_trace_info->channel.process.start =
+                                               shared_trace_info->channel.process_buf;
+       ltt_buffer_begin_callback(&shared_trace_info->channel.process,
                        ltt_get_timestamp(), 0);
        
        shared_trace_info->init = 1;
@@ -553,10 +541,12 @@ void ltt_rw_init(void)
                /* Child */
                role = LTT_ROLE_READER;
                sid = setsid();
-               ret = nice(1);
-               if(ret < 0) {
-                       perror("Error in nice");
-               }
+               //Not a good idea to renice, unless futex wait eventually implement
+               //priority inheritence.
+               //ret = nice(1);
+               //if(ret < 0) {
+               //      perror("Error in nice");
+               //}
                if(sid < 0) {
                        perror("Error setting sid");
                }
index a175d895d8d2c21d13828273ceabb6bceaea13c2..77e0594ff58045c5c8fdb817c1656e95e74558d7 100644 (file)
@@ -33,17 +33,11 @@ static inline __attribute__((no_instrument_function))
 #define LTT_N_SUBBUFS 2
 #endif //LTT_N_SUBBUFS
 
-#ifndef        LTT_SUBBUF_SIZE_CPU
-#define LTT_SUBBUF_SIZE_CPU 1048576
+#ifndef        LTT_SUBBUF_SIZE_PROCESS
+#define LTT_SUBBUF_SIZE_PROCESS 1048576
 #endif //LTT_BUF_SIZE_CPU
 
-#define LTT_BUF_SIZE_CPU (LTT_SUBBUF_SIZE_CPU * LTT_N_SUBBUFS)
-
-#ifndef        LTT_SUBBUF_SIZE_FACILITIES
-#define LTT_SUBBUF_SIZE_FACILITIES 4096
-#endif //LTT_BUF_SIZE_FACILITIES
-
-#define LTT_BUF_SIZE_FACILITIES  (LTT_SUBBUF_SIZE_FACILITIES * LTT_N_SUBBUFS)
+#define LTT_BUF_SIZE_PROCESS (LTT_SUBBUF_SIZE_PROCESS * LTT_N_SUBBUFS)
 
 #ifndef LTT_USERTRACE_ROOT
 #define LTT_USERTRACE_ROOT "/tmp/ltt-usertrace"
@@ -118,7 +112,7 @@ struct ltt_buf {
 
        atomic_t        events_lost;
        atomic_t        corrupted_subbuffers;
-       atomic_t        full;   /* futex on which the writer waits : 1 : full */
+       atomic_t        writer_futex;   /* futex on which the writer waits */
        unsigned int    alloc_size;
        unsigned int    subbuf_size;
 };
@@ -129,10 +123,8 @@ struct ltt_trace_info {
        pid_t daemon_id;
        int nesting;
        struct {
-               struct ltt_buf facilities;
-               struct ltt_buf cpu;
-               char facilities_buf[LTT_BUF_SIZE_FACILITIES] __attribute__ ((aligned (8)));
-               char cpu_buf[LTT_BUF_SIZE_CPU] __attribute__ ((aligned (8)));
+               struct ltt_buf process;
+               char process_buf[LTT_BUF_SIZE_PROCESS] __attribute__ ((aligned (8)));
        } channel;
 };
 
@@ -171,7 +163,7 @@ static inline unsigned int __attribute__((no_instrument_function))
                ltt_get_index_from_facility(ltt_facility_t fID,
                                                                                                                                uint8_t eID)
 {
-       return GET_CHANNEL_INDEX(cpu);
+       return GET_CHANNEL_INDEX(process);
 }
 
 
@@ -423,23 +415,28 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot(
                                                                                                                                                                                 ltt_buf)]);
                        if(reserve_commit_diff == 0) {
                                /* Next buffer not corrupted. */
-                               if((SUBBUF_TRUNC(offset_begin, ltt_buf) 
-                                                               - SUBBUF_TRUNC(atomic_read(&ltt_buf->consumed), ltt_buf))
-                                                                       >= ltt_buf->alloc_size) {
-                                       /* We block until the reader unblocks us */
-                                       atomic_set(&ltt_buf->full, 1);
-                                       /* We block until the reader tells us to wake up.
-                                                Signals will simply cause this loop to restart.
-                                                */
-                                       do {
-                                               ret = futex((unsigned long)&ltt_buf->full, FUTEX_WAIT, 1, 0, 0, 0);
-                                       } while(ret != 0 && ret != EWOULDBLOCK);
+                               //if((SUBBUF_TRUNC(offset_begin, ltt_buf) 
+                               //                              - SUBBUF_TRUNC(atomic_read(&ltt_buf->consumed), ltt_buf))
+                               //                                      >= ltt_buf->alloc_size) {
+                                       if(atomic_dec_return(&ltt_buf->writer_futex) >= 0) {
+                                               /* non contended */
+                                       } else {
+                                               /* We block until the reader unblocks us */
+                                               atomic_set(&ltt_buf->writer_futex, -1);
+                                               /* We block until the reader tells us to wake up.
+                                                        Signals will simply cause this loop to restart.
+                                                        */
+                                               do {
+                                                       ret = futex((unsigned long)&ltt_buf->writer_futex,
+                                                                       FUTEX_WAIT, -1, 0, 0, 0);
+                                               } while(ret != 0 && ret != EWOULDBLOCK);
+                                       }
                                        /* go on with the write */
 
-                               } else {
-                                       /* next buffer not corrupted, we are either in overwrite mode or
-                                        * the buffer is not full. It's safe to write in this new subbuffer.*/
-                               }
+                               //} else {
+                               //      /* next buffer not corrupted, we are either in overwrite mode or
+                               //       * the buffer is not full. It's safe to write in this new subbuffer.*/
+                               //}
                        } else {
                                /* Next subbuffer corrupted. Force pushing reader even in normal
                                 * mode. It's safe to write in this new subbuffer. */
This page took 0.028258 seconds and 4 git commands to generate.