23 #include <sys/types.h> 46 int enable_fd, current_tracer_fd, data_fd;
48 struct timespec ts, ts2;
49 char *trace_enable =
"/debug/tracing/tracing_enabled";
50 char *current_tracer =
"/debug/tracing/current_tracer";
51 char *trace_data =
"/debug/tracing/trace";
52 f64 realtime, monotonic;
53 f64 freq, secs_per_clock;
63 enable_fd = open (trace_enable, O_RDWR);
70 if (write (enable_fd,
"0\n", 2) != 2)
81 data_fd = open (trace_data, O_RDWR | O_TRUNC);
90 current_tracer_fd = open (current_tracer, O_RDWR);
92 if (current_tracer_fd < 0)
99 len = strlen (kernel_tracer);
101 if (write (current_tracer_fd, kernel_tracer, len) != len)
104 close (current_tracer_fd);
109 close (current_tracer_fd);
119 syscall (SYS_clock_gettime, CLOCK_MONOTONIC, &ts);
122 if (write (enable_fd,
"1\n", 2) != 2)
138 s =
format (s,
"cpu %d task %10s type %s timestamp %12.6f\n",
147 u8 *cp = tdata + *index;
152 static u8 *task_name;
158 while (cp < limit && (*cp ==
' ' && *cp ==
'\t'))
166 while (cp < limit && (*cp !=
'\n'))
177 while (cp < limit && *cp !=
']')
190 while (cp < limit && (*cp ==
' ' && *cp ==
'\t'))
200 while (cp < limit && (*cp !=
'.'))
216 for (i = 0; i < 3; i++)
218 while (cp < limit && *cp !=
':')
260 while (cp < limit && (*cp ==
' ' || *cp ==
'\t'))
265 for (i = 0; i < 2; i++)
267 while (cp < limit && *cp !=
':')
284 while (cp < limit && (*cp !=
' ' && *cp !=
'\n'))
304 mhash_t *
h = &em->string_table_hash;
306 if (!em->string_table_hash.hash)
320 int enable_fd, data_fd;
321 char *trace_enable =
"/debug/tracing/tracing_enabled";
322 char *trace_data =
"/debug/tracing/trace";
325 int bytes, total_bytes;
332 enable_fd = open (trace_enable, O_RDWR);
339 if (write (enable_fd,
"0\n", 2) != 2)
348 data_fd = open (trace_data, O_RDWR);
364 bytes = read (data_fd, data + pos, 4096);
368 total_bytes += bytes;
369 _vec_len (data) = total_bytes;
388 .format =
"%d: %s %s",.format_args =
"i4T4t4",.n_enum_strings =
391 "running",
"wakeup",}
395 u32 cpu, string_table_offset, which;
402 ed->which = evt->
type;
404 _vec_len (evt->
task) = 0;
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
u8 * format_sched_event(u8 *s, va_list *va)
sll srl srl sll sra u16x4 i
elog_time_stamp_t init_time
Timestamps.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
void kelog_collect_sched_switch_trace(elog_main_t *em)
static u32 elog_id_for_pid(elog_main_t *em, u8 *name, u32 pid)
static void * elog_event_data_not_inline(elog_main_t *em, elog_event_type_t *type, elog_track_t *track, u64 cpu_time)
Allocate an event to be filled in by the caller, non-inline.
void elog_init(elog_main_t *em, u32 n_events)
void kelog_init(elog_main_t *em, char *kernel_tracer, u32 n_events)
sched_event_t * parse_sched_switch_trace(u8 *tdata, u32 *index)
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
void clib_time_init(clib_time_t *c)
The fine-grained event logger allows lightweight, thread-safe event logging at minimum cost...
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
#define clib_warning(format, args...)
#define ELOG_TYPE_DECLARE(f)
static uword * mhash_get(mhash_t *h, const void *key)
u64 cpu
CPU cycle counter.
clib_time_t cpu_timer
Place holder for CPU clock frequency.
u32 elog_string(elog_main_t *em, char *fmt,...)
add a string to the event-log string table
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define clib_unix_warning(format, args...)
elog_track_t default_track
Default track.