ikev2: add support for custom ipsec-over-udp port
[vpp.git] / src / vppinfra / elog.c
index a86fade..caddf6f 100644 (file)
 #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
@@ -55,8 +56,7 @@ elog_unlock (elog_main_t * em)
 {
   if (PREDICT_FALSE (em->lock != 0))
     {
-      CLIB_MEMORY_BARRIER ();
-      *em->lock = 0;
+      clib_atomic_release (em->lock);
     }
 }
 
@@ -396,7 +396,7 @@ format_elog_event (u8 * s, va_list * va)
 }
 
 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 *);
@@ -404,6 +404,29 @@ format_elog_track (u8 * s, va_list * va)
   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)
 {
@@ -469,7 +492,7 @@ elog_alloc (elog_main_t * em, u32 n_events)
 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;
 
@@ -485,6 +508,7 @@ elog_init (elog_main_t * em, u32 n_events)
   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. */
@@ -538,16 +562,42 @@ u32
 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;
 }
@@ -636,7 +686,7 @@ elog_merge (elog_main_t * dst, u8 * dst_tag, elog_main_t * src, u8 * src_tag,
   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);