C

Triggering API



C.1    Overview

Because event triggering is based on the same instrumented points used by WindView, interactions occur between the two mechanisms which are managed to avoid interference or conflicts. When an instrumentation point is hit, one of the following situations exists:

  • neither instrumentation nor triggering is active

  • instrumentation is active but not triggering

  • triggering is active but not instrumentation

  • both triggering and instrumentation are active

In order to keep the two mechanisms separate, the macro ACTION_IS_SET is introduced. It is shared by the two tools and regulates the activation and interactions of both logging and triggering. The process flow is shown in the following pseudocode:

if ACTION_IS_SET  
    { 
    if WV_ACTION_IS_SET  
        do logging  
    if TRG_ACTION_IS_SET  
        do triggering  
    }

The do logging portion of the process is described in 7. Data Collection. The do triggering function performs the steps described in the flow chart in Figure C-1.  

Figure C-1:   Process Followed if Triggering is Activated

The trigger data structures are shown in C.2 Trigger Structure. All the operations allowed on triggers, such as create, destroy, enable, and disable, are described in C.3 Triggering API. These functions should be used principally through the host GUI. Many parameters are involved and the GUI provides guidance in choosing the proper environment for the construction or modification of a trigger.



C.2    Trigger Structure

The host tools allow users to enter specific information and commands, which the tools then download to the target. Data is usually entered in the GUI window, but it can be entered at the command line as well. The GUI displays and allows entering of the following information (see Figure C-2):

  • Show trigger information.

  • Activate triggering.

  • Create and delete triggers.

  • Enable and disable triggers.

  • Choose the event, context, and/or object which will activate a trigger.

  • Define a conditional expression to refine the circumstances which will activate the trigger (optional).

  • Define the actions related to the trigger (optional) such as:

  • call a user function (the function parameters must be given)

  • start or stop logging

  • Provide the ID of another trigger to be chained to the current one (optional).  

Figure C-2:   Triggering Window and Trigger Maintenance Dialog Box

Once it receives this information, the target is responsible for triggering and performs the following actions:

  • Organizes the data received from the host in a trigger list.

  • Manages the trigger list.

  • Activates and deactivates event triggering.

  • Performs the actions requested by the host (such as disabling, enabling, or deleting triggers).

  • Interacts with WindView and the event points.

The target saves the information coming from the host in a trigger structure. The target is also responsible for setting the flag to activate triggering when necessary. When this flag is set, the event can be detected by the regular WindView instrumentation, by e( ), or through trgEvent( ). Once the event occurs, the ACTION_IS_SET variable is checked to see whether WindView or triggering is active.

If triggering is active, the list of triggers is checked to see if any is related to that event. If one is found, the specified action is performed. Otherwise execution continues.

The triggering structure is defined as follows:

typedef struct trigger 
    { 
    OBJ_CORE          objCore;       /* trigger object core */ 
    event_t           eventId;       /* event type */ 
    UINT16            status;        /* status of the trigger, */ 
                                      /* i.e. enabled, disabled, etc */ 
    BOOL              disable;       /* check if trigger needs to be */ 
                                       /* disabled after use */ 
    int               contextType;   /* type of context where */ 
                                      /* event occurs */ 
    UINT32            contextId;     /* id of context where */ 
                                      /* event occurs */ 
    OBJ_ID            objId;         /* object type */ 
    struct trigger    *chain;        /* pointer to chained trigger */ 
    struct trigger    *next;         /* ptr to next trigger in list */ 
    int               conditional;   /* check if a condition is set */ 
    int               condType;      /* check the expression */ 
                                      /* type (var/fn) */ 
    void *            condEx1;       /* ptr to conditional expression */ 
    int               condOp;        /* conditional operator */ 
                                      */ (==, !=, ...) */ 
    int               condEx2;       /* second operand (constant) */ 
    int               actionType;    /* type of action (none, fn, lib) */ 
    FUNCPTR           actionFunc;    /* pointer to the action */ 
    int               actionArg;     /* argument passed to the action */ 
    BOOL              actionDef;     /* defer the action */ 
    } TRIGGER;

The following macros are also defined:

  • Representing the status of the trigger:

