[ Previous | Next | Contents | Glossary | Search ]
Performance Toolbox Version 1.2 and 2 for AIX: Guide and Reference

Chapter 16. System Performance Measurement Interface Programming Guide

The System Performance Measurement Interface (SPMI) is an application programming interface (API) that provides standardized access to local system resource statistics. By developing SPMI application programs, a user can retrieve information about system performance with minimum system overhead.

SPMI Overview

Two types of application programs can use the SPMI:

The Application Types figure illustrates the two different application types using the SPMI.



Figure 1. Application Types

Possible Uses for the SPMI

The SPMI assists programmers with the following tasks:

SPMI Features

The SPMI offers the following features:

Counter Data
Enables access of activity rate statistics, such as the number of disk-read operations per second.
Level Data
Enables access of system-usage statistics, such as the usage level of real memory.
Single Data Repository
Enables multiple data-user application programs, running simultaneously, to access the same set of statistics.
Self Declarative Data
Enables programs to dynamically present a list of available statistics to a user. The SPMI arranges all performance data in a hierarchy, with related statistics grouped together. The hierarchy contains context nodes (called contexts) and leaf nodes (called statistics). Each context may have subordinate contexts, statistics, or both. A program can traverse the data hierarchy through simple get and get-next calls to the SPMI API. Each context and statistic has a short name and a descriptive name.
Instantiation
Enables the SPMI to monitor multiple copies of a system resource. A context (and its subcontexts and statistics) may exist in multiple instances, such as for each disk, each CPU, or each active process.
Expandable Interface
Enables a DDS application program to expand the set of statistics without affecting the API.
Note: Versions earlier than 2.3 of the SPMI in Performance Toolbox for AIX do not allow simultaneous access of SPMI subroutines from multiple threads of a process.

Understanding the SPMI Data Hierarchy

SPMI data is organized in a multilevel hierarchy of contexts. A context may have subordinate contexts, known as subcontexts, as well as statistics. The higher-level context is called a parent context.

The Sample Data Hierarchy figure illustrates a data hierarchy for a multiprocessor system. Each ellipse depicts a context or subcontext, and each rectangle depicts a statistic. The CPU context consists of a subcontext for each of the processors. The Top context serves as an anchor point for all other contexts.




Figure 2. Sample Data Hierarchy

If an SPMI application program, looking for a statistic called %kernel, follows the CPU context shown in the figure, the program finds the following instances:

CPU/cpu_0/%kernel
CPU/cpu_1/%kernel
. . .
CPU/cpu_n/%kernel

Instantiation

When multiple copies of a resource are available, the SPMI uses a base context description as a template. The SPMI creates one instance of that context for each copy of the resource or system object. This process is known as instantiation. The Sample Data Hierarchy figure illustrates instantiation by showing multiple copies of the CPU context used to describe the processors. A context is considered instantiable if at least one of its immediate subcontexts can exist in more than one copy.

The SPMI can generate new instances of the subcontexts of instantiable contexts prior to the execution of API subroutines that traverse the data hierarchy. An application program can also request instantiation explicitly. In either case, instantiation is accomplished by requesting the instantiation for the parent context of the instances. For example, to instantiate all processor contexts in the Sample Data Hierarchy figure, the application would request instantiation at the CPU context.

Some instantiable contexts always generate a fixed number of subcontext instances in a given system, as long as the system configuration remains unchanged. Examples of this type of instantiability are contexts that contain subcontexts for network interface cards or processors.

Some contexts generate a fixed number of subcontexts on one system, but not on another. Using the Disk context as an example, if System A has a fixed number of disks while System B has removable disk drives, the number of subcontexts for the Disk context of System B changes as disk drives are added and removed while the number of subcontexts for System A is constant.

A final type of context is entirely dynamic in that it will add and delete instances as required during operation. For example, process subcontexts are repeatedly added and deleted during normal system operation.

Instantiability

Because an application program can request instantiation for any context, the contexts are defined as having one of three types of instantiability:

Not instantiable
The context contains either no subcontexts or a fixed number of subcontexts. Most contexts that are themselves subcontexts of an instantiable context belong to this group. In the "Sample Data Hierarchy" figure, the Top context and the cpu_0 through cpu_n subcontexts are not instantiable because none of their immediate subcontexts can occur in more than one copy. The Mem context is also not instantiable, assuming the system processors share one contiguous bank of memory.
Instantiable at system-configuration time
The number of instances never changes unless the system is reconfigured. In the "Sample Data Hierarchy" figure, the CPU context is an example of this kind of instantiability because the number of processors is constant.
Dynamically instantiable
The actual number of instances can vary during system operation. Subcontexts need not be of the same context type. For example, one dynamically instantiable context may have a group of subcontexts with an instance for each active socket and another group with an instance for each Transmission Control Protocol (TCP) connection. In such an arrangement, the number of instances of both groups is likely to change quite frequently in a network system.

Understanding SPMI Data Areas

The SPMI uses a shared memory segment created from user space. When an SPMI application program starts, the SPMI checks whether another program has already set up the SPMI data structures in shared memory. If the SPMI does not find the shared memory area, it creates one and generates and initializes all data structures. If the SPMI finds the shared memory area, it bypasses the initialization process. A counter, called users, shows the number of processes currently using the SPMI.

When an application program terminates, the SPMI releases all memory allocated for the application and decrements the users counter. If the counter drops below 1, the entire common shared memory area is freed. Subsequent execution of an SPMI application reallocates the common shared memory area.

The sys/Spmidef.h file contains declarations of all the SPMI data structures.

Traversing the Data Hierarchy

An application program has access to the data hierarchy through the API. The Application Program View of Data Hierarchy figure gives a simplified picture of the underlying data structures. A set of subroutines allows the application program to navigate through the structures, reviewing what data is available. This action is known as traversing the data hierarchy. The traversal process allows a user to find statistics of interest. To extract data from these statistics, an application program must define a set of statistics, called a statset. See "Data Access Structures and Handles" on page A-8 for more information.



Figure 3. Application Program View of Data Hierarchy

Data Traversal Structures and Handles

To traverse the data hierarchy, an application program uses four data structures, two handles, and a set of subroutines. See the List of SPMI Subroutines for view the subroutines. The structures include:

SpmiCx Structure

The SpmiCx structure describes a context node in the data hierarchy. As seen by an application program, an SpmiCx data structure is always an instance of a context. The data structure names and describes the context in the name and description fields, respectively. The structure also contains a symbolic reference, called a handle, for accessing the parent context (this handle is NULL if the parent context is Top) and a field describing the instantiability of the context. The asnno field contains an Abstract Syntax Notation One (ASN.1) number that makes the structure unique. See Making Dynamic Data-Supplier Statistics Unique for more information about ASN.1.

The SpmiCx structure is defined as follows:

#define SI_MAXNAME 32
#define SI_MAXLNAME 64

enum SiInstFreq
{
   SiNoInst,      /* Subcontexts never change */
   SiCfgInst,     /* Subcontext changes are system configuration changes */
   SiContInst,    /* System operation changes subcontexts continuously */
};
struct SpmiCx
{
   char            name[SI_MAXNAME];         /* short name of the context   */
   char            description[SI_MAXLNAME]; /* descriptive name            */
   SpmiCxHdl       parent;                   /* handle of parent context    */
   enum SiInstFreq inst_freq;                /* instantiability of context  */
   u_short         asnno;                    /* ASN.1 number                */
   u_char          deleted;                  /* nonzero if context deleted  */
   u_char          dummy;                    /* alignment                   */
};

SpmiCxHdl Handle

The SpmiCxHdl handle is a symbolic reference to a context. To access the SpmiCx structure identified by the handle, use the SpmiGetCx subroutine as follows:

struct SpmiCx         *spmicx;
SpmiCxHdl             cxhdl;

spmicx = SpmiGetCx(cxhdl);

SpmiStat Structure

The SpmiStat structure describes a statistics object. The object always describes a single-field counter or level statistic. Typically, a system component updates these fields and the update process is asynchronous to any requests to read the field. The field itself is not contained in the SpmiStat structure, but SPMI subroutines allow an application program to retrieve the field value.

The SpmiStat structure, like the SpmiCx structure, associates a name and a description with each object. It also defines default scale values by anticipating the low and high ranges of the field. For a counter field, the SpmiStat structure defines the low and high ranges of the change anticipated for a 1-second time period (the event rate per second).

The ValType enum defines the SiCounter and SiQuantity used to describe the data type as either a counter or a level, respectively. The SpmiStat structure also contains the format of the field. Though the enum DataType field defines many field formats, only SiLong and SiFloat are currently supported.

The asnno field contains an abstract syntax notation number that makes the structure unique from other structures. See Making Dynamic Data-Supplier Statistics Unique for more information.

The SpmiStat structure is defined as follows:

#define SI_MAXNAME 32
#define SI_MAXLNAME 64
enum ValType
{
   SiCounter,   /* field is always incremented */
   SiQuantity,  /* field maintains a level     */
};
enum DataType
{
   SiULong,
   SiLong,
   SiUInt,
   SiInt,
   SiUShort,
   SiShort,
   SiChar,
   SiAddr,
   SiTimeval,
   SiFloat,
   SiDouble,
   SiPtr,
   SiUnsign,
};
struct SpmiStat
{
   char           name[SI_MAXNAME];         /* short name of statistic     */
   char           description[SI_MAXLNAME]; /* descriptive name            */
   long           min;                      /* default low scale value     */
   long           max;                      /* default high scale value    */
   enum ValType   value_type;               /* data type presented to API  */
   enum DataType  data_type;                /* data format presented to API*/
   u_short        asnno;                    /* ASN.1 number                */
   u_short        dummy;                    /* alignment                   */
};

SpmiCxLink Structure

The SpmiFirstCx and SpmiNextCx S subroutines use the SpmiCxLink structure to traverse the subcontexts of a context. The SpmiCxLink structure serves as a handle when passed as a parameter to the SpmiNextCx subroutine. The structure contains both a reserved field and a field that is the handle of the subcontext.

The SpmiCxLink structure is defined as follows:

struct SpmiCxLink
{
   void       *reserved;      /* reserved field, don't change */
   SpmiCxHdl  context;        /* handle of subcontext         */
};

SpmiStatLink Structure

The SpmiFirstStat and SpmiNextStat subroutines use the SpmiStatLink structure to traverse the statistics of a context. This structure serves as a handle when passed as a parameter to the SpmiNextStat subroutine. The structure contains both a reserved field and a field that is the handle of the statistic.

The SpmiStatLink structure is defined as follows:

struct SpmiStatLink
{
   void        *reserved;     /* reserved field, don't change */
   SpmiStatHdl stat;          /* handle of statistic          */
};

SpmiStatHdl Handle

The SpmiStatHdl handle is a symbolic reference to a statistic. To access the SpmiStat structure identified by the handle, use the SpmiGetStat subroutine as follows:

struct SpmiStat   *spmistat;
SpmiStatHdl       stathdl;

spmistat = SpmiGetStat(stathdl);

Data Access Structures and Handles, StatSets

To access data values, the application program must define the data values it needs to the SPMI. For this purpose, the application program defines sets of statistics, or statsets, through the API. A set of statistics is anchored to a data structure defined as an SpmiStatSet structure. The address of a defined SpmiStatSet structure must be passed to the SPMI through the API each time the application program needs to access the actual data values referenced by the structure.

When the SPMI receives a read request for an SpmiStatSet structure, the SPMI returns the latest value for all the statistics in the set of statistics. This action reduces the system overhead caused by access of kernel structures and other system areas, and ensures that all data values for the statistics within a set are read at the same time. The set of statistics may consist of one or many statistics fields.

The SPMI builds internal data structures for the set in response to API calls from the application program. The Data Value Access Structures figure illustrates a simplified look at the way the application views these structures through the API.



Figure 4. Data Value Access Structures

One SpmiStatVals structure is created for each of the data values selected for the set. When the SPMI executes a request from the application program to read the data values for a set, all SpmiStatVals structures in the set are updated. The application program can then either traverse the list of SpmiStatVals structures, by using the SpmiFirstVals and SpmiNextVals subroutines, or retrieve single values by using the SpmiGetValue or SpmiGetNextValue subroutines.

An application program uses the following data structures to create, delete, and access sets of statistics.

SpmiStatSet Structure

This structure is an anchor point for the structures that define a set of statistics. The application program is responsible for creating the SpmiStatSet structure, adding and deleting statistics, and deleting the SpmiStatSet structure when no longer needed. The SPMI depends on the application program to supply the address of an SpmiStatSet structure. The structure holds only the time stamp for the most recent reading of its associated statistics and the elapsed time since the previous reading.

The SpmiStatSet structure is defined as follows:

struct SpmiStatSet
{
   struct timeval    time;              /* time of current get         */
   struct timeval    time_change;       /* elapsed time since last get */
};

SpmiStatVals Structure

The SpmiStatVals structure carries the data values from the SPMI to the application program. It contains handles that allow an application to access the parent context and the SpmiStat structure of the value. The ref_count field indicates the number of times a particular statistic is included in the same set. The ref_count field usually has a value of 1.

The SpmiStatVals structure is defined as follows:

union Value
{
   long    l;
   float   f;
};
struct SpmiStatVals
{
   void              *reserved;         /* reserved field              */
   SpmiStatHdl       stat;              /* handle of statistic         */
   SpmiCxHdl         context;           /* handle of context           */
   int               ref_count;         /* count of simultaneous users */
   union Value       val;               /* counter/level data value    */
   union Value       val_change;        /* delta change if counter data*/
   enum Error        error;             /* error code                  */
};

The last three fields actually transfer the data values, as follows:

val
Returns the value of the counter or level field. This field returns the statistic's value as maintained by the original supplier of the value. However, the val field is converted to an SPMI data format.
val_change
Returns the difference between the previous reading of the counter and the current reading when the statistic contains counter data. When this value is divided by the elapsed time returned in the SpmiStatSet structure, an event rate-per-time unit can be calculated.
error
Returns a zero value if the SPMI's last attempt to read a data value was successful. Otherwise, this field contains an error code as defined in the sys/Spmidef.h file. See the List of SPMI Error Codes for more information.

Data Access Structures and Handles, HotSets

To access data values, the application program can define a different type of StatSet to the SPMI. It is used to extract data values for the most or least active statistics for a group of peer contexts. For example, it can be used to define that the program wants to receive information about the two highest loaded disks, optionally subject to those values exceeding a specified threshold. For this purpose, the application program defines sets of peer statistics, called hotsets, through the API.

A hotset is anchored to a data structure defined as an SpmiHotSet structure. The address of a defined SpmiHotSet structure must be passed to the SPMI through the API each time the application program needs to access the actual data values referenced by the structure.

When the SPMI receives a read request for an SpmiHotSet structure, the SPMI reads the latest value for all the peer sets of statistics in the hotset in one operation. This action reduces the system overhead caused by access of kernel structures and other system areas, and ensures that all data values for the peer sets of statistics within a hotset are read at the same time. The hotset may consist of one or many sets of peer statistics.

