X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;ds=sidebyside;f=ltt-usertrace%2Fltt%2Fltt-usertrace-fast.h;h=fb01893684259d7ab09bbab69610e792f25ed22b;hb=2786770231bafe751b79ee829519b6d74a4d7709;hp=45b8b6c0cf805abbd24fa4de3dcdbba331068fa5;hpb=0701d15032099822d418c7879427c0bdf21703be;p=lttv.git diff --git a/ltt-usertrace/ltt/ltt-usertrace-fast.h b/ltt-usertrace/ltt/ltt-usertrace-fast.h index 45b8b6c0..fb018936 100644 --- a/ltt-usertrace/ltt/ltt-usertrace-fast.h +++ b/ltt-usertrace/ltt/ltt-usertrace-fast.h @@ -9,18 +9,20 @@ #define _LTT_USERTRACE_FAST_H #ifdef LTT_TRACE +#ifdef LTT_TRACE_FAST #include -#include #include #include #include -#include #include #include #include -#include + +#ifdef __cplusplus +extern "C" { +#endif #ifndef LTT_N_SUBBUFS #define LTT_N_SUBBUFS 2 @@ -51,14 +53,12 @@ #define LTT_TRACER_MAGIC_NUMBER 0x00D6B7ED #define LTT_TRACER_VERSION_MAJOR 0 -#define LTT_TRACER_VERSION_MINOR 7 +#define LTT_TRACER_VERSION_MINOR 8 #ifndef atomic_cmpxchg #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) #endif //atomic_cmpxchg -typedef unsigned int ltt_facility_t; - struct ltt_trace_header { uint32_t magic_number; uint32_t arch_type; @@ -71,12 +71,14 @@ struct ltt_trace_header { uint8_t flight_recorder; uint8_t has_heartbeat; uint8_t has_alignment; /* Event header alignment */ + uint8_t tsc_lsb_truncate; + uint8_t tscbits; uint32_t freq_scale; uint64_t start_freq; uint64_t start_tsc; uint64_t start_monotonic; - uint64_t start_time_sec; - uint64_t start_time_usec; + uint64_t start_time_sec; + uint64_t start_time_usec; } __attribute((packed)); @@ -352,7 +354,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, @@ -366,6 +368,7 @@ 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; do { offset_old = atomic_read(<t_buf->offset); @@ -406,29 +409,40 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot( ltt_buf)]) - atomic_read(<t_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(<t_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"); + /* We detect if a signal came between + * the offset read and signal disabling: + * if it is the case, then we restart + * the loop after reenabling signals. It + * means that it's a signal that has + * won the buffer switch.*/ + if(offset_old != atomic_read(<t_buf->offset)) { + ret = pthread_sigmask(SIG_SETMASK, &oldset, NULL); + if(ret) perror("LTT Error in pthread_sigmask\n"); + continue; + } + /* If the offset is still the same, then + * we can safely proceed to do the + * buffer switch without being + * interrupted by a signal. */ sem_wait(<t_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 { @@ -438,7 +452,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(<t_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; @@ -446,6 +461,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(<t_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 @@ -466,7 +485,6 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot( } while(atomic_cmpxchg(<t_buf->offset, offset_old, offset_end) != offset_old); - /* Push the reader if necessary */ do { consumed_old = atomic_read(<t_buf->consumed); @@ -478,7 +496,7 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot( 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); @@ -541,6 +559,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(reserve_commit_diff == 0) { + 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. */ @@ -626,9 +652,11 @@ static inline void __attribute__((no_instrument_function)) ltt_commit_slot( ltt_deliver_callback(ltt_buf, SUBBUF_INDEX(offset_begin, ltt_buf), NULL); } } - - -#endif //LTT_TRACE +#ifdef __cplusplus +} /* end of extern "C" */ +#endif +#endif //LTT_TRACE_FAST +#endif //LTT_TRACE #endif //_LTT_USERTRACE_FAST_H