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:
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.
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.
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):
Once it receives this information, the target is responsible for triggering and performs the following actions:
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;
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
}
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
}
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
}
void trgOff()
{
set evtAction to TRG_ACTION_IS_UNSET if it is on
}
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
}
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.
}
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
}