The SPMI builds internal data structures for the set in response to API calls from the application program. The Data Value Access Structures figure illustrates the statset access structures; the structures for the hotset looks exactly the same but the referenced context is now the parent context of all peers to examine. This parent context is what groups the peers together; all of the subcontexts of that parent context are of the same type and are considered peer contexts. By naming a specific statistic for one peer context, you reference the same statistic for each of the peer contexts, hence the term "a set of peer statistics".

One SpmiHotVals structure is created for each set of peer statistics selected for the hotset. When the SPMI executes a request from the application program to read the data values for a hotset, all SpmiHotVals structures in the set are updated. The application program can then either traverse the list of SpmiStatVals structures, by using the SpmiFirstHot and SpmiNextHot subroutines, or retrieve single values by using the SpmiNextHotItem subroutine.

An application program uses the following data structures to create, delete, and access hotsets.

SpmiHotSet Structure

This structure is an anchor point for the structures that define a group of peer statistic sets. The application program is responsible for creating the SpmiHotSet structure, adding and deleting peer sets of statistics, and deleting the SpmiHotSet structure when no longer needed. The SPMI depends on the application program to supply the address of an SpmiHotSet structure. The structure holds only the time stamp for the most recent reading of its associated statistics and the elapsed time since the previous reading.

The SpmiHotSet structure is defined as follows:

struct SpmiHotSet
{
   struct timeval    time;              /* time of current get           */
   struct timeval    time_change;       /* elapsed time since last get   */
};

SpmiHotVals Structure

The SpmiHotVals structure carries the data values from the SPMI to the application program. It contains handles that allow an application to access the parent context of the peer contexts and the SpmiStat structure of the peer statistic. The ref_count field indicates the number of times a particular set of peer statistics is included in the same set. The ref_count field usually has a value of 1.

The SpmiHotVals structure is defined as follows:

union Value
{
   long    l;
   float   f;
};
enum HotExcept {
   SiHotNoException = 0,
   SiHotException,
   SiHotTrap,
   SiHotBoth
};
enum HotFeed {
   SiHotNoFeed = 0,
   SiHotThreshold,
   SiHotAlways
};
struct SpmiHotItems
{
   char              name[SI_MAXLNAME]; /* name of the peer context    */
   union Value       val;               /* counter/level data value    */
   union Value       val_change;        /* delta change if counter data*/
};
struct SpmiHotVals
{
   void              *reserved;         /* reserved field              */
   SpmiStatHdl       stat;              /* handle of statistic         */
   SpmiCxHdl         grandpa;           /* parent of the peer contexts */
   int               ref_count;         /* count of simultaneous users */
   enum Error        error;             /* error code                  */
   enum HotExcept    except_type;       /* when to send exceptions     */
   short             trap_no;           /* trap number for SNMP traps  */
   short             severity;          /* severity for exception pckt */
   enum HotFeed      feed_type;         /* when to send data feeds     */
   int               threshold;         /* threshold for what to send  */
   short             frequency;         /* max frequency of exceptions */
   short             max_responses;     /* max  # of responses to send */
   short             avail_resp;        /* # of available hot readings */
   short             count;             /* # of returned hot readings  */
   char              *path;             /* path to grandpa context     */
   struct SpmiHotItems *items;          /* array of returned readings  */
};

The data carrying fields are:

error
Returns a zero value if the SPMI's last attempt to read the data values for a set of peer statistics was successful. Otherwise, this field contains an error code as defined in the sys/Spmidef.h file. See the List of SPMI Error Codes for more information.
avail_resp
Used to return the number of peer statistic data values that meet the selection criteria (threshold). The field max_responses determines the maximum number of entries actually returned.
count
Contains the number of elements returned in the array items. This number will be the number of data values that met the selection criteria (threshold), capped at max_responses.
items
The array used to return count elements. This array is defined in the SpmiHotItems data structure.

SpmiHotItems

An array of this structure is pointed to by the field items in the SpmiHotVals structure. Elements are ordered after the returned data values; ascending if threshold is negative, otherwise descending. Each element in the array has the following fields, used to return the result. Note that each instance of this structure corresponds to one single peek statistic within a set of peer statistics as defined in an instance of an SpmiHotVals structure.

name
The name of the peer context for which the values are returned.
val
Returns the value of the counter or level field for the peer statistic. This field returns the statistic's value as maintained by the original supplier of the value. However, the val field is converted to an SPMI data format.
val_change
Returns the difference between the previous reading of the counter and the current reading when the statistic contains counter data. When this value is divided by the elapsed time returned in the SpmiStatSet structure, an event rate-per-time-unit can be calculated.

Dynamic Data Supplier (DDS) Program Structures

A DDS program can register and supply private statistics to the SPMI by calling SPMI subroutines. The following information describes the program structures used to communicate between a DDS program and the SPMI.

A DDS program initializes the API by using the SpmiDdsInit subroutine. This subroutine allocates the DDS shared memory area, shown in Data-Supplier Shared Memory Layout , based on the two data structures described in:

DDS programs should not directly manipulate the shared memory area, its control information, or its data structures except by using the following fields:

SiShGoAway
Indicates that the DDS program is no longer needed or that its data is corrupted. This field may be set by any data-consumer program. Normally when a DDS program sees that this field has true value, the program calls the SpmiExit subroutine to free the allocated shared memory and unlink from the SPMI interface. Failure to call the SpmiExit subroutine before exiting retains the allocated shared memory. As a result, the DDS program cannot be restarted until the shared memory is freed using the ipcrm command.
 
SiShT
Specifies a time stamp that must be updated by the DDS program each time the shared data area is updated. Data-consumer programs may check this field to see when the DDS program was last active. If too much time elapses without a time-stamp update, the data-consumer program may assume the DDS is inoperative, and will set the SiShGoAway field and release its access to the shared memory area.
Note: The time stamp is a structure with two integer elements. It is expected to be stored in Big Endian notation. Hosts that use Little Endian notation must convert the integer fields to Big Endian notation before storing them.
 
SiShArea
DDS programs must use the SiShArea field. This field contains the address of the data area in the shared memory segment. A DDS program must load a pointer with this field and use that pointer to access the shared memory data area.The program can do calculations directly in the area allocated in shared memory or do the calculations in local data fields and then move the results to shared memory.

Data-Supplier Shared Memory Layout

The following structure shows the DDS shared memory layout:

typedef struct
{
   short              SiShMajor;     /* Major version of shm protocol    */
   short              SiShMinor;     /* Minor version of shm protocol    */
   char               SiShName[64];  /* Path name for shm allocation     */
   char               SiShId;        /* ID for ftok() function           */
   key_t              SiShKey;       /* shared memory key (RSi interface)*/
                                     /* creating process ID (Spmi I/F)   */
   int                SiShMemId;     /* shared memory identifier         */
   u_long             SiShInetAddr;  /* Internet address of owning host  */
   u_short            SiShPortNo;    /* port number to talk to daemon    */
   int                SiShAllocLen;  /* length of allocated area         */
   int                SiShInstBegun; /* instantiations begun             */
   int                SiShInstDone;  /* instantiations completed         */
   int                SiShRefrBegun; /* refreshes begun                  */
   int                SiShRefrDone;  /* refreshes completed              */
   boolean            SiShGoAway;    /* signal supplier to terminate     */
   boolean            SiShAlarmSw;   /* switch to indicate alarm is set  */
   cx_create          *SiShCxTab;    /* pointer to fixed context table   */
   int                SiShCxCnt;     /* count of contexts in above table */
   cx_create          *SiShInstTab;  /* pointer instantiable contexts    */
   int                SiShInstCnt;   /* count of contexts in above table */
   struct SpmiRawStat *SiShStatTab;  /* pointer to consolidated Stats    */
   int                SiShStatCnt;   /* count of Stats in above table    */
   char               *SiShArea;     /* pointer to statistics area       */
   int                SiShAreaLen;   /* length of statistics area        */
   struct timeval     SiShT;         /* time of last area update BY US   */
   struct timeval     SiShPost;      /* time of update of fields below   */
   int                SiShInterval;  /* sample frequency in milliseconds */
   int                SiShSubscrib;  /* current number of values used    */
   struct SpmiCxLink  *SiShAddCx;    /* instantiated contexts to add     */
   struct SpmiCxLink  *SiShActCx;    /* active instantiated contexts     */
   struct SpmiCxLink  *SiShDelCx;    /* contexts to delete               */
   struct SpmiCxLink  *SiShFreeCx;   /* freed contexts                   */
   void               *SiShAlarm;    /* addr of Shm alarm data area      */
   u_long             SiShLock1;     /* lock words to serialize access   */
   u_long             SiShLock2;     /*  .. from multiple threads/CPUs   */
   u_long             SiShRes[4];    /* reserved for future use          */
   char               SiShData;      /* start of data area               */
} SpmiShare;

Declaring a Statistic - the SpmiRawStat Structure

To add permanent statistics, a DDS program must describe the statistics in the SpmiRawStat structure. For each context with statistics that the program wants to add, the program must create a table of statistics.

The SpmiRawStat structure is defined as follows:

#define SI_MAXNAME 32
#define SI_MAXLNAME 64
enum ValType
{
   SiCounter,   /* field is always incremented */
   SiQuantity,  /* field maintains a level     */
};
enum DataType
{
   SiULong,
   SiLong,
   SiUInt,
   SiInt,
   SiUShort,
   SiShort,
   SiChar,
   SiAddr,
   SiTimeval,
   SiFloat,
   SiDouble,
   SiPtr,
   SiUnsign,
};
struct SpmiRawStat
{
   char              name[SI_MAXNAME];  /* short name of statistic     */
   char              description[SI_MAXLNAME]; /* descriptive name     */
   long              min;               /* default low scale value     */
   long              max;               /* default high scale value    */
   enum ValType      value_type;        /* data type presented to API  */
   enum DataType     data_type;         /* data format presented to API*/
   u_short           asnno;             /* ASN.1 number                */
   u_short           size;              /* source data field size      */
   int               offset;            /* source data field offset    */
   enum DataType     type;              /* source data field format    */
   int               (*get_fun)();      /* data access function pointer*/
#ifdef _SOLARIS
   int               ksnoffs;           /* Solaris ksn_struct offset   */
   char              module[SI_MODL];   /* Solaris kstat source module */
   char              statname[SI_STAL]; /* Solaris kstat stat name     */
   char              fieldname[SI_FLDL];/* Solaris kstat field name    */
   int               datoffs;           /* Solaris ksn data offset     */
#endif /* _SOLARIS */
};

Application programs should leave the section inside #ifdef _SOLARIS uninitialized, even on Solaris systems. The following example defines the "gadgets" and "widgets" statistics. See Example of an SPMI Dynamic Data-Supplier Program for a sample program that uses this definition.

static CONST struct SpmiRawStat PUStats[] = {
{  "gadgets", "Fake counter value", 0, 100, SiCounter,
   SiLong, 1, SZ_OFF(dat, a, SiULong), NULL},
{  "widgets", "Another fake counter value", 0, 100, 
SiCounter,
   SiLong, 2, SZ_OFF(dat, b, SiULong), NULL},
};

Declaring a Context - the cx_create Structure

After declaring the statistics, the DDS program must link them to their parent contexts. To do so, the program uses a single table of structures that defines all the contexts as permanent contexts. Each context requires one element of the cx_create type.

The cx_create structure is defined as follows:

#define SI_MAXNAME 32
#define SI_MAXLNAME 64
typedef struct
{
   char           path[SI_MAXLNAME];   /* context path name              */
   char           descr[SI_MAXLNAME];  /* context description            */
   u_short        asnno;               /* ASN.1 number                   */
   u_short        datasize;            /* size of context record         */
   struct SpmiRawStat   *stats;        /* Stat array pointer for context */
   int            num_stats;           /* element count of Stat array    */
   struct SpmiRawStat   *inst_stats;   /* Stat array for multiple        */
                                       /*   instances of this context    */
   int            num_inst_stats;      /* element count for above array  */
   int            (*inst_subs)();      /* function to instantiate context*/
   int            inst_freq;           /* instantiate frequency          */
   u_long         level;               /* relative level (work field)    */
   char           *area;               /* data area pointer              */
   u_long         arealen;             /* length of above data area      */
} cx_create;

The following example defines the DDS/IBM and DDS/IBM/sample1 contexts. See Example of an SPMI Dynamic Data-Supplier Program for a sample program that uses this definition.

static CONST cx_create cx_table[] = {
   {"DDS/IBM", "IBM-defined Dynamic Data Suppliers", 2, 0,
      NULL, 0, NULL, 0, NULL, SiNoInst},
   {"DDS/IBM/sample1", "Bogus Context Number 1", 191, 0,
      PUStats, STAT_L(PUStats), NULL, 0, NULL, SiNoInst},
};

Making Dynamic Data-Supplier Statistics Unique

Some structures contain an asnno field. The SPMI assigns each context and statistic a unique number in Abstract Syntax Notation One (ASN.1) format and stores the number in this field. As a result, the SPMI can export SPMI and DDS statistics to other interfaces, such as the Simple Network Management Protocol (SNMP). ASN.1 identifiers are composed of a series of integers separated by dots. That is, the context called CPU has the ASN.1 identifier of 1. The subcontexts of CPU have ASN.1 identifiers that are numbered starting with 1. The ASN.1 identifiers for statistics belonging to each subcontext of CPU are also numbered starting with 1. For instance, for the CPU/cpu0/idle path name the CPU context has an ASN.1 identifier of 1, the CPU/cpu0 subcontext has an ASN.1 identifier of 1.1, and the CPU/cpu0/idle statistic has an ASN.1 identifier of 1.1.4. This identifier is referred to as the relative dotted-decimal identifier.

The dotted-decimal identifiers of all statistics can be thought of as a substructure or subtree, which can be attached to any point in another network, such as the SNMP Management Information Base (MIB) tree. For example, an SNMP tree has a point defined as:

internet.private.enterprises.ibm.ibmAgents.aix.risc6000.risc6000private

This subtree is graphically illustrated in the following figure titled Hierarchical Organization of Private MIB Subtrees.:



Figure 5. Hierarchical Organization of Private MIB Subtrees

This description corresponds to a dotted-decimal identifier of 1.3.6.1.4.1.2.3.1.2.2 (the numbers 1.3.6.1 correspond to the internet portion of the tree). If the SPMI contexts were attached at this point, the fully qualified dotted-decimal identifier for the CPU/cpu0/idle path name (1.1.4) would be 1.3.6.1.4.1.2.3.1.2.2.1.1.4.

No two contexts or statistics can have the same relative dotted-decimal identifier. The API checks that you do not assign the same ASN.1 number more than once at each level in the subtree defined by your DDS program. This ensures unique relative dotted-decimal identifiers.

In addition, statistics and contexts must have unique names within the parent context. The API checks that DDS programs adhere to this rule so that the full path name of statistics and contexts remains unique.

However, the API can only detect name or ASN.1 number clashes, not resolve them. Therefore, it is recommended that DDS programs use the following naming and numbering scheme. This scheme uses an SPMI-defined context, called DDS, with a relative dotted-decimal identifier of 99. When adding subtrees, DDS programs should use the DDS context as the parent context.

This naming and numbering scheme is graphically illustrated in the following figure titled Extended Set of Statistics.:



