_NTO_TRACE_GET*(), _NTO_TRACE_SET*()

Updated: May 06, 2022

Macros for working with the header of a trace event

Synopsis:

#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) ...

Arguments:

h
The header of a trace event.
cl
(_NTO_TRACE_SETEVENT_C() only) An internal class code of a trace event; see below.
e
(_NTO_TRACE_SETEVENT() only) An internal event code of a trace event; see below.

These arguments are all of type unsigned.

Description:

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):

_NTO_TRACE_GETEVENT_C(h)
Get the class.
_NTO_TRACE_GETEVENT(h)
Get the type of event.
_NTO_TRACE_GETCPU(h)
Get the number of the CPU that the event occurred on.
_NTO_TRACE_SETEVENT_C(h,cl)
Set the class in the header c to be cl.
_NTO_TRACE_SETEVENT(h, e)
Set the event type in the header c to be e.

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.

Examples:

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);
   }
}

Classification:

QNX Neutrino

Safety:  
Cancellation point No
Interrupt handler Yes
Signal handler Yes
Thread Yes