/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* perf720 src/perf/perfagent/usr/samples/perfagent/server/SpmiPeek.c 1.4 */ /* */ /* */ /* */ /* OBJECT CODE ONLY SOURCE MATERIALS */ /* */ /* COPYRIGHT International Business Machines Corp. 1992,1993 */ /* All Rights Reserved */ /* */ /* The source code for this program is not published or otherwise */ /* divested of its trade secrets, irrespective of what has been */ /* deposited with the U.S. Copyright Office. */ /* */ /* IBM_PROLOG_END_TAG */ /* * COMPONENT_NAME: PERFAGENT * * FUNCTIONS: findstats * lststats * main * * ORIGINS: 30 * * * (C) COPYRIGHT International Business Machines Corp. 1992,1993 * All Rights Reserved * Licensed Materials - Property of IBM * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. * * NOTICE TO USERS OF THE SOURCE CODE EXAMPLES * * THE SOURCE CODE EXAMPLES PROVIDED BY IBM ARE ONLY INTENDED TO ASSIST IN THE * DEVELOPMENT OF A WORKING SOFTWARE PROGRAM. THE SOURCE CODE EXAMPLES DO NOT * FUNCTION AS WRITTEN: ADDITIONAL CODE IS REQUIRED. IN ADDITION, THE SOURCE * CODE EXAMPLES MAY NOT COMPILE AND/OR BIND SUCCESSFULLY AS WRITTEN. * * INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THE SOURCE CODE * EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS, "AS IS" WITHOUT * WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE * OF THE SOURCE CODE EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS, * IS WITH YOU. SHOULD ANY PART OF THE SOURCE CODE EXAMPLES PROVE * DEFECTIVE, YOU (AND NOT IBM OR AN AUTHORIZED RISC System/6000* WORKSTATION * DEALER) ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR * CORRECTION. * * IBM does not warrant that the contents of the source code examples, whether * individually or as one or more groups, will meet your requirements or that * the source code examples are error-free. * * IBM may make improvements and/or changes in the source code examples at * any time. * * Changes may be made periodically to the information in the source code * examples; these changes may be reported, for the sample device drivers * included herein, in new editions of the examples. * * References in the source code examples to IBM products, programs, or * services do not imply that IBM intends to make these available in all * countries in which IBM operates. Any reference to an IBM licensed * program in the source code examples is not intended to state or imply * that only IBM's licensed program may be used. Any functionally equivalent * program may be used. * * RISC System/6000 is a trademark of International Business Machines * Corporation. * */ static char *Sccs_id = "@(#)18 1.3 src/perf/perfagent/usr/samples/perfagent/server/SpmiPeek.c, perfagent, perf411, 9430C411a 7/29/94 17:32:53"; /* EXECUTION NOTES: * SpmiPeek is a sample program. If SpmiPeek is invoked without any options, * information about the statistics and contexts are output to the screen. * * The output will look similar to the following: * CPU Central processor statistics * CPU/cpu0 Central processor #0 * CPU/cpu0/user Time executing in user mode (percent) * Data Type(Float) Value Type(Quantity) * min = 0 max = 100 * CPU/cpu0/kern Time executing in kernel mode (percent) * Data Type(Float) Value Type(Quantity) * min = 0 max = 100 * Mem Memory statistics * Mem/Real Physical memory statistics * Mem/Real/size Size of physical memory (4K pages) * Data Type(Long) Value Type(Quantity) * min = 0 max = 20000 * * SpmiPeek has one option (-l). This option will only display a list of * the statistics name. No information is displayed about these stats. * This list can be re-directed to an output file, and then used as input * to the SpmiLogger program. The SpmiLogger program only takes a maximum of * 28 statistics, so the user will need to modify the SpmiLogger input file. */ #include #include #include #include extern char SpmiErrmsg[]; /* Error Msg array */ extern int SpmiErrno; /* Error Number */ char stats[256]; /* statistic name info */ char cxt[256]; /* context name info */ char subcxt[256]; /* text holder */ char *blanks=" "; char *blank2=" "; int instantiable=0; int listflag=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. */ /*=========================================================================*/ #ifdef _NO_PROTO void findstats(cxhdl) SpmiCxHdl cxhdl; #else void findstats(SpmiCxHdl cxhdl) #endif { 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 (spmicx == NULL) { printf("ERROR: SpmiGetCx Failed\n"); if (strlen(SpmiErrmsg)) printf("%s\n", SpmiErrmsg); exit(-1); } /* if the subcxt is a child of another context */ if (!subcxt[0]) { 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 == NULL) { printf("ERROR: SpmiGetCx Failed\n"); if (strlen(SpmiErrmsg)) printf("%s\n", SpmiErrmsg); exit(-1); } 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); } if (!listflag) printf("%s\n",cxt); /* Traverse the stats list for the context */ if (statlink = SpmiFirstStat(cxlink->context)) { while (statlink) { spmistat = SpmiGetStat(statlink->stat); if (spmistat == NULL) { printf("ERROR: SpmiGetStat Failed\n"); if (strlen(SpmiErrmsg)) printf("%s\n", SpmiErrmsg); exit(-1); } statname = SpmiStatGetPath(cxlink->context, statlink->stat, 10); if (statname == NULL) { printf("ERROR: SpmiStatGetPath Failed\n"); if (strlen(SpmiErrmsg)) printf("%s\n", SpmiErrmsg); exit(-1); } /* output statistic name */ strcpy(stats, statname); if (!listflag) { descplace = strlen(stats); descplace = 40 - descplace; strncat(stats, blanks,descplace); strcat(stats, spmistat->description); } printf("%s\n",stats); /* output stat info */ if (!listflag) { 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)"); printf("%s%s\n", blank2, stats); /* output max/min info */ sprintf(num_string,"min = %ld max = %ld", spmistat->min, spmistat->max); strcpy(stats, num_string); printf("%s%s\n", blank2, stats); } /* Go to next statistic */ statlink = SpmiNextStat(statlink); } /* end while(statlink) */ } /* end if (statlink) */ } /* end if (instantiable) */ else { /* print out stat name info for stats with */ /* instantiable parents */ if (!listflag) { strcpy(cxt, spmicxparent->name); strcat(cxt, "/"); strcat(cxt, spmicx->name); strcat(cxt, "/....."); cxtlen1 = strlen(spmicx->name) + 6; printf("%s\n", cxt); } } /* recursive call to function */ /* this gets the next context link */ findstats(cxlink->context); if (cxtlen2 == cxtlen1) subcxt[0] = '\0'; else subcxt[cxtlen2-cxtlen1-1] = '\0'; /* 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; if ((cxhdl = SpmiPathGetCx(NULL, NULL)) == NULL) { printf("ERROR: SpmiPathGetCx Failed.\n"); if (strlen(SpmiErrmsg)) printf("%s", SpmiErrmsg); return; } /* routine to traverse the context links */ findstats(cxhdl); return; } /*================================ main() ============================*/ #ifdef _NO_PROTO main(argc, argv) int argc; char **argv; #else main(int argc, char **argv) #endif { int spmierr = 0; int errflag = 0; int c; while ((c = getopt(argc, argv, "l")) != EOF) { switch (c) { case 'l': listflag++; break; case '?': errflag++; break; } } if (errflag) { printf("Usage: SpmiPeek [-l ]\n"); printf(" Flags: -l Generates a statistics list.\n"); exit(0); } /* Initialize SPMI interface */ if ((spmierr = SpmiInit(15)) != 0) { printf("ERROR: SpmiInit Failed\n"); if (strlen(SpmiErrmsg)) printf("%s", SpmiErrmsg); exit(-98); } /* Traversal routine. */ lststats(); /* Exit SPMI Interface */ SpmiExit(); if (SpmiErrno) { printf("ERROR: SpmiExit Failed.\n"); if (strlen(SpmiErrmsg)) printf("%s", SpmiErrmsg); } exit(0); }