Figure 6. Extended Set of Statistics

Vendors of DDS programs should define a private subcontext of the DDS context as the parent context for all DDS subtrees that the program creates. Assign this private subcontext a meaningful name and an ASN.1 number that corresponds to the ASN.1 number assigned to the vendor in the SNMP subtree enterprises. Such a number is called an Assigned Enterprise Number. For example, IBM has an Assigned Enterprise Number of 2. Therefore, the subcontext for the path name DDS/IBM would have a relative dotted-decimal identifier of 99.2.

DDS programs can be loaded in any sequence. However, since all DDS programs depend on the presence of the vendor-specific context (such as DDS/IBM), each program must attempt to add this context to make sure it exists. Once a program has created the vendor-specific context, it remains defined as long as the common shared memory area exists. When other DDS programs attempt to add the same vendor-specific context, they simply use the already created context. Vendor-specific contexts must never have statistics defined. Statistics should be added to subcontexts of the vendor-specific context.

Note: Vendors without SNMP numbers should register for one by contacting the Internet Assigned Numbers Authority at the following address:

Internet Assigned Numbers Authority
USC/Information Sciences Institute
4676 Admiralty Way
Marina del Rey, California 90202-6695

The Internet address for the Internet Assigned Numbers Authority is iana@isi.edu.


Using the System Performance Measurement Interface API

The API supplied with the Agent component is called the System Performance Measurement Interface (SPMI). It allows you to write programs that extend the number of statistics available from a host's xmservd daemon (dynamic data-supplier programs) and to write programs that access statistics on the local host without using the network interface (local data-consumer programs).

This chapter describes how you use this API to create your own dynamic data-supplier program. The sample programs used to explain the API and several additional ones are provided in machine-readable form as part of the Agent component. The sample programs and a Makefile can be found in directory:

/usr/samples/perfagent/server

Using SPMI to Create a Dynamic Data Supplier

When you want to extend the set of statistics available from the xmservd daemon on a host, you create a dynamic data-supplier (DDS) program using the SPMI API. When the DDS program executes, it registers its statistics with the SPMI. This makes the new statistics immediately available to the local data-consumer programs and to the xmservd daemon so any program that gets its statistics from the extended xmservd daemon can access the additional statistics provided by the DDS. DDS programs must execute on the same host as the one running the xmservd whose set of statistics is to be extended.

Makefiles

The include files are based upon a number of pre-processor define directives being properly set. They must be defined with the -D preprocessor flag. The following define directives should be in effect for compiling on AIX Version 3 or 4.

A Makefile to build all the sample programs provided could look like the one shown below.

LIBS = -lbsd -lSpmi
CC = cc
CFLAGS = -D_BSD -D_AIX -D_AIX_41
all:: SpmiDds SpmiSupl SpmiSupl1 SpmiLogger SpmiPeek lchmon 
lfiltd
SpmiDds: SpmiDds.c
  $(CC) -o SpmiDds SpmiDds.c $(CFLAGS) $(LIBS)
SpmiSupl: SpmiSupl.c
  $(CC) -o SpmiSupl SpmiSupl.c $(CFLAGS) $(LIBS)
SpmiSupl1: SpmiSupl1.c
  $(CC) -o SpmiSupl1 SpmiSupl1.c $(CFLAGS) $(LIBS)
SpmiLogger: SpmiLogger.c
  $(CC) -o SpmiLogger SpmiLogger.c $(CFLAGS) $(LIBS)
SpmiPeek: SpmiPeek.c
  $(CC) -o SpmiPeek SpmiPeek.c $(CFLAGS) $(LIBS)
lchmon: lchmon.c  $(CC) -o lchmon lchmon.c $(CFLAGS) $(LIBS)
 -lcurses
lfiltd: lfiltd.c lex.lfiltd.o lfiltd.h
  $(CC) -o lfiltd lfiltd.c lex.lfiltd.o $(CFLAGS) $(LIBS)
lex.lfiltd.o: lfiltd.lex lfiltd.h
  lex lfiltd.lex
  cp lex.yy.c lex.lfiltd.c
  rm lex.yy.c
  $(CC) -c lex.lfiltd.c $(CFLAGS)

To compile on non-AIX systems, other flags must be used. A Makefile is included with each non-AIX agent. Please use flags as defined in that Makefile. If the compiler you are using doesn't support ANSI function prototyping, add the flag:

-D_NO_PROTO

Writing Dynamic Data-Supplier Programs

A dynamic data-supplier program is intended to extend the set of statistics that data-consumer programs can be supplied with, either from the xmservd daemon of a host or directly from the SPMI repository through local data-consumer programs. A dynamic data-supplier can add statistics as permanent (non-volatile) or dynamic (volatile) contexts with subcontexts and statistics. To illustrate this concept, assume the SPMI has a set of contexts and statistics as pictured in Figure 7.



Figure 7. Start Set of Statistics

Of course, the set of statistics on an IBM RISC System/6000 is much larger than shown, but this will do as an illustration. Now assume that you have access to other statistics and want them added to the set. This is when you want to create a dynamic data-supplier program. For example, you could extend the tree structure of contexts and statistics to look as shown in Figure 8.



Figure 8. Extended Set of Statistics

In Figure 8, two contexts have been added as subcontexts of a context called DDS/IBM and are named Test and Moretest. The first of these contexts has two statistics called gadgets and widgets. The second has no directly descendent statistics but has a subcontext called SubTest, which in turn has two statistics: level and queue.

By convention, DDS programs always add statistics below the context DDS/vendor where vendor is the name of the vendor or customer that develops the DDS program; not the name of the machine type that the programs run on. This convention is established to prevent name clashes between the DDS programs developed by different vendors. Statistics should only be added to subcontexts of the DDS/vendor contexts, never to the DDS/vendor context itself.

The hierarchy shown in figure 8 could be displayed with the program xmpeek. This generates output as shown below:

/birte/Mem/            Memory statistics
/birte/Mem/Real/          Physical memory statistics
/birte/Mem/Real/size          Size of physical memory (4K pages)
/birte/Mem/Real/%free          % memory which is free
/birte/Mem/Real/%comp          % memory allocated to computational segments
/birte/Mem/Virt/          Virtual memory management statistics
/birte/Mem/Virt/pagein          4K pages read by VMM
/birte/Mem/Virt/pageout         4K pages written by VMM
/birte/Mem/Virt/steal           Physical memory 4K frames stolen by VMM
/birte/PagSp/          Paging space statistics
/birte/PagSp/size           Total active paging space size (4K pages)
/birte/PagSp/free           Total free disk paging space (4K pages)
/birte/PagSp/hd6/           Statistics for paging space hd6
/birte/PagSp/hd6/size           Size of paging space (4K pages)
/birte/PagSp/hd6/%free          Free portion of this paging space (percent)
/birte/DDS/            Dynamic Data-Supplier Statistics
/birte/DDS/IBM/           IBM-defined Dynamic Data-Suppliers
/birte/DDS/IBM/Test/           Bogus Context Number 1
/birte/DDS/IBM/Test/gadgets          Fake counter value
/birte/DDS/IBM/Test/widgets          Another fake counter value
/birte/DDS/IBM/Moretest/       Bogus Context Number 2
/birte/DDS/IBM/Moretest/SubTest/          Bogus Context Number 3
/birte/DDS/IBM/Moretest/SubTest/level          Fake quantity value
/birte/DDS/IBM/Moretest/SubTest/queue          Another fake quantity value

A Dynamic Data Supplier for Permanent Extensions

For this first exercise, it is assumed that the added contexts and statistics are non-volatile and as such can be added as permanent statistics. This requires the use of only one subroutine and the following programming steps:

  1. Declare data structures to describe statistics.
  2. Declare data structures to describe contexts.
  3. Declare other data areas as required.
  4. Initialize the SPMI interface.
  5. Initialize exception handling.
  6. Initialize statistics fields.
  7. Create main loop.

Declare Data Structures to Describe Statistics

Statistics are described in a simple structure of type struct SpmiRawStat. For each of the contexts you define that has statistics, you must create a table of statistics. The definition of the statistics gadgets and widgets would look as shown below:

static const struct SpmiRawStat PUStats[] = {
{ "gadgets", "Fake counter value", 0, 100, SiCounter,
   SiLong, 1, SZ_OFF(dat, a, SiULong)},
{ "widgets", "Another fake counter value", 0, 100, 
SiCounter,
   SiLong, 2, SZ_OFF(dat, b, SiULong)},
};

The fields in the structure are the following:

SiCounter Value is incremented continuously. Normally, data-consumer programs show the delta (change) in the value between observations, divided by the elapsed time, representing a rate.

SiQuantity Value represents a level, such as memory used or available disk space.

Since we actually wanted to add two sets of statistics at two different places in the context hierarchy, we also need to declare the second set. The code piece below shows how that can be done:

static const struct SpmiRawStat FakeMemStats[] = {
{ "level", "Fake quantity value", 0, 100, SiQuantity,
   SiLong, 1, SZ_OFF(dat, c, SiULong)},
{ "queue", "Another fake quantity value", 0, 100, 
SiQuantity,
   SiLong, 2, SZ_OFF(dat, d, SiULong)},
};

Declare Data Structures to Describe Contexts

After you have the statistics declared, you need to link them to their parent contexts. This is also done by defining a table of data structures. You need a single table of structures holding all the contexts you want to define as permanent contexts. Each context requires one element of the type cx_create. To create the three contexts we wanted to add, declare the four contexts as shown in the code segment below:

static const cx_create cx_table[] = {
{"DDS/IBM", "IBM-defined Dynamic Data-Suppliers", 2, 0,
   NULL, 0, NULL, 0, NULL, SiNoInst},
{"DDS/IBM/Test", "Bogus Context Number 1", 220, 0,
   PUStats, STAT_L(PUStats), NULL, 0, NULL, SiNoInst},
{"DDS/IBM/Moretest", "Bogus Context Number 2", 221, 0,
   NULL, 0, NULL, 0, NULL, SiNoInst},
{"DDS/IBM/Moretest/SubTest", "Bogus Context Number 3", 222, 
0,
   FakeMemStats, STAT_L(FakeMemStats), NULL, 0, NULL, SiNoInst}
};

The first context declared is the vendor context. Since DDS programs from a vendor may be started in any sequence, there is no guarantee that this context exists. All DDS programs, therefore, must attempt to add the vendor context. If the vendor context exists, the attempt is ignored; otherwise the context is added. Note that this is the only type of context that is handled this way. Attempts to add other contexts twice cause the API to return an error to your program.

Each context element must have the following fields:

Declare Other Data Areas as Required

Your dynamic data-supplier program must define its own data areas as required. We define the structure and fields shown below:

extern char SpmiErrmsg[];
struct dat
{
   u_long  a;
   u_long  b;
   u_long  c;
   u_long  d;
};
static int  CxCount = CX_L(cx_table); /* Count of contexts defined */
static SpmiShare *dataarea = NULL;    /* Shared memory pointer */
static struct dat *d = NULL;         /* Pointer to stats data area */

The first line declares an external variable used by the SPMI API to return an error text to the invoking program if an error occurs.

The next lines define the data structure where we calculate the raw statistics to present to System Performance Measurement Interface (SPMI) interface. The data area must hold all the data fields referenced by non-volatile statistics.

Then we define a counter, which we use the CX_L macro to initialize with the number of static contexts we want to add. Finally we define a pointer that will, eventually, be initialized to point to the data area we share with the SPMI interface.

The SPMI interface and the DDS use shared memory to communicate between themselves. As always, when programs share memory, conventions must be established and adhered to for the use of the shared memory areas. The shared memory used by the SPMI is divided into two main areas: the shared memory structured fields and the shared memory data area.

Shared Memory Structured Fields

The shared memory area is created by subroutines and its control information and generated data structures should (with few exceptions) never be used or manipulated by the DDS program directly. You can see the control information as it is defined in the include file /usr/include/sys/Spmidef.h as the structure SpmiShare. The fields that must be used by the DDS program are:

SiShGoAway
This flag may be set by any data-consumer program to indicate that some condition indicates that the DDS program is no longer needed or that its data is corrupted. Normally, when a DDS sees this flag, it should call the SpmiExit subroutine to free the shared memory it allocated and to unlink from the SPMI interface. Failure to call SpmiExit before exiting retains the allocated DDS shared memory which, in turn, renders it impossible to restart the DDS program until the shared memory is freed through the command ipcrm.
 
