7.3   Selecting Additional Libraries

When you select AIL level logging, all kernel libraries except sigLib are logged by default. You can reduce the amount of data collected by only selecting some libraries; just uncheck them in the Collection Configuration dialog box. You can increase the breadth of data collection by selecting sigLib or the additional library memLib.

Kernel Libraries

Rather than wanting to see information about all objects, you might be interested in how specific tasks, semaphores, and message queues interact. You can instrument combinations of objects in taskLib, semLib, msgLib, and wdLib. You cannot specify particular signals to instrument within sigLib: either all signals are instrumented, or none are. The same holds true for the memLib library.

Table 7-1 lists the WindView target routines that you can call to control the instrumentation of particular objects; see the reference entries in C. Library and Subroutine Reference for more details.

Table 7-1:  WindView Instrumentation Routines


Routine
 
Description
 

wvObjInst( )
 
instrument objects
 
wvSigInst( )
 
instrument signals
 
wvObjInstModeSet( )
 
set object instrumentation level
 

When you select a library by checking it in the Collection Configuration dialog box, all objects in that library, whether they already exist or not, are instrumented. When you start data collection, events are logged for these objects.

To instrument individual objects and groups of objects (whether or not they already exist on the target system), call wvObjInst( ) instead of selecting the library in the dialog box checklist.1 Events that affect these objects are logged if and when AIL level logging begins.

The wvObjInst( ) routine is declared as follows:

STATUS wvObjInst 
    ( 
    int     objType      /* object type: OBJ_TASK, OBJ_SEM, */ 
                         /* OBJ_MSG, OBJ_WD */ 
    void *  objId        /* object ID: specific ID or NULL for all */ 
                         /* objects of objType */ 
    int     mode         /* turn instrumentation on/off:  
                         /* INSTRUMENT_ON, INSTRUMENT_OFF */ 
    )

You cannot instrument individual signals, but you can instrument signals programmatically as well as from the GUI. If you choose, call wvSigInst( ) instead of selecting the library in the dialog box checklist.

The wvSigInst( ) routine is declared as follows:

STATUS wvSigInst 
    ( 
    int     mode         /* turn instrumentation on/off:  
                         /* INSTRUMENT_ON, INSTRUMENT_OFF */ 
    )

You can start event collection using the GUI, or you can start it programmatically. The following example code shows how to carry out a variety of tasks programmatically. Some of them could also be carried out from the GUI. The example creates a semaphore and then enables instrumentation for that semaphore, for signals, and for tasks. At a later point, it starts event logging at AIL level. Later still, it disables signal instrumentation, but other object instrumentation remains active; finally, it stops all event logging.

    sem3Id = semMCreate (SEM_Q_FIFO);  
... 
 
    /* enable object event instrumentation for semaphore 3 */ 
    status = wvObjInst (OBJ_SEM, sem3Id, INSTRUMENT_ON); 
 
    /* enable signal instrumentation */ 
    status = wvSigInst (INSTRUMENT_ON); 
 
    /* enable object event instrumentation for all tasks */ 
    status = wvObjInst (OBJ_TASK, NULL, INSTRUMENT_ON); 
... 
 
/* start event logging */ 
    status = wvEvtLogEnable (OBJECT_STATUS); 
 
/* events of interest are logged in the following code */ 
... 
 
/* disable signal instrumentation */ 
    status = wvSigInst (INSTRUMENT_OFF); 
 
... 
 
/* stop event logging */ 
    status = wvEvtLogDisable ();

The wvObjInstModeSet( ) routine lets you instrument a group of objects beginning from the time of their creation. This routine is declared as follows:

STATUS wvObjInstModeSet 
    ( 
    int    mode         /* turn instrumentation on/off:  
                        /* INSTRUMENT_ON, INSTRUMENT_OFF */ 
    )

For example, suppose you are adding a new module to an already existing piece of code. You might want to see how just those new objects affect the existing application; you do not want to instrument any other objects. Within the object initialization code of the new module, you can surround the creation calls with wvObjInstModeSet( ), as in the following example:

void newCode () 
    { 
    ... 
 
    /* enable instrumentation for all objects created here */ 
    status = wvObjInstModeSet(INSTRUMENT_ON); 
    ... 
    /* create message queue 1 */ 
    mq1Id = msgQCreate (5, 20, MSG_Q_FIFO); 
    /* create message queue 2 */ 
    mq2Id = msgQCreate (5, 20, MSG_Q_FIFO); 
    /* create semaphore 1 */ 
    sem1Id = semMCreate (SEM_Q_FIFO); 
    /* create task 1 */ 
    t1Id = taskSpawn ("task1", TASK_1_PRI, TASK_1_OPTS,  
                   TASK_1_SIZE, task1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 
    ... 
    /* disable object instrumentation */ 
    status = wvObjInstModeSet (INSTRUMENT_OFF) 
    ... 
    }

All objects created between the two calls to wvObjInstModeSet( ) are instrumented. Events that affect those objects are logged if and when AIL level logging is started--for example, with the wvEvtLogEnable( ) routine, as in the following example (which occurs after the newCode( ) fragment shown above):

void existingCode () 
    { 
    ... 
    /* area of existing code where objs from newCode module used */ 
    status = wvEvtLogEnable(OBJECT_STATUS); 
    ... 
 
    /* send a message to message queue 1 */ 
    status = msgQSend (mq1Id, &buff, MSG_4, MSG_4_TIMEOUT, 
                       MSG_PRI_NORMAL); 
    /* receive a message from message queue 2 */ 
    numbytes = msgQReceive (mq2Id, &buff, BUFF_SIZE, TICKS); 
    /* take semaphore 1 */ 
    status = semTake (sem1Id, SEM_1_TIMEOUT); 
    /* suspend task 1 */ 
    status = taskSuspend (t1Id); 
    ... 
 
    /* interesting section finished; stop event logging */ 
    status = wvEvtLogDisable(); 
    ... 
 
    }

To instrument all objects in the system programmatically, do the following at the beginning of your application:

These programmatic steps have the same effect as starting WindView with all five kernel libraries checked, starting WindView logging, and starting your application.

Additional Libraries

The data collected by these instrumented libraries is displayed in the usual way: with icons in the main view graph window. For statistical analysis, the spreadsheet link is used to generate "queries" into the event base that strain out the events necessary for typical statistical analysis purposes.

Each instrumented library is enabled or disabled as a whole. To control which libraries are logged, use the Collection Configuration dialog box (see 3.3 Instrumented Objects). To control what is displayed in the view graph, the Filter Events/States dialog box contains an entry for each additional library (see Figure 5-14).

For WindView 2.0 there is one non-kernel library instrumented, memLib. The information displayed from this library is slightly different from the information generated and displayed by kernel events. While the event data generated by this library is somewhat interesting, the critical information is usually the scalar information generated by the event. For example, the most interesting information about memory activities is usually how much memory is allocated at a particular time. See Figure 3-7 for an explanation of the display.

memLib

On the host, users can view cumulative information depicting what happens as allocated memory grows and shrinks in each target partition. They can see the addresses of memory blocks that get allocated and freed. This simplifies detecting memory leaks. Table 7-2 shows the memory routines associated with each event.

Table 7-2:  Memory Routines Associated with Memory Events


Event
 
Routines
   

memPartAlignedAlloc
 
memAlign( )
 
calloc( )
 
 
memPartAlignedAlloc( )
 
malloc( )
 
 
memPartAlloc( )
 
valloc( )
 
memPartFree
 
memPartFree( )
 
cfree( )
 
 
free( )
   
memPartCreate
 
memPartCreate( )
   
memPartRealloc
 
memPartRealloc( )
 
realloc( )
 
memPartAddToPool
 
memPartAddToPool( )
 
memAddToPool( )
 

The information logged for each event is as follows:

memPartAlignedAlloc   

short

 

eventId

 

event ID

 

UINT32

 

timeStamp

 

time stamp

 

UINT32

 

nBytes

 

amount of memory requested

 

UINT32

 

nBytesPlusHeaderAlign

 

total amount of memory allocated

 

UINT32

 

nBlock

 

pointer to memory block

 

UINT32

 

partId

 

ID of memory partition

 

memPartFree   

short

 

eventId

 

event ID

 

UINT32

 

timeStamp

 

time stamp

 

UINT32

 

nBytesPlusHeaderAlign

 

total amount of memory freed

 

UINT32

 

pBlock

 

pointer to memory block

 

UINT32

 

partId

 

ID of memory partition

 

memPartCreate   

short

 

eventId

 

event ID

 

UINT32

 

timeStamp

 

time stamp

 

UINT32

 

poolSize

 

amount of memory in partition

 

UINT32

 

partId

 

ID of memory partition

 

memPartRealloc   

short

 

eventId

 

event ID

 

UINT32

 

timeStamp

 

time stamp

 

UINT32

 

nBytes

 

amount of memory requested

 

UINT32

 

nBytesPlusHeaderAlign

 

total amount of memory allocated

 

UINT32

 

pBlock

 

pointer to memory block

 

UINT32

 

partId

 

ID of memory partition

 

memPartAddToPool   

short

 

eventId

 

event ID

 

UINT32

 

timeStamp

 

time stamp

 

UINT32

 

poolSize

 

amount of memory in partition

 

UINT32

 

partId

 

ID of memory partition

 


1:  To instrument only objects that are created after a certain point, use the wvObjInstModeSet( ) routine described later in this section.