fix usertrace fast
[lttv.git] / ltt-usertrace / ltt / ltt-usertrace-fast.h
index d3fac6dad587a34ca736afeda5a3db78b78a2113..5bcec27db93e91feabbaee6a11ededa1a9a24d38 100644 (file)
 #include <pthread.h>
 #include <stdint.h>
 #include <syscall.h>
-#include <asm/timex.h>
 #include <semaphore.h>
 #include <signal.h>
 
 #include <ltt/ltt-facility-id-user_generic.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #ifndef        LTT_N_SUBBUFS
 #define LTT_N_SUBBUFS 2
 #endif //LTT_N_SUBBUFS
@@ -349,7 +352,7 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot(
                                                                                                                        struct ltt_trace_info *trace,
                                                                                                                        struct ltt_buf *ltt_buf,
                                                                                                                        unsigned int data_size,
-                                                                                                                       unsigned int *slot_size,
+                                                                                                                       size_t *slot_size,
                                                                                                                        uint64_t *tsc,
                                                                                                                        size_t *before_hdr_pad,
                                                                                                                        size_t *after_hdr_pad,
@@ -363,6 +366,8 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot(
        int consumed_old, consumed_new;
        int commit_count, reserve_count;
        int ret;
+       sigset_t oldset, set;
+       int signals_disabled = 0;
 
        do {
                offset_old = atomic_read(&ltt_buf->offset);
@@ -403,29 +408,28 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot(
                                                                                                                                                                                                                                 ltt_buf)])
                                - atomic_read(&ltt_buf->commit_count[SUBBUF_INDEX(offset_begin,
                                                                                                                                                                                 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) {
-                               /* sem_wait is not signal safe. Disable signals around it. */
                                {
-                                       sigset_t oldset, set;
+                                       /* sem_wait is not signal safe. Disable signals around it.
+                                        * Signals are kept disabled to make sure we win the cmpxchg. */
 
                                        /* Disable signals */
-                                       ret = sigfillset(&set);
-                                       if(ret) perror("LTT Error in sigfillset\n"); 
-                                       
-                                       ret = pthread_sigmask(SIG_BLOCK, &set, &oldset);
-                                       if(ret) perror("LTT Error in pthread_sigmask\n");
-
+                                       if(!signals_disabled) {
+                                               ret = sigfillset(&set);
+                                               if(ret) perror("LTT Error in sigfillset\n"); 
+               
+                                               ret = pthread_sigmask(SIG_BLOCK, &set, &oldset);
+                                               if(ret) perror("LTT Error in pthread_sigmask\n");
+                                               signals_disabled = 1;
+                                       }
                                        sem_wait(&ltt_buf->writer_sem);
 
-                                       /* Enable signals */
-                                       ret = pthread_sigmask(SIG_SETMASK, &oldset, NULL);
-                                       if(ret) perror("LTT Error in pthread_sigmask\n");
                                }
-
                                        /* go on with the write */
 
                                //} else {
@@ -435,7 +439,8 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot(
                        } else {
                                /* Next subbuffer corrupted. Force pushing reader even in normal
                                 * mode. It's safe to write in this new subbuffer. */
-                               sem_post(&ltt_buf->writer_sem);
+                               /* No sem_post is required because we fall through without doing a
+                                * sem_wait. */
                        }
                        size = ltt_get_header_size(trace, ltt_buf->start + offset_begin,
                                        before_hdr_pad, after_hdr_pad, header_size) + data_size;
@@ -443,6 +448,10 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot(
                                /* Event too big for subbuffers, report error, don't complete 
                                 * the sub-buffer switch. */
                                atomic_inc(&ltt_buf->events_lost);
+                               if(reserve_commit_diff == 0) {
+                                       ret = pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+                                       if(ret) perror("LTT Error in pthread_sigmask\n");
+                               }
                                return NULL;
                        } else {
                                /* We just made a successful buffer switch and the event fits in the
@@ -463,7 +472,6 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot(
        } while(atomic_cmpxchg(&ltt_buf->offset, offset_old, offset_end)
                                                        != offset_old);
 
-
        /* Push the reader if necessary */
        do {
                consumed_old = atomic_read(&ltt_buf->consumed);
@@ -538,6 +546,14 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot(
        }
 
        if(begin_switch) {
+               /* Enable signals : this is what guaranteed that same reserve which did the
+                * sem_wait does in fact win the cmpxchg for the offset. We only call
+                * these system calls on buffer boundaries because of their performance
+                * cost. */
+               if(signals_disabled) {
+                       ret = pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+                       if(ret) perror("LTT Error in pthread_sigmask\n");
+               }
                /* New sub-buffer */
                /* This code can be executed unordered : writers may already have written
                         to the sub-buffer before this code gets executed, caution. */
@@ -623,7 +639,10 @@ static inline void __attribute__((no_instrument_function)) ltt_commit_slot(
                ltt_deliver_callback(ltt_buf, SUBBUF_INDEX(offset_begin, ltt_buf), NULL);
        }
 }
-       
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
 
 #endif //LTT_TRACE_FAST
 #endif //LTT_TRACE
This page took 0.043616 seconds and 4 git commands to generate.