SiShT
A time stamp which must be updated by the DDS program each time the shared data area is updated. Data-consumer programs, and the xmservd daemon in particular, checks this field to see when your DDS was last active. If more than 30 seconds elapse without the time stamp being updated, xmservd assumes your dynamic data-supplier has died, sets the SiShGoAway flag and releases its access of the shared memory area. (30 seconds is the default. A value from 15 to 600 seconds can be specified using the command line option -m for xmservd.
Note: The time stamp is a structure with two integer elements. It is expected to be stored in Big-Endian notation. Hosts that use Little-Endian notation must convert the integer fields to Big-Endian notation before storing them.
 
SiShArea
The address of the data area in the shared memory segment. Your DDS program must load a pointer with the contents of this field and use that pointer to access the shared memory data area.

Shared Memory Data Area

The shared memory data area is where your DDS is supposed to place its statistics values as they are calculated. You can do your calculations directly in the area allocated in shared memory, or you can do the calculations in local data fields and then move the result to shared memory. The important thing is to be aware that the shared memory area is guaranteed to be large enough to contain the last of those fields in your data structure that are referenced in any one of the tables defining statistics, but no larger.

Thus, if the structure dat as defined in the code segment in section Declare Other Data Areas as required had additional data fields, those would not be available in shared memory because no declared statistics reference them. Attempts to access such fields would cause segmentation faults.

Initialize the SPMI Interface

With all required declarations in place we can register with the SPMI interface. This is done through a single subroutine called SpmiDdsInit. For specifics, see the SpmiDdsInit subroutine on page . For the purpose of this example, the subroutine is invoked with the statements shown below:

dataarea = SpmiDdsInit(cx_table, CxCount, NULL,0, 
"/etc/SpmiSupl1SHM");
if (!dataarea)
{
   printf("%s", SpmiErrmsg);
   exit(-1);
}
d = (struct dat *) &dataarea->
SiShArea[0];

Initialize Exception Handling

Because a DDS uses shared memory to talk to SPMI, it is very important to make sure the shared memory area is released when your DDS program dies. The best way to make sure this happens is to catch the signals that indicate that your program dies. The same function used to process the signals can conveniently be used for normal program exit. This could be done as shown in this code piece:

void SpmiStopMe()
{
   dataarea = NULL;
   SpmiExit();
   exit(0);
}
signal(SIGTERM, SpmiStopMe);
signal(SIGHUP, SpmiStopMe);
signal(SIGINT, SpmiStopMe);
signal(SIGSEGV, SpmiStopMe);

The function SpmiStopMe makes sure the shared memory area is freed and then exits. The "signal" lines defining the signal handler should be placed around the place in the DDS program where the program registers with SPMI.

Initialize Statistics Fields

In most cases, statistics values are a combination of the types SiCounter and SiQuantity. Data consumers normally are interested in delta values for the former, so the first thing to do is take the first reading and initialize the statistics fields in shared memory. That way, even the first delta values read by a data consumer are likely to be valid.

Updating data fields always requires updating the time stamp. The lines used to do this and to give the initial field values could follow the scheme shown below. In this example, the fields are updated directly in the shared memory data area.

gettimeofday(&dataarea->
SiShT, NULL);
d->
a = ... ;
d->
b = ... ;
d->
c = ... ;
d->
d = ... ;

Create Main Loop

The main loop is normally very simple and is conveniently made as a while loop. One of the conditions you should always include in your while loop is a test for the SiShGoAway flag. Your program may have additional conditions added to terminate the program as required by the application. The example main loop below only tests for the flag:

while(!dataarea->
SiShGoAway)
{
   usleep(499000);
   gettimeofday($dataarea->
SiShT, NULL);
   d->
a = ... ;
   d->
b = ... ;
   d->
c = ... ;
   d->
d = ... ;
}
SpmiStopMe();

Although the main loop can be as simple as shown above, such simplicity may cause the DDS program to update the values in the shared memory area more often than required. In situations where the DDS has defined values but no data-consumer program is using any of those, updating the data fields is entirely unnecessary.

Two fields let you add a little more finesse to your dynamic data-supplier program. Both fields are Shared Memory Structured Fields and can be accessed through the pointer returned by SpmiDdsInit. The fields are not updated by every data-consumer program; only by the xmservd daemon. Therefore, your DDS program must be able to cope with the situation that the two fields are not updated. The fields are:

SiShInterval
An integer that gives you the number of milliseconds between requests for data values from xmservd. Since different requestors of values may request with different intervals, this value reflects the smallest interval of those defined (i.e., the interval defined for the instrument that runs fastest).
 
SiShSubscrib
The number of data values currently being requested from this DDS program by xmservd.

Obviously, if SiShSubscrib is zero, nobody is requesting continuous supply of data values and you can reduce the update frequency in your DDS accordingly. It is recommended that you do not stop the updating of the data fields but that you do so with intervals of, say, five seconds.

If SiShSubscrib is nonzero, somebody is requesting continuous supply of data values and you should adjust the update frequency to match the request frequency as given in SiShInterval.

A main loop that uses these principles could look as shown here:

while(!dataarea->
SiShGoAway)
{
   if (datarea->
SiShSubscrib)
      usleep(dataarea->
SiShInterval * 1000);
   else
      sleep(5);
   gettimeofday(&dataarea->
SiShT, NULL);
   d->
a = ... ;
   d->
b = ... ;
   d->
c = ... ;
   d->
d = ... ;
}
SpmiStopMe();

The SiShSubscrib field normally holds a count of all data-consumer programs written to the RSi API (see RSi Programming Guide ) that are currently subscribing to data values in the shared memory area. However, in order to allow a program that acts both as a data consumer and a dynamic data supplier, you can move the port number of the port assigned to the data consumer side of the program to the field SiShPortNo, which is another shared memory structured field. A data-consumer/dynamic data-supplier program could use a statement like the following to insert the port number:

dataarea->
SiShPortNo = rsh->
portno;

where rsh is the RSiHandle for the host. The field portno in the RSiHandle structure is updated by the subroutine RSiOpen.

When the port number is inserted in the shared memory area, the xmservd does not count subscriptions for data values in the shared memory area that originate at that port number on the local host.

The Entire Program

The above program segments are combined into a working DDS program below. Source code for the program can be found in /usr/samples/perfagent/server/SpmiSupl1.c :

#include <stdio.h>

#include <sys/signal.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/Spmidef.h>
extern char  SpmiErrmsg[];
struct dat
{
   u_long      a;
   u_long      b;
   u_long      c;
   u_long      d;
};
static const struct SpmiRawStat PUStats[] = {
{ "gadgets", "Fake counter value", 0, 100, SiCounter,
   SiLong, 1, SZ_OFF(dat, a, SiULong)},
{ "widgets", "Another fake counter value", 0, 100, 
SiCounter,
   SiLong, 2, SZ_OFF(dat, b, SiULong)},
};
static const struct SpmiRawStat FakeMemStats[] = {
{ "level", "Fake quantity value", 0, 100, SiQuantity,
   SiLong, 1, SZ_OFF(dat, c, SiULong)},
{ "queue", "Another fake quantity value", 0, 100, 
SiQuantity,
   SiLong, 2, SZ_OFF(dat, d, SiULong)},
};
static const cx_create cx_table[] = {
{"DDS/IBM", "IBM-defined Dynamic Data-Suppliers", 2, 0,
   NULL, 0, NULL, 0, NULL, SiNoInst},
{"DDS/IBM/Test", "Bogus Context Number 1", 220, 0,
   PUStats, STAT_L(PUStats), NULL, 0, NULL, SiNoInst},
{"DDS/IBM/Moretest", "Bogus Context Number 2", 221, 0,
   NULL, 0, NULL, 0, NULL, SiNoInst},
{"DDS/IBM/Moretest/SubTest", "Bogus Context Number 3", 222, 
0,
   FakeMemStats, STAT_L(FakeMemStats), NULL, 0, NULL, SiNoInst},
};
static int  CxCount = CX_L(cx_table); /* Count of contexts defined */
static SpmiShare *dataarea = NULL;    /* Shared memory pointer  */
static struct dat *d = NULL;          /* Pointer to stats data area */
void SpmiStopMe()
{
   dataarea = NULL;
   SpmiExit();
   exit(0);
}

void main()
{
   dataarea = SpmiDdsInit(cx_table, CxCount, NULL, 0, 
"/etc/SpmiSul1SHM");
   if (!dataarea)
   {
      printf("%s", SpmiErrmsg);
      exit(-1);
   }

   d = (struct dat *)&dataarea->
SiShArea[0];
   signal(SIGTERM, SpmiStopMe);
   signal(SIGHUP, SpmiStopMe);
   signal(SIGINT, SpmiStopMe);
   signal(SIGSEGV, SpmiStopMe);

   gettimeofday &dataarea >
SiShT, NULL);
   d->
a = 22;
   d->
b = 42;
   d->
c = 28;
   d->
d = 62;


while(!dataarea->
SiShT, NULL);
{
   usleep(499000);
   gettimeofday(&dataarea->
SiShT, NULL);
   d->
a += dataarea->
SiShT.tv_sec & 0xff;
   d->
b += dataarea->
SiShT.tv_sec & 0xf;
   d->
c += (dataarea->
SiShT.tv_sec & 0x20f) & 0xffff;
   d->
d += (dataarea->
SiShT.tv_sec & 0x7f) & 0xffff;
 }
 SpmiStopMe();
}

A Dynamic Data Supplier for Volatile Extensions

A DDS program may allow contexts and statistics to be added and deleted on the fly. For example, assume your DDS is concerned with monitoring of the response times between pairs of network hosts. On even a small network, it would be quite excessive to define all possible host pairs and keep track of them all. At any point in time, however, a limited number of sessions are active, but this number changes as do the host pairs involved. If you wanted to reflect this volatility in the statistics you present, you would need the ability to add and delete statistics on the fly.

To illustrate the use of the two subroutines that allow you to add and delete contexts dynamically, we will expand the first sample program. We are extending the context hierarchy shown in figure 8 to look like the hierarchy shown in Figure 9.



Figure 9. Dynamic Extension of Statistics

As you can see, we plan to add a context called Bingo to the hierarchy with the previously added context Moretest as parent of the new context. The context we add has two statistics values, namely problems and solutions. It is our plan to allow the context to be added and deleted dynamically. For lack of a better trigger, we let the time-of-day determine when to add and delete the context.

We shall not be writing an entire new program. Rather, we take the previous example program and merely add the code lines required for the additional functionality using the following steps:

Declare Data Structures to Describe Dynamic Statistics

Statistics are defined almost the same way whether they are to be added permanently or dynamically. It is still true that all statistics for a context must be defined in one array. That one array may be referenced by more contexts, if appropriate; but most likely, it is not. The only real difference is that each set of statistics meant to be added dynamically must reference a separate data structure as source of its data fields. This is quite different from permanent statistics where all statistics source fields must reside in a common structure.

Obviously, there's a reason for this. Static data values occur only once. They all reside in one contiguous area in shared memory. Dynamic data values, on the contrary, may exist in multiple instances and may come and go. They are allocated dynamically in shared memory when they are required and when the values are deleted, their shared memory areas are returned to the free list.

The definition of statistics to add the problems and solutions values is shown below:

static CONST struct SpmiRawStat InstStats[] = {
{ "problems", "Fake counter value", 0, 100, SiCounter,
   SiLong, 1, SZ_OFF(inst, a, SiLong)},
{ "solutions", "Another fake counter value", 0, 100, 
SiCounter,
   SiLong, 2, SZ_OFF(inst, b, SiLong)} };

You notice that this time we do not reference the structure dat used previously but a different structure called inst, which we have yet to define.

Declare Data Structures to Describe Dynamic Context

In this example we add only a single context. We could have added many more but for each context, which the DDS program may want to add, one element must be defined in a table of contexts. No context can be dynamically added unless it was defined in a table and passed to the SpmiDdsInit function when your DDS registered with the SPMI. The table has exactly the same format as the table of permanent contexts but must not be the same table. The code segment below shows how we define the single context we need to add:

Note: The pack name, description, and ASN.1 number of the context are used as placeholders, only. The real values to use are supplied on the SpmiDDsAddCx subroutine each time a context is called.
static CONST cx_create inst_table[] = {
{"DDS/IBM/Moretest/INST1", "Instantiable Context Number 1", 
215, 0,
   InstStats, STAT_L(InstStats), NULL, 0, NULL, SiNoInst}
};

Declare Other Data Areas as Required

We need only define the structure referenced by the declared statistics and a pointer to be used for accessing the allocated shared data area. For convenience we also define an integer to hold the number of dynamic contexts:

struct inst
{
   float  a;
   u_long  b;
};

int   InstCount = CX_L(inst_table); /* Count of contexts defined */
struct inst *pt1 = NULL;           /* Pointer to stats data area */

Modify Registration with the Spmi Interface

Registration with the SPMI is almost unchanged. All we need is to tell the subroutine where the dynamic context table is and how many elements it has. This is shown in the following code segment:

dataarea = SpmiDdsInit(cx_table, CxCount, inst_table, InstCount,
"/etc/SpmiSupl_hook");
if (!dataarea)
{
   fprintf(stderr, "%s\n", SpmiErrmsg);
   exit(-1);
}
d = (struct dat *)&dataarea->
SiShArea[0];

Modify Main Loop to Add and Delete Dynamic Context

Finally, the code segment below shows the modified main loop. The loop has been extended with three pieces of code. The first one uses a subroutine SpmiDdsAddCx to add the context. The second uses SpmiDdsDelCx to delete the context again, and the third updates the values in the shared data area whenever the context and its statistics are active:

while(!dataarea->
SiShGoAway)
{
   if (dataarea->
SiShSubscrib)
      usleep(dataarea->
SiShInterval * 1000);
   else
      sleep(5);
   gettimeofday(&dataarea>
SiShT, NULL);
   d->
a = ... ;
   d->
b = ... ;
   d->
c = ... ;
   d->
d = ... ;
   if (((dataarea->
SiShT.tv_sec % 59) == 0) && (!pt1))
   {
      if (!(pt1 = (struct inst *)SpmiDdsAddCx(0, 
"DDS/IBM/Moretest/Bingo",
           "Dynamically added", 1)))
         fprintf(stderr, "Add failed: \"%s\"\n", 
SpmiErrmsg);
   }
   if (((dataarea->
SiShT.tv_sec % 120) == 0) && (pt1))
   {
      if (i = SpmiDdsDelCx((char *)pt1))
         fprintf(stderr, "Delete failed: \"%s\"\n", 
SpmiErrmsg);
      else
         pt1 = NULL;
   }
   if (pt1)
   {
      pt1->
a = ... ;
      pt1->
b = ... ;
   }
}
SpmiStopMe();

The supplied sample program SpmiSupl.c does what has just been explained. It also adds yet another context dynamically. You may want to play with that program before writing your own.

Recognizing Volatile Extensions

When your dynamic data-supplier program adds or deletes volatile extensions, this is indicated to SPMI through fields in the shared memory area. Neither the xmservd daemon nor other local data-consumer programs become aware of your changes until some event prompts them to look in the shared memory area.

This approach keeps the updating of the context structure to a minimum. The changes are only implemented if requested. The following is a list of events that causes xmservd or other local data-consumer programs to check the shared memory area for changes to volatile extensions. The RSi calls represent requests received by xmservd over the network interface; the SPMI calls would be issued by xmservd because of incoming requests or by other local data-consumer programs as required:


Example of an SPMI Data User Program

The following example program accesses the SPMI data:

/*  The following statistics are added by the SpmiPathAddSetStat
 *  subroutine to form a set of statistics:
 *     CPU/cpu0/kern
 *     CPU/cpu0/idle
 *     Mem/Real/%free
 *     PagSp/%free
 *     Proc/runque
 *     Proc/swpque
 *  These statistics are then retrieved every 2 seconds and their
 *  value is displayed to the user.
 */
#include <sys/types.h>

#include <sys/errno.h>

#include <signal.h>

#include <stdio.h>

#include <sys/Spmidef.h>
#define TIME_DELAY 2            /* time between samplings */
extern char   SpmiErrmsg[];     /* Spmi Error message array */
extern int    SpmiErrno;        /* Spmi Error indicator */
struct SpmiStatSet *statset;    /* statistics set */
/*====================== must_exit() ==========================*/
/* This subroutine is called when the program is ready to exit.
 * It frees any statsets that were defined and exits the
 * interface.
 */
/*=============================================================*/
void must_exit()
{
    /* free statsets */
    if (statset)
    if (SpmiFreeStatSet(statset))
       if (SpmiErrno)
       printf("%s", SpmiErrmsg);
    /* exit SPMI */
    SpmiExit();
    if (SpmiErrno)
       printf("%s", SpmiErrmsg);
    exit(0);
}
/*======================== getstats() =========================*/
/* getstats() traverses the set of statistics and outputs the
 * statistics values.
 */