#define TRG_ENABLE 1 
#define TRG_DISABLE 0

  • Defining whether the condition is a variable or a function:

#define TRIGGER_COND_FUNC       0 
#define TRIGGER_COND_VAR        1 
#define TRIGGER_COND_LIB        2


C.3    Triggering API

The following functions are used to manipulate the triggering structure, to detect the presence of a trigger, and to perform the action specified in the trigger definition:

Adding a Trigger to the Trigger List

TRIGGER_ID trgAdd 
    ( 
    event_t     event,        /* event type as defined in eventP.h */ 
                               /* for WindView, if given */ 
    int         status,       /* initial status (enabled/disabled) */ 
    int         contextType,  /* type of context where event occurs */ 
    UINT32      contextId,    /* ID (if any) of context where event occurs */ 
    OBJ_ID      objId,        /* object type, if given */ 
    int         conditional,  /* flag specifying if there is a condition */ 
    int         condType,     /* flag specifying if an existing condition */ 
                               /* is a variable or a function */ 
    int         * condEx1,    /* pointer to conditional expression */ 
    int         condOp,       /* operator (==, !=, <, <=, >, >=, |, &) */ 
    int         condEx2,      /* second operand (constant) */ 
    BOOL        disable,      /* flag specifying whether to disable */ 
                               /* trigger after it is hit */ 
    TRIGGER     *chain,       /* flag specifying if another trigger is */ 
                               /* associated with this one */ 
    int         actionType,   /* action type associated with trigger */ 
    FUNCPTR     actionFunc,   /* pointer to the function */ 
    BOOL        actionDef,    /* defer the action */ 
    int         actionArg     /* argument passed to function if any */ 
    ) 
    { 
        fills in the trigger struct and adds it to the trigger list; 
        returns the trigger ID 
    }

Deleting a Trigger from the Trigger List

Triggers are deleted when they are removed from the trigger list. The function trgDelete( ) also checks to see if any other triggers are still active; if none are but triggering is still active, it turns it off. Triggering introduces some overhead and should be disabled if no function is present.

STATUS trgDelete 
    ( 
    TRIGGER_ID trgId 
    ) 
    { 
        delete the trigger from the table;         turn triggering off if this was  
        the last trigger and triggering  is still on 
    }

Activating Triggering

Any time an event point is hit when triggering is active, a check for the presence of possible triggers is performed. This introduces overhead, so it is important to activate triggering only when necessary:

STATUS trgOn() 
    { 
        set evtAction to TRG_ACTION_IS_SET if not already set 
    }

Deactivating Triggering

void trgOff() 
    { 
        set evtAction to TRG_ACTION_IS_UNSET if it is on 
    }

Showing Information on Triggers

The following information is given:

  • trigger ID
  • event ID
  • status
  • condition
  • disable trigger
  • chained trigger

If options is 1 and trgId is specified, all parameters are shown for the specified trigger. If trgId is NULL all the triggers are shown.

STATUS trgShow 
    ( 
    TRIGGER_ID trgId, 
    int        options 
    ) 
    { 
        display information on the specified trigger 
        or on all triggers 
    }

Changing Trigger Status

Once a trigger is created by trgAdd( ), its status can be set by using the trgEnable( ) function. This is the mechanism used to activate a chained trigger. A counter is also incremented to keep track of the total number of currently enabled triggers. This information is used by trgDisable( ).

STATUS trgEnable 
    ( 
    TRIGGER_ID trgId 
    ) 
    { 
        enable the trigger unless the maximum number of triggers 
        is already enabled 
    }

A trigger can be disabled by using trgDisable( ). This function also checks to see if there are any other triggers still active. This is done through the counter trgCnt. If trgCnt is 0 and triggering is still on, it calls trgOff( ).

STATUS trgDisable 
    ( 
    TRIGGER_ID trgId 
    ) 
    { 
        turn the trigger off; if this is the last active trigger,         turn triggering off. 
    }

Creating a User Event to Fire a Trigger

This routine triggers a user event. A trigger must exist and triggering must have been started with trgOn( ) or from the triggering GUI to use this routine. evtId must be in the range 40000-65535.

void trgEvent 
    ( 
    event_t evtId     /* event*/ 
    ) 
    { 
        set a user event with the specified ID 
    }