2 /* LTTng user-space "fast" tracing header
4 * Copyright 2006 Mathieu Desnoyers
8 #ifndef _LTT_USERTRACE_FAST_H
9 #define _LTT_USERTRACE_FAST_H
12 #include <asm/atomic.h>
16 #include <linux/futex.h>
19 static inline _syscall6(long, futex
, unsigned long, uaddr
, int, op
, int, val
,
20 unsigned long, timeout
, unsigned long, uaddr2
, int, val2
)
25 #define LTT_N_SUBBUFS 2
26 #endif //LTT_N_SUBBUFS
28 #ifndef LTT_SUBBUF_SIZE_CPU
29 #define LTT_SUBBUF_SIZE_CPU 1048576
30 #endif //LTT_BUF_SIZE_CPU
32 #define LTT_BUF_SIZE_CPU (LTT_SUBBUF_SIZE_CPU * LTT_N_SUBBUFS)
34 #ifndef LTT_SUBBUF_SIZE_FACILITIES
35 #define LTT_SUBBUF_SIZE_FACILITIES 4096
36 #endif //LTT_BUF_SIZE_FACILITIES
38 #define LTT_BUF_SIZE_FACILITIES (LTT_SUBBUF_SIZE_FACILITIES * LTT_N_SUBBUFS)
40 #ifndef LTT_USERTRACE_ROOT
41 #define LTT_USERTRACE_ROOT "/tmp/ltt-usertrace"
42 #endif //LTT_USERTRACE_ROOT
45 /* Buffer offset macros */
47 #define BUFFER_OFFSET(offset, buf) (offset & (buf->alloc_size-1))
48 #define SUBBUF_OFFSET(offset, buf) (offset & (buf->subbuf_size-1))
49 #define SUBBUF_ALIGN(offset, buf) \
50 (((offset) + buf->subbuf_size) & (~(buf->subbuf_size-1)))
51 #define SUBBUF_TRUNC(offset, buf) \
52 ((offset) & (~(buf->subbuf_size-1)))
53 #define SUBBUF_INDEX(offset, buf) \
54 (BUFFER_OFFSET(offset,buf)/buf->subbuf_size)
57 #define LTT_TRACER_MAGIC_NUMBER 0x00D6B7ED
58 #define LTT_TRACER_VERSION_MAJOR 0
59 #define LTT_TRACER_VERSION_MINOR 7
61 #ifndef atomic_cmpxchg
62 #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
63 #endif //atomic_cmpxchg
64 struct ltt_trace_header
{
65 uint32_t magic_number
;
67 uint32_t arch_variant
;
68 uint32_t float_word_order
; /* Only useful for user space traces */
70 //uint32_t system_type;
71 uint8_t major_version
;
72 uint8_t minor_version
;
73 uint8_t flight_recorder
;
74 uint8_t has_heartbeat
;
75 uint8_t has_alignment
; /* Event header alignment */
79 uint64_t start_monotonic
;
80 uint64_t start_time_sec
;
81 uint64_t start_time_usec
;
82 } __attribute((packed
));
85 struct ltt_block_start_header
{
88 uint64_t freq
; /* khz */
92 uint64_t freq
; /* khz */
94 uint32_t lost_size
; /* Size unused at the end of the buffer */
95 uint32_t buf_size
; /* The size of this sub-buffer */
96 struct ltt_trace_header trace
;
97 } __attribute((packed
));
105 atomic_t reserve_count
[LTT_N_SUBBUFS
];
106 atomic_t commit_count
[LTT_N_SUBBUFS
];
108 atomic_t events_lost
;
109 atomic_t corrupted_subbuffers
;
110 atomic_t full
; /* futex on which the writer waits : 1 : full */
111 unsigned int alloc_size
;
112 unsigned int subbuf_size
;
115 struct ltt_trace_info
{
121 struct ltt_buf facilities
;
123 char facilities_buf
[LTT_BUF_SIZE_FACILITIES
] __attribute__ ((aligned (8)));
124 char cpu_buf
[LTT_BUF_SIZE_CPU
] __attribute__ ((aligned (8)));
130 extern __thread
struct ltt_trace_info
*thread_trace_info
;
132 void ltt_thread_init(void);
134 void ltt_usertrace_fast_buffer_switch(void);
138 static inline uint64_t ltt_get_timestamp()
143 static inline unsigned int ltt_subbuf_header_len(struct ltt_buf
*buf
)
145 return sizeof(struct ltt_block_start_header
);
150 static inline void ltt_write_trace_header(struct ltt_trace_header
*header
)
152 header
->magic_number
= LTT_TRACER_MAGIC_NUMBER
;
153 header
->major_version
= LTT_TRACER_VERSION_MAJOR
;
154 header
->minor_version
= LTT_TRACER_VERSION_MINOR
;
155 header
->float_word_order
= 0; //FIXME
156 header
->arch_type
= 0; //FIXME LTT_ARCH_TYPE;
157 header
->arch_size
= sizeof(void*);
158 header
->arch_variant
= 0; //FIXME LTT_ARCH_VARIANT;
159 header
->flight_recorder
= 0;
160 header
->has_heartbeat
= 0;
162 #ifdef CONFIG_LTT_ALIGNMENT
163 header
->has_alignment
= sizeof(void*);
165 header
->has_alignment
= 0;
169 header
->freq_scale
= 0;
170 header
->start_freq
= 0;
171 header
->start_tsc
= 0;
172 header
->start_monotonic
= 0;
173 header
->start_time_sec
= 0;
174 header
->start_time_usec
= 0;
178 static inline void ltt_buffer_begin_callback(struct ltt_buf
*buf
,
179 uint64_t tsc
, unsigned int subbuf_idx
)
181 struct ltt_block_start_header
*header
=
182 (struct ltt_block_start_header
*)
183 (buf
->start
+ (subbuf_idx
*buf
->subbuf_size
));
185 header
->begin
.cycle_count
= tsc
;
186 header
->begin
.freq
= 0; //ltt_frequency();
188 header
->lost_size
= 0xFFFFFFFF; // for debugging...
190 header
->buf_size
= buf
->subbuf_size
;
192 ltt_write_trace_header(&header
->trace
);
198 static inline void ltt_buffer_end_callback(struct ltt_buf
*buf
,
199 uint64_t tsc
, unsigned int offset
, unsigned int subbuf_idx
)
201 struct ltt_block_start_header
*header
=
202 (struct ltt_block_start_header
*)
203 (buf
->start
+ (subbuf_idx
*buf
->subbuf_size
));
204 /* offset is assumed to never be 0 here : never deliver a completely
205 * empty subbuffer. */
206 /* The lost size is between 0 and subbuf_size-1 */
207 header
->lost_size
= SUBBUF_OFFSET((buf
->subbuf_size
- offset
),
209 header
->end
.cycle_count
= tsc
;
210 header
->end
.freq
= 0; //ltt_frequency();
214 static inline void ltt_deliver_callback(struct ltt_buf
*buf
,
218 ltt_usertrace_fast_buffer_switch();
220 #endif //_LTT_USERTRACE_FAST_H