/*=============================================================*/
void getstats()
{
    int                  counter=20;    /* every 20 lines output
                                         * the header
                                         */
    struct SpmiStatVals   *statval1;
    float                 spmivalue;
    /* loop until a stop signal is received. */
    while (1)
    {
       if(counter == 20)
       {
          /* output header info */
          /* The statistics are displayed in reverse order of how
           * they were entered into the set of statistics.
           */
          printf("\nCPU/cpu0   CPU/cpu0  Mem/Real   PagSp     ");
          printf("Proc       Proc\n");
          printf("    kern       idle    %%free     %%free    ");
          printf("runque     swpque\n");
          printf("============================================");
          printf("===============\n");
          counter=0;
       }
       /* retrieve set of statistics */
       if (SpmiGetStatSet(statset, TRUE) != 0)
       {
          printf("SpmiGetStatSet failed.\n");
          if (SpmiErrno)
             printf("%s", SpmiErrmsg);
          must_exit();
       }
       /* retrieve first statistic */
       statval1 = SpmiFirstVals(statset);
       if (statval1 == NULL)
       {
          printf("SpmiFirstVals Failed\n");
          if (SpmiErrno)
             printf("%s", SpmiErrmsg);
          must_exit();
       }
       /* traverse the set of statistics */
       while (statval1 != NULL)
       {
          /* value to be displayed */
          Spmivalue = SpmiGetValue(statset, statval1);
          if (spmivalue < 0.0)
          {
             printf("SpmiGetValue Failed\n");
             if (SpmiErrno)
                printf("%s", SpmiErrmsg);
             must_exit();
          }
          printf("  %6.2f   ",spmivalue);
          statval1 = SpmiNextVals(statset, statval1);
       }  /* end while (statval1) */
       printf("\n");

       counter++;
       sleep(TIME_DELAY);
    }
    return;
}
/*======================== addstats() =========================*/
/* addstats() adds statistics to the statistics set. */
/* addstats() also takes advantage of the different ways a
 * statistic may be added to the set.
 */
