Macros for working with the header of a trace event
#include <sys/trace.h> #define _NTO_TRACE_GETCPU(h) ... #define _NTO_TRACE_GETEVENT(h) ... #define _NTO_TRACE_GETEVENT_C(h) ... #define _NTO_TRACE_SETEVENT_C(h,cl) ... #define _NTO_TRACE_SETEVENT(h, e) ...
These arguments are all of type unsigned.
You can use the _NTO_TRACE_GET*() and _NTO_TRACE_SET*() macros to work with the header of a trace event (the header member of a traceevent_t or an event_data_t structure):
The class and event numbers that you use with these macros are internal representations that, when combined, fit into the trace event's header. There isn't a one-to-one mapping between the external and internal class numbers, so some of the internal event numbers are adjusted to indicate the class:
External class | Internal class | Adjustment to event numbers |
---|---|---|
_NTO_TRACE_COMM | _TRACE_COMM_C | |
_NTO_TRACE_CONTROL | _TRACE_CONTROL_C | |
_NTO_TRACE_EMPTY | _TRACE_EMPTY_C | |
_NTO_TRACE_INTa | _TRACE_INT_C | |
_NTO_TRACE_INTENTER | _TRACE_INT_C | Set to _TRACE_INT_ENTRY |
_NTO_TRACE_INTEXIT | _TRACE_INT_C | Set to _TRACE_INT_EXIT |
_NTO_TRACE_INT_HANDLER_ENTER | _TRACE_INT_C | Set to _TRACE_INT_HANDLER_ENTRY |
_NTO_TRACE_INT_HANDLER_EXIT | _TRACE_INT_C | Set to _TRACE_INT_HANDLER_EXIT |
_NTO_TRACE_KERCALLa | _TRACE_KER_CALL_C | |
_NTO_TRACE_KERCALLENTER | _TRACE_KER_CALL_C | |
_NTO_TRACE_KERCALLEXIT | _TRACE_KER_CALL_C | Add _TRACE_MAX_KER_CALL_NUM |
_NTO_TRACE_KERCALLINT | _TRACE_KER_CALL_C | Add 2 * _TRACE_MAX_KER_CALL_NUM |
_NTO_TRACE_PROCESS | _TRACE_PR_TH_C | Set to the position of the rightmost set bit plus 1, shifted left 6 places |
_NTO_TRACE_SEC | _TRACE_SEC_C | |
_NTO_TRACE_SYSTEM | _TRACE_SYSTEM_C | |
_NTO_TRACE_THREAD | _TRACE_PR_TH_C | Set to the position of the rightmost set bit |
_NTO_TRACE_USER | _TRACE_USER_C | |
_NTO_TRACE_VTHREAD | _TRACE_PR_TH_C | Set to the position of the rightmost set bit, plus _TRACE_MAX_TH_STATE_NUM |
a This is a pseudo-class that comprises all the related classes.
See the parser in the Sample Programs appendix of the System Analysis Toolkit User's Guide.
Here's some code that converts external classes to internal ones, and vice versa:
/* * Finds rightmost bit location */ static unsigned ck_bit(uint32_t k) { if(k) { unsigned s=0U; while (!(k & 0x1)) { ++s; k >>= 1; } return (s); } else { return (unsigned)(-1); } } void external_to_internal (unsigned ext_class, unsigned ext_event, unsigned *int_class, unsigned *int_event) { *int_class = -1; *int_event = -1; switch (ext_class) { case _NTO_TRACE_COMM: *int_class = _TRACE_COMM_C; *int_event = ext_event; break; case _NTO_TRACE_CONTROL: *int_class = _TRACE_CONTROL_C; *int_event = ext_event; break; case _NTO_TRACE_INTENTER: *int_class = _TRACE_INT_C; *int_event = _TRACE_INT_ENTRY; break; case _NTO_TRACE_INTEXIT: *int_class = _TRACE_INT_C; *int_event = _TRACE_INT_EXIT; break; case _NTO_TRACE_INT_HANDLER_ENTER: *int_class = _TRACE_INT_C; *int_event = _TRACE_INT_HANDLER_ENTRY; break; case _NTO_TRACE_INT_HANDLER_EXIT: *int_class = _TRACE_INT_C; *int_event = _TRACE_INT_HANDLER_EXIT; break; case _NTO_TRACE_KERCALLENTER: *int_class = _TRACE_KER_CALL_C; *int_event = ext_event; break; case _NTO_TRACE_KERCALLEXIT: *int_class = _TRACE_KER_CALL_C; *int_event = ext_event + _TRACE_MAX_KER_CALL_NUM; break; case _NTO_TRACE_KERCALLINT: *int_class = _TRACE_KER_CALL_C; *int_event = ext_event + (2 * _TRACE_MAX_KER_CALL_NUM); break; case _NTO_TRACE_PROCESS: *int_class = _TRACE_PR_TH_C; *int_event = (ck_bit( ext_event) + 1) << 6; break; case _NTO_TRACE_SEC: *int_class = _TRACE_SEC_C; *int_event = ext_event; break; case _NTO_TRACE_SYSTEM: *int_class = _TRACE_SYSTEM_C; *int_event = ext_event; break; case _NTO_TRACE_THREAD: *int_class = _TRACE_PR_TH_C; *int_event = ck_bit( ext_event); break; case _NTO_TRACE_USER: *int_class = _TRACE_USER_C; *int_event = ext_event; break; case _NTO_TRACE_VTHREAD: *int_class = _TRACE_PR_TH_C; *int_event = ck_bit( ext_event) + _TRACE_MAX_TH_STATE_NUM; break; default: printf ("Unknown class: %d\n", ext_class); } } void internal_to_external (unsigned int_class, unsigned int_event, unsigned *ext_class, unsigned *ext_event) { int event_64 = 0; *ext_class = -1; *ext_event = -1; switch (int_class) { case _TRACE_COMM_C: *ext_class = _NTO_TRACE_COMM; *ext_event = int_event; break; case _TRACE_CONTROL_C: *ext_class = _NTO_TRACE_CONTROL; *ext_event = int_event; break; case _TRACE_INT_C: *ext_event = -1; switch (int_event) { case _TRACE_INT_ENTRY: *ext_class = _NTO_TRACE_INTENTER; break; case _TRACE_INT_EXIT: *ext_class = _NTO_TRACE_INTEXIT; break; case _TRACE_INT_HANDLER_ENTRY: *ext_class = _NTO_TRACE_INT_HANDLER_ENTER; break; case _TRACE_INT_HANDLER_EXIT: *ext_class = _NTO_TRACE_INT_HANDLER_EXIT; break; default: printf ("Unknown Interrupt event: %d\n", int_event); } break; case _TRACE_KER_CALL_C: /* Remove _NTO_TRACE_KERCALL64 if it's set. */ if (int_event & _NTO_TRACE_KERCALL64) { event_64 = 1; int_event = int_event & ~_NTO_TRACE_KERCALL64; } /* Determine the class and event. */ if (int_event < _TRACE_MAX_KER_CALL_NUM) { *ext_class = _NTO_TRACE_KERCALLENTER; *ext_event = int_event; } else if (int_event < 2 * _TRACE_MAX_KER_CALL_NUM) { *ext_class = _NTO_TRACE_KERCALLEXIT; *ext_event = int_event - _TRACE_MAX_KER_CALL_NUM; } else if (int_event < 3 * _TRACE_MAX_KER_CALL_NUM) { *ext_class = _NTO_TRACE_KERCALLINT; *ext_event = int_event - 2 * _TRACE_MAX_KER_CALL_NUM; } else { printf ("Unknown kernel event: %d\n", int_event); } /* Add _NTO_TRACE_KERCALL64 to the external event if it was set for the internal event. */ if (event_64) { *ext_event = *ext_event | _NTO_TRACE_KERCALL64; } break; case _TRACE_PR_TH_C: *ext_event = -1; if (int_event >= (2 * _TRACE_MAX_TH_STATE_NUM)) { *ext_class = _NTO_TRACE_PROCESS; *ext_event = 1 << ((int_event >> 6) - 1); } else if (int_event >= _TRACE_MAX_TH_STATE_NUM) { *ext_class = _NTO_TRACE_VTHREAD; *ext_event = 1 << (int_event - _TRACE_MAX_TH_STATE_NUM); } else { *ext_class = _NTO_TRACE_THREAD; *ext_event = 1 << int_event; } break; case _TRACE_SEC_C: *ext_class = _NTO_TRACE_SEC; *ext_event = int_event; break; case _TRACE_SYSTEM_C: *ext_class = _NTO_TRACE_SYSTEM; *ext_event = int_event; break; case _TRACE_USER_C: *ext_class = _NTO_TRACE_USER; *ext_event = int_event; break; default: printf ("Unknown class: %d\n", int_class); } }
Safety: | |
---|---|
Cancellation point | No |
Interrupt handler | Yes |
Signal handler | Yes |
Thread | Yes |