49 while (__sync_lock_test_and_set (em->
lock, 1))
132 for (i = 0; i < l; i++)
138 if (t->
format[i + 1] ==
'%')
227 digits[0] = digits[1] = 0;
228 while (p[i] >=
'0' && p[i] <=
'9')
232 digits[
i] = p[
i] -
'0';
236 if (i >= 1 && i <= 2)
241 *number = 10 * digits[0] + digits[1];
259 if (f[0] ==
'%' && f[1] !=
'%')
273 f += f[0] ==
'+' || f[0] ==
'-' || f[0] ==
'=';
276 while ((f[0] >=
'0' && f[0] <=
'9') || f[0] ==
'.')
280 f += f[0] ==
'w' || f[0] ==
'l' || f[0] ==
'L';
285 ASSERT (*result_len > f - percent);
286 l =
clib_min (f - percent, *result_len - 1);
291 *result_len = f - fmt;
311 uword n_bytes = 0, n_digits, f_bytes = 0;
313 f_bytes =
sizeof (arg_format);
317 if (a == 0 || a[0] == 0)
339 else if (n_bytes == 2)
341 else if (n_bytes == 4)
343 else if (n_bytes == 8)
351 s =
format (s, arg_format, e);
353 else if (a[0] ==
'T')
357 s =
format (s, arg_format, e);
359 else if (n_bytes == 8)
360 s =
format (s, arg_format, l);
362 s =
format (s, arg_format, i);
371 else if (n_bytes == 8)
375 s =
format (s, arg_format, x);
380 s =
format (s, arg_format, d);
382 n_bytes = strlen (d) + 1;
390 ASSERT (n_digits > 0 && n_digits <= 2);
410 u64 cpu_time_now, os_time_now_nsec;
415 #include <sys/syscall.h> 416 syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts);
419 os_time_now_nsec = 1e9 * (ts.tv_sec - 1490885108) + ts.tv_nsec;
423 os_time_now_nsec = 0;
426 et->
cpu = cpu_time_now;
427 et->
os_nsec = os_time_now_nsec;
468 memset (em, 0,
sizeof (em[0]));
515 for (i = 0; i < n; i++)
573 uword n_bytes = 0, n_digits;
600 ASSERT (n_digits > 0 && n_digits <= 2);
630 u32 string_table_offset_for_src_events;
631 u32 track_offset_for_src_tracks;
635 memset (&newt, 0,
sizeof (newt));
655 new_name = (
char *)
format (0,
"%s:%s%c", dst_tag, t->
name, 0);
688 string_table_offset_for_src_events);
691 e->
track += track_offset_for_src_tracks;
696 f64 dt_event, dt_os_nsec, dt_clock_nsec;
709 dt_event = dt_os_nsec;
727 &&
fabs (dt_os_nsec - dt_clock_nsec) < 100)
728 dt_event = dt_clock_nsec;
756 e->
time += dt_event + align_tweak;
761 dt_event = -dt_event;
762 for (e = dst->
events + 0; e < dst->events + l; e++)
763 e->
time += dt_event + align_tweak;
806 uword n_digits, n_bytes = 0;
817 else if (n_bytes == 2)
819 else if (n_bytes == 4)
821 else if (n_bytes == 8)
830 n_bytes = strlen ((
char *) d) + 1;
836 else if (n_bytes == 8)
883 uword n_digits, n_bytes = 0;
898 else if (n_bytes == 2)
903 else if (n_bytes == 4)
908 else if (n_bytes == 8)
923 n_bytes = strlen (t) + 1;
936 else if (n_bytes == 8)
960 int n = va_arg (*va,
int);
962 for (i = 0; i < n; i++)
969 sizeof (t[i].n_enum_strings));
979 int n = va_arg (*va,
int);
981 for (i = 0; i < n; i++)
988 sizeof (t[i].n_enum_strings));
989 vec_resize (t[i].enum_strings_vector, t[i].n_enum_strings);
999 int n = va_arg (*va,
int);
1001 for (i = 0; i < n; i++)
1011 int n = va_arg (*va,
int);
1013 for (i = 0; i < n; i++)
1041 int flush_ring = va_arg (*va,
int);
char ** enum_strings_vector
String table as a vector constructed when type is registered.
f64 time
Absolute time as floating point number in seconds.
elog_time_stamp_t serialize_time
void unserialize_check_magic(serialize_main_t *m, void *magic, u32 magic_bytes)
elog_event_t * elog_get_events(elog_main_t *em)
convert event ring events to events, and return them as a vector.
static void maybe_fix_string_table_offset(elog_event_t *e, elog_event_type_t *t, u32 offset)
static i64 elog_time_stamp_diff_os_nsec(elog_time_stamp_t *t1, elog_time_stamp_t *t2)
void elog_time_now(elog_time_stamp_t *et)
#define vec_serialize(m, v, f)
word elog_track_register(elog_main_t *em, elog_track_t *t)
register an event track
elog_time_stamp_t init_time
Timestamps.
#define vec_unserialize(m, v, f)
serialize_function_t unserialize_64
u64 time_cycles
Absolute time stamp in CPU clock cycles.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static u64 clib_cpu_time_now(void)
u8 * format_elog_track(u8 *s, va_list *va)
char * function
Function name generating event.
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
#define hash_set_mem(h, key, value)
static void elog_lock(elog_main_t *em)
void serialize_elog_main(serialize_main_t *m, va_list *va)
u8 * format_elog_event(u8 *s, va_list *va)
char * format
Format string.
static uword find_or_create_type(elog_main_t *em, elog_event_type_t *t)
serialize_function_t serialize_64
u8 data[20]
20-bytes of data follows, pads to 32 bytes.
static void serialize_elog_time_stamp(serialize_main_t *m, va_list *va)
char * enum_strings[]
String table for enum/number to string formatting.
static void unserialize_elog_event_type(serialize_main_t *m, va_list *va)
static void new_event_type(elog_main_t *em, uword i)
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
void unserialize_elog_main(serialize_main_t *m, va_list *va)
u32 n_enum_strings
Number of elements in string enum table.
serialize_function_t unserialize_f32
static void unserialize_elog_event(serialize_main_t *m, va_list *va)
void elog_init(elog_main_t *em, u32 n_events)
word elog_event_type_register(elog_main_t *em, elog_event_type_t *t)
register an event type
u32 type_index_plus_one
Type index plus one assigned to this type.
static i64 elog_time_stamp_diff_cpu(elog_time_stamp_t *t1, elog_time_stamp_t *t2)
static void unserialize_elog_time_stamp(serialize_main_t *m, va_list *va)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
uword * lock
SMP lock, non-zero means locking required.
static uword elog_event_range(elog_main_t *em, uword *lo)
char * format_args
Specifies how arguments to format are parsed from event data.
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
#define vec_end(v)
End (last data address) of vector.
uword * event_type_by_format
Hash table mapping type format to type index.
static int elog_cmp(void *a1, void *a2)
elog_event_type_t * event_types
Vector of event types.
static uword parse_2digit_decimal(char *p, uword *number)
static char * elog_serialize_magic
char * name
Track name vector.
elog_event_t * event_ring
Vector of events (circular buffer).
static void serialize_elog_event_type(serialize_main_t *m, va_list *va)
f64 nsec_per_cpu_clock
Use serialize_time and init_time to give estimate for cpu clock frequency.
static void unserialize_elog_track(serialize_main_t *m, va_list *va)
void clib_time_init(clib_time_t *c)
void elog_alloc(elog_main_t *em, u32 n_events)
serialize_function_t unserialize_f64
void unserialize_cstring(serialize_main_t *m, char **s)
static void elog_unlock(elog_main_t *em)
The fine-grained event logger allows lightweight, thread-safe event logging at minimum cost...
clib_error_t * serialize(serialize_main_t *m,...)
#define vec_free(V)
Free vector's memory (no header).
static f64 elog_nsec_per_clock(elog_main_t *em)
#define clib_memcpy(a, b, c)
static void serialize_elog_event(serialize_main_t *m, va_list *va)
static uword max_pow2(uword x)
u32 track_index_plus_one
Set to one when track has been added to main structure.
static void unserialize_integer(serialize_main_t *m, void *x, u32 n_bytes)
static void serialize_integer(serialize_main_t *m, u64 x, u32 n_bytes)
u32 n_total_events_disable_limit
When count reaches limit logging is disabled.
static void serialize_elog_track(serialize_main_t *m, va_list *va)
u64 os_nsec
OS timer in nano secs since epoch 3/30/2017, see elog_time_now()
serialize_function_t unserialize_vec_8
void serialize_magic(serialize_main_t *m, void *magic, u32 magic_bytes)
uword event_ring_size
Power of 2 number of elements in ring.
u64 cpu
CPU cycle counter.
clib_error_t * unserialize(serialize_main_t *m,...)
#define vec_append(v1, v2)
Append v2 after v1.
u16 track
Track for this event.
#define clib_mem_unaligned(pointer, type)
clib_time_t cpu_timer
Place holder for CPU clock frequency.
serialize_function_t serialize_f32
void serialize_cstring(serialize_main_t *m, char *s)
#define vec_elt(v, i)
Get vector value at index i.
elog_event_t * events
Vector of events converted to generic form after collection.
template key/value backing page structure
#define hash_create_vec(elts, key_bytes, value_bytes)
serialize_function_t serialize_vec_8
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)
u16 type
Event type index.
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
void * elog_event_data(elog_main_t *em, elog_event_type_t *type, elog_track_t *track, u64 cpu_time)
elog_track_t * tracks
Vector of tracks.
#define hash_get_mem(h, key)
struct clib_bihash_value offset
template key/value backing page structure
static u8 * fixed_format(u8 *s, char *fmt, char *result, uword *result_len)
char * string_table
Events may refer to strings in string table.
#define vec_foreach(var, vec)
Vector iterator.
elog_track_t default_track
Default track.
#define CLIB_MEMORY_BARRIER()
void elog_merge(elog_main_t *dst, u8 *dst_tag, elog_main_t *src, u8 *src_tag, f64 align_tweak)
u32 n_total_events
Total number of events in buffer.
#define CLIB_CACHE_LINE_BYTES
static void * elog_event_data_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.
elog_event_t * elog_peek_events(elog_main_t *em)
convert event ring events to events, and return them as a vector.
serialize_function_t serialize_f64
#define vec_resize_aligned(V, N, A)
Resize a vector (no header, alignment specified).