/*=============================================================*/
void addstats()
{
    SpmiCxHdl   cxhdl, parenthdl;
    /* initialize the statistics set */
    statset = SpmiCreateStatSet();
    if (statset == NULL)
    {
       printf("SpmiCreateStatSet Failed\n");
       if (SpmiErrno)
          printf("%s", SpmiErrmsg);
       must_exit();
    }
    /* Pass SpmiPathGetCx the fully qualified path name of the
     * context
     */
    if (!(cxhdl = SpmiPathGetCx("Proc", NULL)))
    {
       printf("SpmiPathGetCx failed for Proc context.\n");
       if (SpmiErrno)
          printf("%s", SpmiErrmsg);
       must_exit();
    }
    /* Pass SpmiPathAddSetStat the name of the statistic */
    /* & the handle of the parent */
    if (!SpmiPathAddSetStat(statset,"swpque", cxhdl))
    {
       printf("SpmiPathAddSetStat failed for Proc/swpque
          statistic.\n");
       if (SpmiErrno)
          printf("%s", SpmiErrmsg);
       must_exit();
    }
    if (!SpmiPathAddSetStat(statset,"runque", cxhdl))
    {
       printf("SpmiPathAddSetStat failed for Proc/runque
          statistic.\n");
       if (SpmiErrno)
          printf("%s", SpmiErrmsg);
       must_exit();
    }
    /* Pass SpmiPathAddSetStat the fully qualified name of the
     * statistic
     */
    if (!SpmiPathAddSetStat(statset,"PagSp/%free", NULL))
    {
       printf("SpmiPathAddSetStat failed for PagSp/%%free
          statistic.\n");
       if (SpmiErrno)
          printf("%s", SpmiErrmsg);
       must_exit();
    }
    if (!(parenthdl = SpmiPathGetCx("Mem", NULL)))
    {
       printf("SpmiPathGetCx failed for Mem context.\n");
       if (SpmiErrno)
          printf("%s", SpmiErrmsg);
       must_exit();
    }
    /* Pass SpmiPathGetCx the name of the context */
    /* & the handle of the parent context */
    if (!(cxhdl = SpmiPathGetCx("Real", parenthdl)))
    {
       printf("SpmiPathGetCx failed for Mem/Real context.\n");
       if (SpmiErrmsg)
          printf("%s", SpmiErrmsg);
       must_exit();
    }
    if (!SpmiPathAddSetStat(statset,"%free", cxhdl))
    {
       printf("SpmiPathAddSetStat failed for Mem/Real/%%free
          statistic.\n");
       if (SpmiErrno)
          printf("%s", SpmiErrmsg);
       must_exit();
    }
    /* Pass SpmiPathGetCx the fully qualified path name of the
     * context
     */
    if (!(cxhdl = SpmiPathGetCx("CPU/cpu0", NULL)))
    {
       printf("SpmiPathGetCx failed for CPU/cpu0 context.\n");
       if (SpmiErrno)
          printf("%s", SpmiErrmsg);
       must_exit();
    }
    if (!SpmiPathAddSetStat(statset,"idle", cxhdl))
    {
       printf("SpmiPathAddSetStat failed for CPU/cpu0/idle
          statistic.\n");
       if (SpmiErrno)
          printf("%s", SpmiErrmsg);
       must_exit();
    }
    if (!SpmiPathAddSetStat(statset,"kern", cxhdl))
    {
       printf("SpmiPathAddSetStat failed for CPU/cpu0/kern
          statistic.\n");
       if (SpmiErrno)
          printf("%s", SpmiErrmsg);
       must_exit();
    }
    return;
}
/*=============================================================*/
main(int argc, char **argv)
{
    int   spmierr=0;
    /* Initialize SPMI */
    if ((spmierr = SpmiInit(15)) != 0)
    {
       printf("Unable to initialize SPMI interface\n");
       if (SpmiErrno)
          printf("%s", SpmiErrmsg);
       exit(-98);
    }
    /* set up interrupt signals */
    signal(SIGINT,must_exit);
    signal(SIGTERM,must_exit);
    signal(SIGSEGV,must_exit);
    signal(SIGQUIT,must_exit);

    /* Go to statistics routines. */
    addstats();
    getstats();

    /* Exit SPMI */
    must_exit();
}

Example of an SPMI Data Traversal Program

The following SPMI example program traverses a data hierarchy:

#include <sys/types.h>

#include <sys/errno.h>

#include <stdio.h>

#include <sys/Spmidef.h>
extern char         SpmiErrmsg[];       /* Error Msg array */
char                stats[256];         /* statistic name info */
char                cxt[256];           /* context name info */
char                subcxt[256];        /* text holder */
char                *blanks=" ";        /* blanks for text */
char                *blank2=" ";
int                 instantiable=0;
/*======================= findstats() =========================*/
/* findstats is a function that traverses recursively down a
 * context link.  When the end of the context link is found,
 * findstats traverses down the statistics links and writes the
 * statistic name to stdout.  findstats is originally passed the
 * context handle for the TOP context.
 */
/*============================================================*/
void findstats(SpmiCxHdl cxhdl)
{
   struct SpmiCxLink   *cxlink;
   struct SpmiStatLink *statlink;
   struct SpmiCx       *spmicx, *spmicxparent;
   struct SpmiStat     *spmistat;
   char                *statname;
   char                num_string[30];
   int                 cxtlen1, cxtlen2, descplace;
   /* Get first context */
   if (cxlink = SpmiFirstCx(cxhdl))
   {
      while (cxlink)
      {
         /* output context name */
         spmicx = SpmiGetCx(cxlink->
context);
         /* if the subcxt is a child of another context */
         if (strcmp(subcxt,NULL))
         {
            strcat(subcxt,"/");
            strcat(subcxt,spmicx->
name);
         }
         else
            strcpy(subcxt,spmicx->
name);
         cxtlen1 = strlen(spmicx->
name);
         cxtlen2 = strlen(subcxt);
         /* determine if the context's parent is instantiable */
         /* because we don't want to have to print stats twice */
         spmicxparent = SpmiGetCx(spmicx->
parent);
         if ( spmicxparent->
inst_freq == SiContInst )
         {
            instantiable++;
         }
         else
            instantiable = 0;
         /* only want to print out the stats for any contexts */
         /* whose parents aren't instantiable.  If the parent */
         /* is instantiable then you only want to print out   */
         /* the stats for the first instance of that parent. */
         if (instantiable <= 1)
         {
            strcpy(cxt,subcxt);
            if (!instantiable)
            {
               if (cxtlen1 == cxtlen2)
                  descplace = 30 - cxtlen2;
               else
                  descplace = 35 - cxtlen2;
               strncat(cxt,blanks,descplace);
               strcat(cxt,spmicx->
description);
            }
            fprintf(stdout,"%s\n",cxt);
            /* Traverse the stats list for the context */
            if (statlink = SpmiFirstStat(cxlink->
context))
            {
               while (statlink)
               {
                  spmistat = SpmiGetStat(statlink->
stat);
                  statname = SpmiStatGetPath(cxlink->
context,
                  statlink->
stat, 10);
                  /* output statistic name */
                  strcpy(stats,statname);
                  descplace = strlen(stats);
                  descplace = 40 - descplace;
                  strncat(stats,blanks,descplace);
                  strcat(stats,spmistat->
description);
                  fprintf(stdout, "%s\n",stats);
                  /* output stat info */
                  strcpy(stats,"Data Type(");
                  if (spmistat->
data_type == SiLong)
                     strcat(stats,"Long) ");
                  else
                     strcat(stats,"Float)");
                  strcat(stats,"  Value Type(");
                  if (spmistat->
value_type == SiCounter)
                     strcat(stats,"Counter)");
                  else
                     strcat(stats,"Quantity)");
                  fprintf(stdout, "%s%s\n",blank2,stats);
            fprintf(stdout,"%s\n",cxt);
         }
         /* recursive call to function */
         /* this gets the next context link */
         findstats(cxlink->
context);
         if (cxtlen2 == cxtlen1)
           strcpy(subcxt,NULL);
         else
            subcxt[cxtlen2-cxtlen1-1] = NULL;
         /* Go to next context */
         cxlink = SpmiNextCx(cxlink);
      }  /* end while(cxlink) */
   }  /* end if (cxlink) */
   return;
}
/*========================= lststats() ========================*/
/* lststats gets the TOP context handle.  This handle is then
 * passed to the findstats routine
 */
/*=============================================================*/
void lststats()
{
   SpmiCxHdl      cxhdl;
   return;
}
/*============================  main()  =======================*/
main(int argc, char **argv)
{
   int    spmierr=0;
   /* Initialize SPMI interface */
   if ((spmierr = SpmiInit(15)) != 0)
   {
      fprintf(stderr, "Unable to initialize SPMI interface\n");
      fprintf(stderr, "%s", SpmiErrmsg);
      exit(-98);
   }
   /* Traversal routine. */
   lststats();

   /* Exit SPMI Interface */
   SpmiExit();
   if (strlen(SpmiErrmsg))
      fprintf(stderr, "%s", SpmiErrmsg);
   exit(0);
}

Example of an SPMI Dynamic Data-Supplier Program

The following SPMI example program expands the data hierarchy:

   signal(SIGTERM, SpmiStopMe);
   signal(SIGHUP, SpmiStopMe);
   signal(SIGINT, SpmiStopMe);
   signal(SIGSEGV, SpmiStopMe);

List of SPMI Error Codes

All SPMI subroutines use constants to define error codes. The SPMI Error Code table lists the error descriptions.

Symbolic Name Number Description
SiSuccess 0 Successful execution.
SiInvalidCx 180 The referenced context doesn't exist.
SiNoShmPtr 181 Unable to identify shared memory segment.
SiShmemFailed 182 Unable to access shared memory.
SiAssumedDead 183 A data-supplier program appears to have terminated.
SiInstBusy 184 Can't instantiate; shared memory update in progress.
SiNotInst 185 Requested instantiation could not be performed.
SiNotInit 186 SPMI interface not initialized.
SiBadArgument 187 One or more arguments to a subroutine call is invalid.
SiNotFound 188 A requested data structure doesn't exist.
SiNoValue 189 No data value returned from the SpmiGetValue subroutine.
SiInitFailed 190 Initializing of the SPMI API failed.
SiSmuxFailed 191 Context could not be exported to the snmpd daemon through the SMUX protocol.
SiLocked 192 Some other process or thread has locked the common shared memory area and prevents the subroutine from executing its the requested function. Retry the subroutine call.
SiDuplicate 193 Attempt to add a context path that alreadu exists.
SiCallocFailed 194 Memory allocation error.
SiNoLicense 195 No licence to use is installed and valid.
SiDeleted 196 The requested context has been deleted.
SiOtherErr 197 Unspecified internal error.

Related Information

System Performance Measurement Interface Overview for Programming> , Understanding the SPMI Data Hierarchy , Understanding SPMI Data Areas , Dynamic Data Supplier (DDS) Program Structures .


SPMI Subroutines

The SPMI subroutines constitute the application programming interface (API) to the SPMI.

The SPMI Interface Subroutines

The SPMI subroutines are organized according to function.

The following functional lists of SPMI subroutines are provided:

Initialize, Terminate, and Instantiate subroutines

The following subroutines prepare a system for SPMI processing, free memory after SPMI processing, or create an instance of a system resource or object:

SpmiInit Initializes the SPMI.
SpmiExit Releases allocated memory and disconnects from the SPMI library.
SpmiInstantiate Explicitly instantiates the subcontexts of an instantiable context.

Data Hierarchy Traversal subroutines

The following subroutines navigate through an SPMI data hierarchy:

SpmiPathGetCx Returns a handle to use when referencing a context.
SpmiFirstCx Locates the first subcontext of a context.
SpmiNextCx Locates the next subcontext of a context.
SpmiFirstStat Locates the first statistic belonging to a context.
SpmiNextStat Locates the next statistic belonging to a context.
SpmiStatGetPath Returns the full path name of a statistic.
SpmiGetCx Returns a pointer to the SpmiCx structure corresponding to a specified context handle.
SpmiGetStat Returns a pointer to the SpmiStat structure corresponding to a specified statistic handle.

StatSet Maintenance subroutines

The followings SPMI subroutines create or remove a set of statistics, or add or delete statistics from the set:

SpmiCreateStatSet Creates an empty set of statistics.
SpmiPathAddSetStat Adds a statistics value to a set of statistics.
SpmiFreeStatSet Erases a set of statistics.
SpmiDelSetStat Removes a single statistic from a set of statistics.

HotSet Maintenance subroutines

The followings SPMI subroutines create or remove a hotset, or add or delete sets of peer statistics to or from the set:

SpmiCreateHotSet Creates an empty set of peer statistics (hotset).
SpmiAddSetHot Adds a set of peer statistics values to a hotset.
SpmiFreeHotSet Erases a hotset.
SpmiDelSetHot Removes a set of peer statistics from a hotset.

Data Access subroutines

The following subroutines access SPMI statistics:

SpmiGetStatSet Requests the SPMI to read the data values for all statistics belonging to a specified statset.
SpmiFirstVals Returns a pointer to the first SpmiStatVals structure belonging to a statset.
SpmiNextVals Returns a pointer to the next SpmiStatVals structure belonging to a statset.
SpmiGetValue Returns a decoded value based on the type of data value extracted from the data field of an SpmiStatVals structure.
SpmiNextValue Returns a pointer to the next SpmiStatVals structure in a set of statistics. Combines calls to SpmiFirstVals, SpmiNextVals, and SpmiGetValue into a single call for more efficient startset processing.
SpmiGetHotSet Requests the SPMI to read the data values for all sets of peer statistics belonging to a specified hotset.
SpmiFirstHot Returns a pointer to the first set of peer statistics (SpmiHotVals structure) belonging to a hotset.
SpmiNextHot Returns a pointer to the next set of peer statistics (SpmiHotVals structure) belonging to a hotset.
SpmiNextHotItem Returns a pointer to the next set of peer statistics (SpmiHotVals structure) belonging to a hotset and decodes the next data value from the SpmiHotVals structure. Used to walk all the returned SpmiHotItems elements returned by SpmiGetHotSet.

Expand or Reduce the Data Hierarchy subroutines

The following subroutines are used by SPMI Dynamic Data Supplier (DDS) programs:

SpmiDdsInit Initializes a DDS program, establishes access to the common shared memory area, and connects the DDS shared memory area to the SPMI.
SpmiDdsAddCx Adds a volatile context from a DDS program.
SpmiDdsDelCx Deletes a volatile context previously added from the DDS program.

SpmiAddSetHot Subroutine

Purpose

Adds a set of peer statistics values to a hotset.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiHotVals *SpmiAddSetHot(HotSet, StatName, 
GrandParent, maxresp,
                                  threshold, frequency, feed_type,
                                  except_type, severity, trap_no)
struct SpmiHotSet *HotSet;
char *StatName;
SpmiCxHdl GrandParent;
int maxresp;
int threshold;
int frequency;
int feed_type;
int excp_type;
int severity;
int trap_no;

Description

The SpmiAddSetHot subroutine adds a set of peer statistics to a hotset. The SpmiHotSet structure that provides the anchor point to the set must exist before the SpmiAddSetHot subroutine call can succeed.

Parameters

HotSet
Specifies a pointer to a valid structure of type SpmiHotSet as created by the SpmiCreateHotSet subroutine call.

StatName
Specifies the name of the statistic within the subcontexts (peer contexts) of the context identified by the GrandParent parameter.

GrandParent
Specifies a valid SpmiCxHdl handle as obtained by another subroutine call. The handle must identify a context with at least one subcontext, which contains the statistic identified by the StatName parameter. If the context specified is one of the RTime contexts, no subcontext need to exist at the time the SpmiAddSetHot subroutine call is issued; the presence of the metric identified by the StatName parameter is checked against the context class description.

If the context specified has or may have multiple levels of instantiable context below it (such as the FS and RTime/ARM contexts), the metric is only searched for at the lowest context level. The SpmiHotSet created is a pseudo hotvals structure used to link together a peer group of SpmiHotVals structures, which are created under the covers, one for each subcontext of the GrandParent context. In the case of RTime/ARM, if additional contexts are later added under the GrandParent contexts, additional hotsets are added to the peer group. This is transparent to the application program, except that the SpmiFirstHot, SpmiNextHot, and SpmiNextHotItem subroutine calls will return the peer group SpmiHotVals pointer rather than the pointer to the pseudo structure.

Note that specifying a specific volume group context (such as FS/rootvg) or a specific application context (such as RTime/ARN/armpeek) is still valid and won't involve creation of pseudo SpmiHotVals structures.

maxresp
Must be non-zero if excp_type specifies that exceptions or SNMP traps must be generated. If specified as zero, indicates that all SpmiHotItems that meet the criteria specified by threshold must be returned, up-to a maximum of maxresp items. If both exceptions/traps and feeds are requested, the maxresp value is used to cap the number of exceptions/alerts as well as the number of items returned. If feed_type is specified as SiHotAlways, the maxresp parameter is still used to return at most maxresp items.

Where the GrandParent argument specifies a context that has multiple levels of instantiable contexts below it, the maxresp is applied to each of the lowest level contexts above the the actual peer contexts at a time. For example, if the GrandParent context is FS (file systems) and the system has three volume groups, then a maxresp value of 2 could cause up to a maximum of 2 x 3 = 6 responses to be generated.

threshold
Must be non-zero if excp_type specifies that exceptions or SNMP traps must be generated. If specified as zero, indicates that all values read qualify to be returned in feeds. The value specified is compared to the data value read for each peer statistic. If the data value exceeds the threshold, it qualifies to be returned as an SpmiHotItems element in the SpmiHotVals structure. If the threshold is specified as a negative value, the value qualifies if it is lower than the numeric value of threshold. If feed_type is specified as SiHotAlways, the threshold value is ignored for feeds. For peer statistics of type SiCounter, the threshold must be specified as a rate per second; for SiQuantity statistics the threshold is specified as a level.

frequency
Must be non-zero if excp_type specifies that exceptions or SNMP traps must be generated. Ignored for feeds. Specifies the minimum number of minutes that must expire between any two exceptions/traps generated from this SpmiHotVals structure. This value must be specified as no less than 5 minutes.

feed_type
Specifies if feeds of SpmiHotItems should be returned for this SpmiHotVals structure. The following values are valid:

SiHotNoFeed
No feeds should be generated
SiHotThreshold
Feeds are controlled by threshold.
SiHotAlways
All values, up-to a maximum of maxresp must be returned as feeds.

excp_type
Controls the generation of exception data packets and/or the generation of SNMP Traps from xmservd. Note that these types of packets and traps can only actually be sent if xmservd is running. Because of this, exception packets and SNMP traps are only generated as long as xmservd is active. Traps can only be generated on AIX systems. The conditions for generating exceptions and traps are controlled by the threshold and frequency parameters. The following values are valid for excp_type:

SiNoHotException
Generate neither exceptions not traps.
SiHotException
Generate exceptions but not traps.
SiHotTrap
Generate SNMP traps but not exceptions.
SiHotBoth
Generate both exceptions and SNMP traps.

severity
Required to be positive and greater than zero if exceptions are generated, otherwise specify as zero. Used to assign a severity code to the exception for display by exmon.

trap_no
Required to be positive and greater than zero if SNMP traps are generated, otherwise specify as zero. Used to assign the trap number in the generated SNMP trap.

Return Values

The SpmiAddSetHot subroutine returns a pointer to a structure of type SpmiHotVals if successful. If unsuccessful, the subroutine returns a NULL value.

Programming Notes

The SpmiAddSetHot functions in a straight forward manner and as described above in all cases where the GrandParent context is a context that has only one level of instantiable contexts below it. This covers most context types such as CPU, Disk, LAN, etc. In a few cases, currently only the FS (file system) and RTime/ARM (application response) contexts, the Spmi works by creating pseudo-hotvals structures that effectively expand the hotset. These pseudo-hotvals structures are created either at the time the SpmiAddSetHot call is issued or when new subcontexts are created for a context that's already the GrandParent of a hotvals peer set. For example:

When a peer set is created for RTime/ARM, maybe only a few or no subcontexts of this context exists. If two applications were defined at this point, say checking and savings, one valsset would be created for the RTime/ARM context and a pseudo-valsset for each of RTime/ARM/checking and RTime/ARM/savings. As new applications are added to the RTime/ARM contexts, new pseudo-valssets are automatically added to the hotset.

Pseudo-valssets represent an implementation convenience and also helps minimize the impact of retrieving and presenting data for hotsets. As far as the caller of the RSiGetHotItem subroutine call is concerned, it is completely transparent. All this caller will ever see is the real hotvals structure. That is not the case for callers of SpmiFirstHot, SpmiNextHot, and SpmiNextHotItem. All of these subroutines will return pseudo-valssets and the calling program should be prepared to handle this.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.


SpmiCreateHotSet

Purpose

Creates an empty hotset.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiHotSet *SpmiCreateHotSet()

Description

The SpmiCreateHotSet subroutine creates an empty hotset and returns a pointer to an SpmiHotSet structure.This structure provides the anchor point for a hotset and must exist before the SpmiAddSetHot subroutine can be successfully called.

Return Values

The SpmiCreateHotSet subroutine returns a pointer to a structure of type SpmiHotSet if successful. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiDelSetHot subroutine , SpmiFreeHotSet subroutine , SpmiAddSetHot subroutine .

Understanding SPMI Data Areas.


SpmiCreateStatSet Subroutine

Purpose

Creates an empty set of statistics.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiStatSet *SpmiCreateStatSet()

Description

The SpmiCreateStatSet subroutine creates an empty set of statistics and returns a pointer to an SpmiStatSet structure.

The SpmiStatSet structure provides the anchor point to a set of statistics and must exist before the SpmiPathAddSetStat subroutine can be successfully called.

Return Values

The SpmiCreateStatSet subroutine returns a pointer to a structure of type SpmiStatSet if successful. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiDelSetStat subroutine , SpmiFreeStatSet subroutine , SpmiPathAddSetStat subroutine .

Understanding SPMI Data Areas .


SpmiDdsAddCx Subroutine

Purpose

Adds a volatile context to the contexts defined by an application.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
char *SpmiDdsAddCx(Ix, Path, Descr, Asnno)
ushort Ix;
char *Path, *Descr;
int Asnno;

Description

The SpmiDdsAddCx subroutine uses the shared memory area to inform the SPMI that a context is available to be added to the context hierarchy, moves a copy of the context to shared memory, and allocates memory for the data area.

Parameters

Ix
Specifies the element number of the added context in the table of dynamic contexts. No context can be added if the table of dynamic contexts has not been defined in the SpmiDdsInit subroutine call. The first element of the table is element number 0.

Path
Specifies the full path name of the context to be added. If the context is not at the top level, the parent context must already exist.

Descr
Provides the description of the context to be added as it will be presented to data consumers.

Asnno
Specifies the ASN.1 number to be assigned to the new context. All subcontexts on the same level as the new context must have unique ASN.1 numbers. Typically, each time the SpmiDdsAddCx subroutine adds a subcontext to the same parent context, the Asnno parameter is incremented. See Making Dynamic Data-Supplier Statistics Unique for more information about ASN.1 numbers.

Return Values

If successful, the SpmiDdsAddCx subroutine returns the address of the shared memory data area. If an error occurs, an error text is placed in the external SpmiErrmsg character array, and the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiDdsDel subroutine , SpmiDdsInit subroutine .

Understanding SPMI Data Areas .


SpmiDdsDelCx Subroutine

Purpose

Deletes a volatile context.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
int SpmiDdsDelCx(Area)
char *Area;

Description

The SpmiDdsDelCx subroutine informs the SPMI that a previously added, volatile context should be deleted.

If the SPMI has not detected that the context to delete was previously added dynamically, the SpmiDdsDelCx subroutine removes the context from the list of to-be-added contexts and returns the allocated shared memory to the free list. Otherwise, the SpmiDdsDelCx subroutine indicates to the SPMI that a context and its associated statistics must be removed from the context hierarchy and any allocated shared memory must be returned to the free list.

Parameters

Area
Specifies the address of the previously allocated shared memory data area as returned by an SpmiDdsAddCx subroutine call.

Return Values

If successful, the SpmiDdsDelCx subroutine returns a value of 0. If an error occurs, an error text is placed in the external SpmiErrmsg character array, and the subroutine returns a nonzero value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiDdsAddCx subroutine , SpmiDdsInit subroutine .

Understanding SPMI Data Areas.


SpmiDdsInit Subroutine

Purpose

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
SpmiShare *SpmiDdsInit(CxTab, CxCnt, IxTab, IxCnt, 
FileName)
cx_create *CxTab, *IxTab;
int CxCnt, IxCnt;
char *FileName;

Description

The SpmiDdsInit subroutine establishes a program as a dynamic data-supplier (DDS) program. To do so, the SpmiDdsInit subroutine:

  1. Determines the size of the shared memory required and creates a shared memory segment of that size.
  2. Moves all static contexts and all statistics referenced by those contexts to the shared memory.
  3. Calls the SPMI and requests it to add all of the DDS static contexts to the context tree.

Note: The SpmiDdsInit subroutine issues an SpmiInit subroutine call if the application program has not issued one.

Note: If the calling program uses shared memory for other purposes, including memory mapping of files, the SpmiDdsInit or the SpmiInit subroutine call must be issued before access is established to other shared memory areas.

Parameters

CxTab
Specifies a pointer to the table of nonvolatile contexts to be added.

CxCnt
Specifies the number of elements in the table of nonvolatile contexts. Use the CX_L macro to find this value.

IxTab
Specifies a pointer to the table of volatile contexts the program may want to add later. If no contexts are defined, specify NULL.

IxCnt
Specifies the number of elements in the table of volatile contexts. Use the CX_L macro to find this value. If no contexts are defined, specify 0.

FileName
Specifies the fully qualified path and file name to use when creating the shared memory segment. At execution time, if the file exists, the process running the DDS must be able to write to the file. Otherwise, the SpmiDdsInit subroutine call does not succeed. If the file does not exist, it is created. If the file cannot be created, the subroutine returns an error. If the file name includes directories that do not exist, the subroutine returns an error.

For non-AIX systems, a sixth argument is required to inform the SPMI how much memory to allocate in the DDS shared memory segment. This is not required for AIX systems because facilities exist to expand a memory allocation in shared memory. The sixth argument is:

size
Size in bytes of the shared memory area to allocate for the DDS program. This parameter is of type int.

Return Values

If successful, the SpmiDdsInit subroutine returns the address of the shared memory control area. If an error occurs, an error text is placed in the external SpmiErrmsg character array, and the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiExit subroutine , SpmiInit subroutine .

Understanding SPMI Data Areas .


SpmiDelSetHot Subroutine

Purpose

Removes a single set of peer statistics from a hotset.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
int SpmiDelSetHot(HotSet, HotVal)
struct SpmiHotSet *HotSet;
struct SpmiHotVals *HotVal;

Description

The SpmiDelSetHot subroutine removes a single set of peer statistics, identified by the HotVal parameter, from a hotset, identified by the HotSet parameter.

Parameters

HotSet
Specifies a pointer to a valid structure of type SpmiHotSet as created by the SpmiCreateHotSet subroutine call.

HotVal
Specifies a pointer to a valid structure of type SpmiHotVals as created by the SpmiAddSetHot subroutine call. You can not specify an SpmiHotVals that was internally generated by the Spmi library code as described under the GrandParent parameter to SpmiAddSetHot.

Return Values

The SpmiDelSetHot subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiCreateHotSet subroutine , SpmiFreeHotSet subroutine , SpmiAddSetHot subroutine .

Understanding SPMI Data Areas .


SpmiDelSetStat Subroutine

Purpose

Removes a single statistic from a set of statistics.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
int SpmiDelSetStat(StatSet, StatVal)
struct SpmiStatSet *StatSet;
struct SpmiStatVals *StatVal;

Description

The SpmiDelSetStat subroutine removes a single statistic, identified by the StatVal parameter, from a set of statistics, identified by the StatSet parameter.

Parameters

StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet subroutine call.

StatVal
Specifies a pointer to a valid structure of type SpmiStatVals as created by the SpmiPathAddSetStat subroutine call.

Return Values

The SpmiDelSetStat subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes rel="pagenum"> for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiCreateStatSet subroutine , SpmiFreeStatSet subroutine , SpmiPathAddSetStat subroutine .

Understanding SPMI Data Areas .


SpmiExit Subroutine

Purpose

Terminates a dynamic data supplier (DDS) or local data consumer program's association with the SPMI, and releases allocated memory.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
void SpmiExit()

Description

A successful SpmiInit or SpmiDdsInit subroutine call allocates shared memory. Therefore, a Dynamic Data Supplier (DDS) program that has issued a successful SpmiInit or SpmiDdsInit subroutine call should issue an SpmiExit subroutine call before the program exits the SPMI. Allocated memory is not released until the program issues an SpmiExit subroutine call.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiInit subroutine , SpmiDdsInit subroutine .


SpmiFirstCx Subroutine

Purpose

Locates the first subcontext of a context.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiCxLink *SpmiFirstCx(CxHandle)
SpmiCxHdl CxHandle;

Description

The SpmiFirstCx subroutine locates the first subcontext of a context. The subroutine returns a NULL value if no subcontexts are found.

The structure pointed to by the returned pointer contains a handle to access the contents of the corresponding SpmiCx structure through the SpmiGetCx subroutine call.

Parameters

CxHandle
Specifies a valid SpmiCxHdl handle as obtained by another subroutine call.

Return Values

The SpmiFirstCx subroutine returns a pointer to an SpmiCxLink structure if successful. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiGetCx subroutine , SpmiNextCx subroutine .

Understanding SPMI Data Areas .

Understanding the SPMI Data Hierarchy.


SpmiFirstHot Subroutine

Purpose

Locates the first of the sets of peer statistics belonging to a hotset.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiHotVals *SpmiFirstHot(HotSet)
struct SpmiHotSet HotSet;

Description

The SpmiFirstHot subroutine locates the first of the SpmiHotVals structures belonging to the specified SpmiHotSet. Using the returned pointer, the SpmiHotSet can then either be decoded directly by the calling program, or it can be used to specify the starting point for a subsequent SpmiNextHotItem subroutine call. The SpmiFirstHot subroutine should only be executed after a successful call to the SpmiGetHotSet subroutine.

Parameters

HotSet
Specifies a valid SpmiHotSet structure as obtained by another subroutine call.

Return Values

The SpmiFirstHot subroutine returns a pointer to a structure of type SpmiHotVals structure if successful. If unsuccessful, the subroutine returns a NULL value. A returned pointer may refer to a pseudo-hotvals structure as described in Programming Notes for the SpmiAddSetHot subroutine.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiCreateHotSet subroutine , SpmiAddSetHot subroutine , SpmiNextHot subroutine , SpmiNextHotItem subroutine .

Understanding SPMI Data Areas .

Understanding the SPMI Data Hierarchy.


SpmiFirstStat Subroutine

Purpose

Locates the first of the statistics belonging to a context.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiStatLink *SpmiFirstStat(CxHandle)
SpmiCxHdl CxHandle;

Description

The SpmiFirstStat subroutine locates the first of the statistics belonging to a context. The subroutine returns a NULL value if no statistics are found.

The structure pointed to by the returned pointer contains a handle to access the contents of the corresponding SpmiStat structure through the SpmiGetStat subroutine call.

Parameters

CxHandle
Specifies a valid SpmiCxHdl handle as obtained by another subroutine call.

Return Values

The SpmiFirstStat subroutine returns a pointer to a structure of type SpmiStatLink if successful. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiGetStat subroutine , SpmiNextStat subroutine .

Understanding SPMI Data Areas .

Understanding the SPMI Data Hierarchy .


SpmiFirstVals Subroutine

Purpose

Returns a pointer to the first SpmiStatVals structure belonging to a set of statistics.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiStatVals *SpmiFirstVals(StatSet)
struct SpmiStatSet *StatSet;

Description

The SpmiFirstVals subroutine returns a pointer to the first SpmiStatVals structure belonging to the set of statistics identified by the StatSet parameter. SpmiStatVals structures are accessed in reverse order so the last statistic added to the set of statistics is the first one returned. This subroutine call should only be issued after an SpmiGetStatSet subroutine has been issued against the statset.

Parameters

StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet subroutine call.

Return Values

The SpmiFirstVals subroutine returns a pointer to an SpmiStatVals structure if successful. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiCreateStatSet subroutine , SpmiNextVals subroutine .

Understanding SPMI Data Areas .


SpmiFreeHotSet Subroutine

Purpose

Erases a hotset.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
int SpmiFreeHotSet(HotSet)
struct SpmiHotSet *HotSet;

Description

The SpmiFreeHotSet subroutine erases the hotset identified by the HotSet parameter. All SpmiHotVals structures chained off the SpmiHotSet structure are deleted before the set itself is deleted.

Parameters

HotSet
Specifies a pointer to a valid structure of type SpmiHotSet as created by the SpmiCreateHotSet subroutine call.

Return Values

The SpmiFreeHotSet subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiCreateHotSet subroutine , SpmiDelSetHot subroutine , SpmiAddSetHot subroutine .

Understanding SPMI Data Areas .


SpmiFreeStatSet Subroutine

Purpose

Erases a set of statistics.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
int SpmiFreeStatSet(StatSet)
struct SpmiStatSet *StatSet;

Description

The SpmiFreeStatSet subroutine erases the set of statistics identified by the StatSet parameter. All SpmiStatVals structures chained off the SpmiStatSet structure are deleted before the set itself is deleted.

Parameters

StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet subroutine call.

Return Values

The SpmiFreeStatSet subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiCreateStatSet subroutine , SpmiDelSetStat subroutine , SpmiPathAddSetStat subroutine .

Understanding SPMI Data Areas .


SpmiGetCx Subroutine

Purpose

Returns a pointer to the SpmiCx structure corresponding to a specified context handle.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiCx *SpmiGetCx(CxHandle)
SpmiCxHdl CxHandle;

Description

The SpmiGetCx subroutine returns a pointer to the SpmiCx structure corresponding to the context handle identified by the CxHandle parameter.

Parameters

CxHandle
Specifies a valid SpmiCxHdl handle as obtained by another subroutine call.

Return Values

The SpmiGetCx subroutine returns a a pointer to an SpmiCx data structure if successful. If unsuccessful, the subroutine returns NULL.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiFirstCx subroutine , SpmiNextCx subroutine .

Understanding SPMI Data Areas .

Understanding the SPMI Data Hierarchy.


SpmiGetHotSet Subroutine

Purpose

Requests the SPMI to read the data values for all sets of peer statistics belonging to a specified SpmiHotSet.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
int SpmiGetHotSet(HotSet, Force);
struct SpmiHotSet *HotSet;
boolean Force;

Description

The SpmiGetHotSet subroutine requests the SPMI to read the data values for all peer sets of statistics belonging to the SpmiHotSet identified by the HotSet parameter. The Force parameter is used to force the data values to be refreshed from their source.

The Force parameter works by resetting a switch held internally in the SPMI for all SpmiStatVals and SpmiHotVals structures, regardless of the SpmiStatSets and SpmiHotSets to which they belong. Whenever the data value for a peer statistic is requested, this switch is checked. If the switch is set, the SPMI reads the latest data value from the original data source. If the switch is not set, the SPMI reads the data value stored in the SpmiHotVals structure. This mechanism allows a program to synchronize and minimize the number of times values are retrieved from the source. One method programs can use is to ensure the force request is not issued more than once per elapsed amount of time.

Parameters

HotSet
Specifies a pointer to a valid structure of type SpmiHotSet as created by the SpmiCreateHotSet subroutine call.

Force
If set to true, forces a refresh from the original source before the SPMI reads the data values for the set. If set to false, causes the SPMI to read the data values as they were previously retrieved from the data source.

When the force argument is set true, the effect is that of marking all statistics known by the SPMI as obsolete, which causes the SPMI to refresh all requested statistics from kernel memory or other sources. As each statistic is refreshed, the obsolete mark is reset. Statistics that are not part of the HotSet specified in the subroutine call remain marked as obsolete. Therefore, if an application repetitively issues a series of SpmiGetHotSet and SpmiGetStatSet subroutine calls for multiple hotsets and statsets, each time, only the first such call need set the force argument to true.

Return Values

The SpmiGetHotSet subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiCreateHotSet subroutine , SpmiAddSetHot subroutine .

Data Access Structures and Handles, HotSets.


SpmiGetStat Subroutine

Purpose

Returns a pointer to the SpmiStat structure corresponding to a specified statistic handle.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiStat *SpmiGetStat(StatHandle)
SpmiStatHdl StatHandle;

Description

The SpmiGetStat subroutine returns a pointer to the SpmiStat structure corresponding to the statistic handle identified by the StatHandle parameter.

Parameters

StatHandle
Specifies a valid SpmiStatHdl handle as obtained by another subroutine call.

Return Values

The SpmiGetStat subroutine returns a pointer to a structure of type SpmiStat if successful. If unsuccessful, the subroutine returns a NULL value.

Return Values

The SpmiGetStat subroutine returns a pointer to a structure of type SpmiStat if successful. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiFirstStat subroutine rel="pagenum">, SpmiNextStat subroutine .

Understanding SPMI Data Areas .

Understanding the SPMI Data Hierarchy.


SpmiGetStatSet Subroutine

Purpose

Requests the SPMI to read the data values for all statistics belonging to a specified set.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
int SpmiGetStatSet(StatSet, Force);
struct SpmiStatSet *StatSet;
boolean Force;

Description

The SpmiGetStatSet subroutine requests the SPMI to read the data values for all statistics belonging to the SpmiStatSet identified by the StatSet parameter. The Force parameter is used to force the data values to be refreshed from their source.

The Force parameter works by resetting a switch held internally in the SPMI for all SpmiStatVals and SpmiHotVals structures, regardless of the SpmiStatSets and SpmiHotSets to which they belong. Whenever the data value for a statistic is requested, this switch is checked. If the switch is set, the SPMI reads the latest data value from the original data source. If the switch is not set, the SPMI reads the data value stored for the SpmiStatVals structure. This mechanism allows a program to synchronize and minimize the number of times values are retrieved from the source. One method is to ensure the force request is not issued more than once per elapsed amount of time.

Parameters

StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet subroutine call.

Force
If set to true, forces a refresh from the original source before the SPMI reads the data values for the set. If set to false, causes the SPMI to read the data values as they were previously retrieved from the data source.

When the force argument is set true, the effect is that of marking all statistics known by the SPMI as obsolete, which causes the SPMI to refresh all requested statistics from kernel memory or other sources. As each statistic is refreshed, the obsolete mark is reset. Statistics that are not part of the StatSet specified in the subroutine call remain marked as obsolete. Therefore, if an application repetitively issues the SpmiGetStatSet and SpmiGetHotSet subroutine calls for multiple statsets and hotsets, each time, only the first such call need set the force argument to true.

Return Values

The SpmiGetStatSet subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiCreateStatSet subroutine , SpmiPathAddSetStat subroutine .

Data Access Structures and Handles, StatSets.


SpmiGetValue Subroutine

Purpose

Returns a decoded value based on the type of data value extracted from the data field of an SpmiStatVals structure.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
float SpmiGetValue(StatSet, StatVal)
struct SpmiStatSet *StatSet;
struct SpmiStatVals *StatVal;

Description

The SpmiGetValue subroutine performs the following steps:

  1. Verifies that an SpmiStatVals structure exists in the set of statistics identified by the StatSet parameter.
  2. Determines the format of the data field as being either SiFloat or SiLong and extracts the data value for further processing.
  3. Determines the data value as being of either type SiQuantity or type SiCounter.
  4. If the data value is of type SiQuantity, returns the val field of the SpmiStatVals structure.
  5. If the data value is of type SiCounter, returns the value of the val_change field of the SpmiStatVals structure divided by the elapsed number of seconds since the previous time a data value was requested for this set of statistics.

This subroutine call should only be issued after an SpmiGetStatSet subroutine has been issued against the statset.

Parameters

StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet subroutine call.

StatVal
Specifies a pointer to a valid structure of type SpmiStatVals as created by the SpmiPathAddSetStat subroutine call or returned by the SpmiFirstVals or SpmiNextVals subroutine calls.

Return Values

The SpmiGetValue subroutine returns the decoded value if successful. If unsuccessful, the subroutine returns a negative value that has a numerical value of at least 1.1.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes rel="pagenum"> for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiGetStatSet subroutine , SpmiCreateStatSet subroutine , SpmiPathAddSetStat subroutine .

Data Access Structures and Handles, StatSets.

Understanding SPMI Data Areas .


SpmiInit Subroutine

Purpose

Initializes the SPMI for a local data consumer program.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
int SpmiInit (TimeOut)
int TimeOut;

Description

The SpmiInit subroutine initializes the SPMI. During SPMI initialization, a memory segment is allocated and the application program obtains basic addressability to that segment. An application program must issue the SpmiInit subroutine call before issuing any other subroutine calls to the SPMI.

Note: The SpmiInit subroutine is automatically issued by the SpmiDdsInit subroutine call. Successive SpmiInit subroutine calls are ignored.

Note: If the calling program uses shared memory for other purposes, including memory mapping of files, the SpmiInit subroutine call must be issued before access is established to other shared memory areas.

The SPMI entry point called by the SpmiInit subroutine assigns a segment register to be used by the SPMI subroutines (and the application program) for accessing common shared memory and establishes the access mode to the common shared memory segment. After SPMI initialization, the SPMI subroutines are able to access the common shared memory segment in read-only mode.

Parameters

TimeOut
Specifies the number of seconds the SPMI waits for a Dynamic Data Supplier (DDS) program to update its shared memory segment. If a DDS program does not update its shared memory segment in the time specified, the SPMI assumes that the DDS program has terminated or disconnected from shared memory and removes all contexts and statistics added by the DDS program.

The SPMI saves the largest TimeOut value received from the programs that invoke the SPMI. The TimeOut value must be zero or must be greater than or equal to 15 seconds and less than or equal to 600 seconds. A value of zero overrides any other value from any other program that invokes the Spmi and disables the checking for terminated DDS programs.

Return Values

The SpmiInit subroutine returns a value of 0 if successful. If unsuccessful, the subroutine returns a nonzero value. If a nonzero value is returned, the application program should not attempt to issue additional SPMI subroutine calls.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiDdsInit subroutine , SpmiExit subroutine .


SpmiInstantiate Subroutine

Purpose

Explicitly instantiates the subcontexts of an instantiable context.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
int SpmiInstantiate(CxHandle)
SpmiCxHdl CxHandle;

Description

The SpmiInstantiate subroutine explicitly instantiates the subcontexts of an instantiable context. If the context is not instantiable, do not call the SpmiInstantiate subroutine.

An instantiation is done implicitly by the SpmiPathGetCx and SpmiFirstCx subroutine calls. Therefore, application programs usually do not need to instantiate explicitly.

Parameters

CxHandle
Specifies a valid context handle (SpmiCxHdl) as obtained by another subroutine call.

Return Values

The SpmiInstantiate subroutine returns a value of 0 if successful. If the context is not instantiable, the subroutine returns a nonzero value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiFirstCx subroutine , SpmiPathGetCx subroutine .

Understanding the SPMI Data Hierarchy.


SpmiNextCx Subroutine

Purpose

Locates the next subcontext of a context.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiCxLink *SpmiNextCx(CxLink)
struct SpmiCxLink *CxLink;

Description

The SpmiNextCx subroutine locates the next subcontext of a context, taking the context identified by the CxLink parameter as the current subcontext. The subroutine returns a NULL value if no further subcontexts are found.

The structure pointed to by the returned pointer contains an SpmiCxHdl handle to access the contents of the corresponding SpmiCx structure through the SpmiGetCx subroutine call.

Parameters

CxLink
Specifies a pointer to a valid SpmiCxLink structure as obtained by a previous SpmiFirstCx subroutine call.

Return Values

The SpmiNextCx subroutine returns a pointer to a structure of type SpmiCxLink if successful. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiFirstCx subroutine , SpmiGetCx subroutine .

Understanding SPMI Data Areas .

Understanding the SPMI Data Hierarchy.


SpmiNextHot Subroutine

Purpose

Locates the next set of peer statistics (SpmiHotVals structure) belonging to an SpmiHotSet.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiHotVals *SpmiNextHot(HotSet, HotVals)
struct SpmiHotSet *HotSet;
struct SpmiHotVals *HotVals;

Description

The SpmiNextHot subroutine locates the next SpmiHotVals structure belonging to an SpmiHotSet, taking the set of peer statistics identified by the HotVals parameter as the current one. The subroutine returns a NULL value if no further SpmiHotVals structures are found. The SpmiNextHot subroutine should only be executed after a successful call to the SpmiGetHotSet subroutine and (usually, but not necessarily) a call to the SpmiFirstHot subroutine and one or more subsequent calls to SpmiNextHot.

The subroutine allows the application programmer to position at the next set of peer statistics in preparation for using the SpmiNextHotItem subroutine call to traverse this peer set's array of SpmiHotItems elements. Use of this subroutine is only necessary if it is desired to skip over some SpmiHotVals structores in an SpmiHotSet. Under most circumstances, the SpmiNextHotItem will be the sole means of accessing all elements of the SpmiHotItems arrays of all peer sets belonging to an SpmiHotSet.

Parameters

HotSet
Specifies a valid pointer to an SpmiHotSet structure as obtained by a previous SpmiCreateHotSet subroutine call.

HotVals
Specifies a pointer to an SpmiHotVals structure as returned by a previous SpmiFirstHot or SpmiNextHot subroutine call or as returned by an SpmiAddSetHot subroutine call.

Return Values

The SpmiNextHot subroutine returns a pointer to the next SpmiHotVals structure within the hotset. If no more SpmiHotVals structures are available, the subroutine returns a NULL value. A returned pointer may refer to a pseudo-hotvals structure as described in Programming Notes for the SpmiAddSetHot subroutine.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiFirstHot subroutine , SpmiGetHotSet subroutine , SpmiNextHotItem subroutine .

Data Access Structures and Handles, HotSets.


SpmiNextHotItem Subroutine

Purpose

Locates and decodes the next SpmiHotItems element at the current position in an SpmiHotSet.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiHotVals *SpmiNextHotItem(HotSet, HotVals, index, 
value, name)
struct SpmiHotSet *HotSet;
struct SpmiHotVals *HotVals;
int *index;
float *value;
char **name;

Description

The SpmiNextHotItem subroutine locates the next SpmiHotItems structure belonging to an SpmiHotSet, taking the element identified by the HotVals and index parameters as the current one. The subroutine returns a NULL value if no further SpmiHotItems structures are found. The SpmiNextHotItem subroutine should only be executed after a successful call to the SpmiGetHotSet subroutine.

The SpmiNextHotItem subroutine is designed to be used for walking all SpmiHotItems elements returned by a call to the SpmiGetHotSet subroutine, visiting the SpmiHotVals structures one by one. By feeding the returned value and the updated integer pointed to by index back to the next call, this can be done in a tight loop. Succesful calls to SpmiNextHotItem will decode each SpmiHotItems element and return the data value in value and the name of the peer context that owns the corresponding statistic in name.

Parameters

HotSet
Specifies a valid pointer to an SpmiHotSet structure as obtained by a previous SpmiCreateHotSet subroutine call.

HotVals
Specifies a pointer to an SpmiHotVals structure as returned by a previousSpmiNextHotItem, SpmiFirstHot, or SpmiNextHot subroutine call or as returned by an SpmiAddSetHot subroutine call. If this parameter is specified as NULL, the first SpmiHotVals structure of the SpmiHotSet is used and the index parameter is assumed to be set to zero, regardless of its actual value.

index
A pointer to an integer that contains the desired element number in the SpmiHotItems array of the SpmiHotVals structure specified by HotVals. A value of zero points to the first element. When the SpmiNextHotItem subroutine returns, the integer contain the index of the next SpmiHotItems element within the returned SpmiHotVals structure. If the last element of the array is decoded, the value in the integer will point beyond the end of the array, and the SpmiHotVals pointer returned will point to the peer set, which has now been completely decoded. By passing the returned SpmiHotVals pointer and the index parameter to the next call to SpmiNextHotItem, the subroutine will detect this and proceed to the first SpmiHotItems element of the next SpmiHotVals structure if one exists.

value
A pointer to a float variable. A successful call will return the decoded data value for the statistic. Before the value is returned, the SpmiNextHotItem function:

name
A pointer to a character pointer. A successful call will return a pointer to the name of the peer context for which the data value was read.

Return Values

The SpmiNextHotItem subroutine returns a pointer to the current SpmiHotVals structure within the hotset. If no more SpmiHotVals structures are available, the subroutine returns a NULL value. The structure returned contains the data, such as threshold, which may be relevant for presentation of the results of an SpmiGetHotSet subroutine call to end-users. A returned pointer may refer to a pseudo-hotvals structure as described in Programming Notes for the SpmiAddSetHot subroutine.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiFirstHot subroutine , SpmiNextHot subroutine , SpmiGetHotSet subroutine .

Data Access Structures and Handles, HotSets.


SpmiNextStat Subroutine

Purpose

Locates the next statistic belonging to a context.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiStatLink *SpmiNextStat(StatLink)
struct SpmiStatLink *StatLink;

Description

The SpmiNextStat subroutine locates the next statistic belonging to a context, taking the statistic identified by the StatLink parameter as the current statistic. The subroutine returns a NULL value if no further statistics are found.

The structure pointed to by the returned pointer contains an SpmiStatHdl handle to access the contents of the corresponding SpmiStat structure through the SpmiGetStat subroutine call.

Parameters

StatLink
Specifies a valid pointer to a SpmiStatLink structure as obtained by a previous SpmiFirstStat subroutine call.

Return Values

The SpmiNextStat subroutine returns a pointer to a structure of type SpmiStatLink if successful. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiFirstStat subroutine , SpmiGetStat subroutine .

Understanding SPMI Data Areas .

Understanding the SPMI Data Hierarchy.


SpmiNextVals Subroutine

Purpose

Returns a pointer to the next SpmiStatVals structure in a set of statistics.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiStatVals *SpmiNextVals(StatSet, StatVal)
struct SpmiStatSet *StatSet;
struct SpmiStatVals *StatVal;

Description

The SpmiNextVals subroutine returns a pointer to the next SpmiStatVals structure in a set of statistics, taking the structure identified by the StatVal parameter as the current structure. The SpmiStatVals structures are accessed in reverse order so the statistic added before the current one is returned. This subroutine call should only be issued after an SpmiGetStatSet subroutine has been issued against the statset.

Parameters

StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet subroutine call.

StatVal
Specifies a pointer to a valid structure of type SpmiStatVals as created by the SpmiPathAddSetStat subroutine call or returned by a previous SpmiFirstVals or SpmiNextVals subroutine call.

Return Values

The SpmiNextVals subroutine returns a pointer to a SpmiStatVals structure if successful. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiCreateStatSet subroutine , SpmiFirstVals subroutine , SpmiPathAddSetStat subroutine .

Data Access Structures and Handles, StatSets.


SpmiNextValue Subroutine

Purpose

Returns either the first SpmiStatVals structure in a set of statistics or the next SpmiStatVals structure in a set of statistics and a decoded value based on the type of data value extracted from the data field of an SpmiStatVals structure.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiStatVals*SpmiNextValue(StatSet, StatVal, 
value)
struct SpmiStatSet *StatSet;
struct SpmiStatVals *StatVal;
float *value;

Description

Instead of issuing subroutine calls to SpmiFirstVals/SpmiNextVals (to get the first or next SpmiStatVals structure) followed by calls to SpmiGetValue (to get the decoded value from the SpmiStatVals structure), the SpmiNextValue subroutine returns both in one call. This subroutine call returns a pointer to the first SpmiStatVals structure belonging to the StatSet parameter if the StatVal parameter is NULL. If the StatVal partameter is not NULL, the next SpmiStatVals structure is returned, taking the structure identified by the StatVal parameter as the current structure. The data value corresponding to the returned SpmiStatVals structure is decoded and returned in the field pointed to by the value argument. In decoding the data value, the subroutine does the following:

Note: This subroutine call should only be issued after an SpmiGetStatSet subroutine has been issued against the statset.

Parameters

StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet subroutine call.

StatVal
Specifies either a NULL pointer or a pointer to a valid structure of type SpmiStatVals as created by the SpmiPathAddSetStat subroutine call or returned by a previous SpmiNextValue subroutine call. If StatVal is NULL, then the first SpmiStatVals pointer belonging to the set of statistics pointed to by StatSet is returned.

value
A pointer used to return a decoded value based on the type of data value extracted from the data field of the returned SpmiStatVals structure.

Return Value

The SpmiNextValue subroutine returns a pointer to a SpmiStatVals structure if successful. If unsuccessful, the subroutine returns a NULL value.

If the StatVal parameter is:

NULL
The first SpmiStatVals structure belonging to the StatSet parameter is returned.

not NULL
The next SpmiStatVals structure after the structure identified by the StatVal parameter is returned and the value parameter is used to return a decoded value based on the type of data value extracted from the data field of the returned SpmiStatVals structure.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Programming Notes

The SpmiNextValue subroutine maintains internal state information so that retrieval of the next data value from a statset can be done without traversing linked lists of data structures. The stats information is kept separate for each process, but is shared by all threads of a process.

If the subroutine is accessed from multiple threads, the state information is useless and the performance advantage is lost. The same is true if the program is simultaneously accessing two or more statsets. To benefit from the performance advantage of the SpmiNextValue subroutine, a program should retrieve all values in order from one stat set before retrieving values from the next statset.

The implementation of the subroutine allows a program to retrieve data values beginning at any point in the statset if the SpmiStatVals pointer is known. Doing so will cause a linked list traversal. If subsequent invocations of SpmiNextValue uses the value returned from the first and following invocation as their second argument, the traversal of the link list can be avoided.

It should be noted that the value returned by a successful SpmiNextValue invocation is always the pointer to the SpmiStatVals structure whose data value is decoded and returned in the value argument.

Implementation Specifics

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiGetStatSet subroutine , SpmiCreateStatSet subroutine , SpmiPathAddSetStat subroutine .

Data Access Structures and Handles, StatSets.


SpmiPathAddSetStat Subroutine

Purpose

Adds a statistics value to a set of statistics.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
struct SpmiStatVals *SpmiPathAddSetStat(StatSet, StatName, 
Parent)
struct SpmiStatSet *StatSet;
char *StatName;
SpmiCxHdl Parent;

Description

The SpmiPathAddSetStat subroutine adds a statistics value to a set of statistics. The SpmiStatSet structure that provides the anchor point to the set must exist before the SpmiPathAddSetStat subroutine call can succeed.

Parameters

StatSet
Specifies a pointer to a valid structure of type SpmiStatSet as created by the SpmiCreateStatSet subroutine call.

StatName
Specifies the name of the statistic within the context identified by the Parent parameter.If the Parent parameter is NULL, you must specify the fully qualified path name of the statistic in the StatName parameter.

Parent
Specifies either a valid SpmiCxHdl handle as obtained by another subroutine call or a NULL value.

Return Values

The SpmiPathAddSetStat subroutine returns a pointer to a structure of type SpmiStatVals if successful. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

The SpmiGetStatSet subroutine , SpmiCreateStatSet subroutine , SpmiDelSetStat subroutine , SpmiFreeStatSet subroutine .

Data Access Structures and Handles, StatSets.


SpmiPathGetCx Subroutine

Purpose

Returns a handle to use when referencing a context.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
SpmiCxHdl SpmiPathGetCx(CxPath, Parent)
char *CxPath;
SpmiCxHdl Parent;

Description

The SpmiPathGetCx subroutine searches the context hierarchy for a given path name of a context and returns a handle to use when subsequently referencing the context.

Parameters

CxPath
Specifies the path name of the context to find. If you specify the fully qualified path name in the CxPath parameter, you must set the Parent parameter to NULL. If the path name is not qualified or is only partly qualified (that is, if it does not include the names of all contexts higher in the data hierarchy), the SpmiPathGetCx subroutine begins searching the hierarchy at the context identified by the Parent parameter. If the CxPath parameter is either NULL or an empty string, the subroutine returns a handle identifying the Top context.

Parent
Specifies the anchor context that fully qualifies the CxPath parameter. If you specify a fully qualified path name in the CxPath parameter, you must set the Parent parameter to NULL.

Return Values

The SpmiPathGetCx subroutine returns a handle to a context if successful. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

Understanding SPMI Data Areas .

Understanding the SPMI Data Hierarchy.


SpmiStatGetPath Subroutine

Purpose

Returns the full path name of a statistic.

Library

SPMI Library (libSpmi.a)

Syntax

#include <sys/Spmidef.h>
char *SpmiStatGetPath(Parent, StatHandle, MaxLevels)
SpmiCxHdl Parent;
SpmiStatHdl StatHandle;
int MaxLevels;

Description

The SpmiStatGetPath subroutine returns the full path name of a statistic, given a parent context SpmiCxHdl handle and a statistics SpmiStatHdl handle. The MaxLevels parameter can limit the number of levels in the hierarchy that must be searched to generate the path name of the statistic.

The memory area pointed to by the returned pointer is freed when the SpmiStatGetPath subroutine call is repeated. For each invocation of the subroutine, a new memory area is allocated and its address returned.If the calling program needs the returned character string after issuing the SpmiStatGetPath subroutine call, the program must copy the returned string to locally allocated memory before reissuing the subroutine call.

Parameters

Parent
Specifies a valid SpmiCxHdl handle as obtained by another subroutine call.

StatHandle
Specifies a valid SpmiStatHdl handle as obtained by another subroutine call. This handle must point to a statistic belonging to the context identified by the Parent parameter.

MaxLevels
Limits the number of levels in the hierarchy that must be searched to generate the path name. If this parameter is set to 0, no limit is imposed.

Return Values

If successful, the SpmiStatGetPath subroutine returns a pointer to a character array containing the full path name of the statistic. If unsuccessful, the subroutine returns a NULL value.

Error Codes

All SPMI subroutines use external variables to provide error information. To access these variables, an application program must define the following external variables:

If the subroutine returns without an error, the SpmiErrno variable is set to 0 and the SpmiErrmsg character array is empty. If an error is detected, the SpmiErrno variable returns an error code, as defined in the sys/Spmidef.h file, and the SpmiErrmsg variable contains text, in English, explaining the cause of the error. See the List of SPMI Error Codes for more information.

Implementation Specifics

This subroutine is part of the server option of the Performance Aide for AIX licensed product and is also included in the Performance Toolbox for AIX licensed product.

Files

/usr/include/sys/Spmidef.h
Declares the subroutines, data structures, handles, and macros that an application program can use to access the SPMI.

Related Information

Understanding SPMI Data Areas .

Understanding the SPMI Data Hierarchy.


[ Previous | Next | Contents | Glossary | Search ]