#include <vppinfra/format.h>
#include <vppinfra/hash.h>
#include <vppinfra/math.h>
+#include <vppinfra/lock.h>
static inline void
elog_lock (elog_main_t * em)
{
if (PREDICT_FALSE (em->lock != 0))
- while (__sync_lock_test_and_set (em->lock, 1))
- ;
+ while (clib_atomic_test_and_set (em->lock))
+ CLIB_PAUSE ();
}
static inline void
{
if (PREDICT_FALSE (em->lock != 0))
{
- CLIB_MEMORY_BARRIER ();
- *em->lock = 0;
+ clib_atomic_release (em->lock);
}
}
elog_lock (em);
+ /* Multiple simultaneous registration attempts, */
+ if (t->type_index_plus_one > 0)
+ {
+ elog_unlock (em);
+ return t->type_index_plus_one - 1;
+ }
+
l = vec_len (em->event_types);
t->type_index_plus_one = 1 + l;
}
u8 *
-format_elog_track (u8 * s, va_list * va)
+format_elog_track_name (u8 * s, va_list * va)
{
elog_main_t *em = va_arg (*va, elog_main_t *);
elog_event_t *e = va_arg (*va, elog_event_t *);
return format (s, "%s", t->name);
}
+u8 *
+format_elog_track (u8 * s, va_list * args)
+{
+ elog_main_t *em = va_arg (*args, elog_main_t *);
+ f64 dt = va_arg (*args, f64);
+ int track_index = va_arg (*args, int);
+ elog_event_t *e, *es;
+ u8 indent;
+
+ indent = format_get_indent (s) + 1;
+
+ es = elog_peek_events (em);
+ vec_foreach (e, es)
+ {
+ if (e->track != track_index)
+ continue;
+ s = format (s, "%U%18.9f: %U\n", format_white_space, indent, e->time + dt,
+ format_elog_event, em, e);
+ }
+ vec_free (es);
+ return s;
+}
+
void
elog_time_now (elog_time_stamp_t * et)
{
#ifdef CLIB_UNIX
{
#include <sys/syscall.h>
+#ifdef __APPLE__
+ clock_gettime (CLOCK_REALTIME, &ts);
+#else
syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts);
+#endif
cpu_time_now = clib_cpu_time_now ();
/* Subtract 3/30/2017's worth of seconds to retain precision */
os_time_now_nsec = 1e9 * (ts.tv_sec - 1490885108) + ts.tv_nsec;
void
elog_init (elog_main_t * em, u32 n_events)
{
- memset (em, 0, sizeof (em[0]));
+ clib_memset (em, 0, sizeof (em[0]));
em->lock = 0;
elog_track_register (em, &em->default_track);
elog_time_now (&em->init_time);
+ em->string_table_hash = hash_create_string (0, sizeof (uword));
}
/* Returns number of events in ring and start index. */
elog_string (elog_main_t * em, char *fmt, ...)
{
u32 offset;
+ uword *p;
+ uword len;
va_list va;
+ elog_lock (em);
+ vec_reset_length (em->string_table_tmp);
va_start (va, fmt);
- offset = vec_len (em->string_table);
- em->string_table = (char *) va_format ((u8 *) em->string_table, fmt, &va);
+ em->string_table_tmp = va_format (em->string_table_tmp, fmt, &va);
va_end (va);
- /* Null terminate string if it is not already. */
- if (vec_end (em->string_table)[-1] != 0)
- vec_add1 (em->string_table, 0);
+ /* String table entries MUST be NULL terminated */
+ len = vec_len (em->string_table_tmp);
+ ASSERT (len > 0);
+ if (em->string_table_tmp[len - 1] != 0)
+ vec_add1 (em->string_table_tmp, 0);
+
+ /* See if we already have this string in the string table */
+ p = hash_get_mem (em->string_table_hash, em->string_table_tmp);
+
+ /* We already have the string, so give the caller its offset */
+ if (p)
+ {
+ elog_unlock (em);
+ return (p[0]);
+ }
+
+ /* We don't, so add it. */
+
+ offset = vec_len (em->string_table);
+ vec_append (em->string_table, em->string_table_tmp);
+
+ hash_set_mem (em->string_table_hash, em->string_table_tmp, offset);
+
+ /* We gave the key to the string table hash, so we can't reuse it! */
+ em->string_table_tmp = 0;
+ elog_unlock (em);
return offset;
}
elog_track_t newt;
int i;
- memset (&newt, 0, sizeof (newt));
+ clib_memset (&newt, 0, sizeof (newt));
/* Acquire src and dst events */
elog_get_events (src);
/*
* Move the earlier set of events later, to avoid creating
- * events which preceed the Big Bang (aka have negative timestamps).
+ * events which precede the Big Bang (aka have negative timestamps).
*
* Not to any scale, we have something like the following picture:
*