diff options
Diffstat (limited to 'vppinfra/vppinfra/elog.h')
-rw-r--r-- | vppinfra/vppinfra/elog.h | 460 |
1 files changed, 0 insertions, 460 deletions
diff --git a/vppinfra/vppinfra/elog.h b/vppinfra/vppinfra/elog.h deleted file mode 100644 index 9756fb83a8d..00000000000 --- a/vppinfra/vppinfra/elog.h +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (c) 2015 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - Copyright (c) 2005,2009 Eliot Dresselhaus - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -/* High speed event logging with much thanks to Dave Barach. */ - -#ifndef included_clib_elog_h -#define included_clib_elog_h - -#include <vppinfra/cache.h> -#include <vppinfra/error.h> /* for ASSERT */ -#include <vppinfra/serialize.h> -#include <vppinfra/time.h> /* for clib_cpu_time_now */ -#include <vppinfra/mhash.h> - -typedef struct -{ - union - { - /* Absolute time stamp in CPU clock cycles. */ - u64 time_cycles; - - /* Absolute time as floating point number in seconds. */ - f64 time; - }; - - /* Event type index. */ - u16 type; - - /* Track for this event. Tracks allow events to be sorted and - displayed by track. Think of 2 dimensional display with time and - track being the x and y axes. */ - u16 track; - - /* 20-bytes of data follows and pads to 32 bytes. */ - u8 data[20]; -} elog_event_t; - -typedef struct -{ - /* Type index plus one assigned to this type. - This is used to mark type as seen. */ - u32 type_index_plus_one; - - /* String table as a vector constructed when type is registered. */ - char **enum_strings_vector; - - /* Format string. (example: "my-event (%d,%d)"). */ - char *format; - - /* Specifies how arguments to format are parsed from event data. - String of characters '0' '1' or '2' '3' to specify log2 size of data - (e.g. for u8, u16, u32 or u64), - 's' means a null-terminated C string - 't' means argument is an index into enum string table for this type. - 'e' is a float, - 'f' is a double. */ - char *format_args; - - /* Function name generating event. */ - char *function; - - /* Number of elements in string enum table. */ - u32 n_enum_strings; - - /* String table for enum/number to string formatting. */ - char *enum_strings[]; -} elog_event_type_t; - -typedef struct -{ - /* Track name vector. */ - char *name; - - /* Set to one when track has been added to - main structure. */ - u32 track_index_plus_one; -} elog_track_t; - -typedef struct -{ - /* CPU cycle counter. */ - u64 cpu; - - /* OS timer in nano secs since epoch Jan 1 1970. */ - u64 os_nsec; -} elog_time_stamp_t; - -typedef struct -{ - /* Total number of events in buffer. */ - u32 n_total_events; - - /* When count reaches limit logging is disabled. This is - used for event triggers. */ - u32 n_total_events_disable_limit; - - /* Dummy event to use when logger is disabled. */ - elog_event_t dummy_event; - - /* Power of 2 number of elements in ring. */ - uword event_ring_size; - - /* Vector of events (circular buffer). Power of 2 size. - Used when events are being collected. */ - elog_event_t *event_ring; - - /* Vector of event types. */ - elog_event_type_t *event_types; - - /* Hash table mapping type format to type index. */ - uword *event_type_by_format; - - /* Events may refer to strings in string table. */ - char *string_table; - - /* Vector of tracks. */ - elog_track_t *tracks; - - /* Default track. */ - elog_track_t default_track; - - /* Place holder for CPU clock frequency. */ - clib_time_t cpu_timer; - - elog_time_stamp_t init_time, serialize_time; - - /* SMP lock, non-zero means locking required */ - uword *lock; - - /* Use serialize_time and init_time to give estimate for - cpu clock frequency. */ - f64 nsec_per_cpu_clock; - - /* Vector of events converted to generic form after collection. */ - elog_event_t *events; -} elog_main_t; - -always_inline uword -elog_n_events_in_buffer (elog_main_t * em) -{ - return clib_min (em->n_total_events, em->event_ring_size); -} - -always_inline uword -elog_buffer_capacity (elog_main_t * em) -{ - return em->event_ring_size; -} - -always_inline void -elog_reset_buffer (elog_main_t * em) -{ - em->n_total_events = 0; - em->n_total_events_disable_limit = ~0; -} - -always_inline void -elog_enable_disable (elog_main_t * em, int is_enabled) -{ - em->n_total_events = 0; - em->n_total_events_disable_limit = is_enabled ? ~0 : 0; -} - -/* Disable logging after specified number of ievents have been logged. - This is used as a "debug trigger" when a certain event has occurred. - Events will be logged both before and after the "event" but the - event will not be lost as long as N < RING_SIZE. */ -always_inline void -elog_disable_after_events (elog_main_t * em, uword n) -{ - em->n_total_events_disable_limit = em->n_total_events + n; -} - -/* Signal a trigger. We do this when we encounter an event that we want to save - context around (before and after). */ -always_inline void -elog_disable_trigger (elog_main_t * em) -{ - em->n_total_events_disable_limit = - em->n_total_events + vec_len (em->event_ring) / 2; -} - -/* External function to register types/tracks. */ -word elog_event_type_register (elog_main_t * em, elog_event_type_t * t); -word elog_track_register (elog_main_t * em, elog_track_t * t); - -always_inline uword -elog_is_enabled (elog_main_t * em) -{ - return em->n_total_events < em->n_total_events_disable_limit; -} - -/* Add an event to the log. Returns a pointer to the - data for caller to write into. */ -always_inline void * -elog_event_data_inline (elog_main_t * em, - elog_event_type_t * type, - elog_track_t * track, u64 cpu_time) -{ - elog_event_t *e; - uword ei; - word type_index, track_index; - - /* Return the user dummy memory to scribble data into. */ - if (PREDICT_FALSE (!elog_is_enabled (em))) - return em->dummy_event.data; - - type_index = (word) type->type_index_plus_one - 1; - track_index = (word) track->track_index_plus_one - 1; - if (PREDICT_FALSE ((type_index | track_index) < 0)) - { - if (type_index < 0) - type_index = elog_event_type_register (em, type); - if (track_index < 0) - track_index = elog_track_register (em, track); - } - - ASSERT (type_index < vec_len (em->event_types)); - ASSERT (track_index < vec_len (em->tracks)); - ASSERT (is_pow2 (vec_len (em->event_ring))); - - if (em->lock) - ei = clib_smp_atomic_add (&em->n_total_events, 1); - else - ei = em->n_total_events++; - - ei &= em->event_ring_size - 1; - e = vec_elt_at_index (em->event_ring, ei); - - e->time_cycles = cpu_time; - e->type = type_index; - e->track = track_index; - - /* Return user data for caller to fill in. */ - return e->data; -} - -/* External version of inline. */ -void *elog_event_data (elog_main_t * em, - elog_event_type_t * type, - elog_track_t * track, u64 cpu_time); - -/* Non-inline version. */ -always_inline void * -elog_event_data_not_inline (elog_main_t * em, - elog_event_type_t * type, - elog_track_t * track, u64 cpu_time) -{ - /* Return the user dummy memory to scribble data into. */ - if (PREDICT_FALSE (!elog_is_enabled (em))) - return em->dummy_event.data; - return elog_event_data (em, type, track, cpu_time); -} - -/* Most common forms: log a single 32 bit datum, w / w-out track */ -always_inline void -elog (elog_main_t * em, elog_event_type_t * type, u32 data) -{ - u32 *d = elog_event_data_not_inline (em, - type, - &em->default_track, - clib_cpu_time_now ()); - d[0] = data; -} - -/* Inline version of above. */ -always_inline void -elog_inline (elog_main_t * em, elog_event_type_t * type, u32 data) -{ - u32 *d = elog_event_data_inline (em, - type, - &em->default_track, - clib_cpu_time_now ()); - d[0] = data; -} - -always_inline void -elog_track (elog_main_t * em, elog_event_type_t * type, elog_track_t * track, - u32 data) -{ - u32 *d = elog_event_data_not_inline (em, - type, - track, - clib_cpu_time_now ()); - d[0] = data; -} - -always_inline void -elog_track_inline (elog_main_t * em, elog_event_type_t * type, - elog_track_t * track, u32 data) -{ - u32 *d = elog_event_data_inline (em, - type, - track, - clib_cpu_time_now ()); - d[0] = data; -} - -always_inline void * -elog_data (elog_main_t * em, elog_event_type_t * type, elog_track_t * track) -{ - return elog_event_data_not_inline (em, type, track, clib_cpu_time_now ()); -} - -always_inline void * -elog_data_inline (elog_main_t * em, elog_event_type_t * type, - elog_track_t * track) -{ - return elog_event_data_inline (em, type, track, clib_cpu_time_now ()); -} - -/* Macro shorthands for generating/declaring events. */ -#define __ELOG_TYPE_VAR(f) f -#define __ELOG_TRACK_VAR(f) f - -#define ELOG_TYPE_DECLARE(f) static elog_event_type_t __ELOG_TYPE_VAR(f) - -#define ELOG_TYPE_INIT_FORMAT_AND_FUNCTION(fmt,func) \ - { .format = fmt, .function = func, } - -#define ELOG_TYPE_INIT(fmt) \ - ELOG_TYPE_INIT_FORMAT_AND_FUNCTION(fmt,(char *) __FUNCTION__) - -#define ELOG_TYPE_DECLARE_HELPER(f,fmt,func) \ - static elog_event_type_t __ELOG_TYPE_VAR(f) = \ - ELOG_TYPE_INIT_FORMAT_AND_FUNCTION (fmt, func) - -#define ELOG_TYPE_DECLARE_FORMAT_AND_FUNCTION(f,fmt) \ - ELOG_TYPE_DECLARE_HELPER (f, fmt, (char *) __FUNCTION__) - -#define ELOG_TYPE_DECLARE_FORMAT(f,fmt) \ - ELOG_TYPE_DECLARE_HELPER (f, fmt, 0) - -/* Shorthands with and without __FUNCTION__. - D for decimal; X for hex. F for __FUNCTION__. */ -#define ELOG_TYPE(f,fmt) ELOG_TYPE_DECLARE_FORMAT_AND_FUNCTION(f,fmt) -#define ELOG_TYPE_D(f) ELOG_TYPE_DECLARE_FORMAT (f, #f " %d") -#define ELOG_TYPE_X(f) ELOG_TYPE_DECLARE_FORMAT (f, #f " 0x%x") -#define ELOG_TYPE_DF(f) ELOG_TYPE_DECLARE_FORMAT_AND_FUNCTION (f, #f " %d") -#define ELOG_TYPE_XF(f) ELOG_TYPE_DECLARE_FORMAT_AND_FUNCTION (f, #f " 0x%x") -#define ELOG_TYPE_FD(f) ELOG_TYPE_DECLARE_FORMAT_AND_FUNCTION (f, #f " %d") -#define ELOG_TYPE_FX(f) ELOG_TYPE_DECLARE_FORMAT_AND_FUNCTION (f, #f " 0x%x") - -#define ELOG_TRACK_DECLARE(f) static elog_track_t __ELOG_TRACK_VAR(f) -#define ELOG_TRACK(f) ELOG_TRACK_DECLARE(f) = { .name = #f, } - -/* Log 32 bits of data. */ -#define ELOG(em,f,data) elog ((em), &__ELOG_TYPE_VAR(f), data) -#define ELOG_INLINE(em,f,data) elog_inline ((em), &__ELOG_TYPE_VAR(f), data) - -/* Return data pointer to fill in. */ -#define ELOG_TRACK_DATA(em,f,track) \ - elog_data ((em), &__ELOG_TYPE_VAR(f), &__ELOG_TRACK_VAR(track)) -#define ELOG_TRACK_DATA_INLINE(em,f,track) \ - elog_data_inline ((em), &__ELOG_TYPE_VAR(f), &__ELOG_TRACK_VAR(track)) - -/* Shorthand with default track. */ -#define ELOG_DATA(em,f) elog_data ((em), &__ELOG_TYPE_VAR (f), &(em)->default_track) -#define ELOG_DATA_INLINE(em,f) elog_data_inline ((em), &__ELOG_TYPE_VAR (f), &(em)->default_track) - -u32 elog_string (elog_main_t * em, char *format, ...); -void elog_time_now (elog_time_stamp_t * et); - -/* Convert ievents to events and return them as a vector. - Sets em->events to resulting vector. */ -elog_event_t *elog_get_events (elog_main_t * em); - -/* Convert ievents to events and return them as a vector with no side effects. */ -elog_event_t *elog_peek_events (elog_main_t * em); - -/* Merge two logs, add supplied track tags. */ -void elog_merge (elog_main_t * dst, u8 * dst_tag, - elog_main_t * src, u8 * src_tag); - -/* 2 arguments elog_main_t and elog_event_t to format event or track name. */ -u8 *format_elog_event (u8 * s, va_list * va); -u8 *format_elog_track (u8 * s, va_list * va); - -void serialize_elog_main (serialize_main_t * m, va_list * va); -void unserialize_elog_main (serialize_main_t * m, va_list * va); - -void elog_init (elog_main_t * em, u32 n_events); -void elog_alloc (elog_main_t * em, u32 n_events); - -#ifdef CLIB_UNIX -always_inline clib_error_t * -elog_write_file (elog_main_t * em, char *unix_file) -{ - serialize_main_t m; - clib_error_t *error; - - error = serialize_open_unix_file (&m, unix_file); - if (error) - return error; - error = serialize (&m, serialize_elog_main, em); - if (!error) - serialize_close (&m); - return error; -} - -always_inline clib_error_t * -elog_read_file (elog_main_t * em, char *unix_file) -{ - serialize_main_t m; - clib_error_t *error; - - error = unserialize_open_unix_file (&m, unix_file); - if (error) - return error; - error = unserialize (&m, unserialize_elog_main, em); - if (!error) - unserialize_close (&m); - return error; -} - -#endif /* CLIB_UNIX */ - -#endif /* included_clib_elog_h */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ |