42 #define AGENT_NAME "perfevent" 46 #undef PACKAGE_BUGREPORT 47 #undef PACKAGE_TARNAME 50 #undef PACKAGE_VERSION 52 #include <pcp/pmapi.h> 55 #define MYPCPLIB "libpcp.so" // Name of my PCP library. 57 #define PM_OPTFLAG_EXIT (1<<5) 58 #define PM_CONTEXT_UNDEF -1 59 #define PM_CONTEXT_HOST 1 60 #define PM_CONTEXT_ARCHIVE 2 61 #define PM_CONTEXT_LOCAL 3 73 unsigned long long *ullPtr;
82 unsigned long long ull;
91 typedef struct _pcp_register
102 typedef struct _pcp_event_info
120 typedef struct _pcp_reg_alloc
135 typedef struct _pcp_control_state
147 typedef struct _pcp_context
158 typedef struct _pcp_hash
191 #define HASH_SIZE 512 194 #define COUNT_ROUTINES 1 195 #if (COUNT_ROUTINES == 1) 217 #define mRtnCnt(funcname) \ 218 if (COUNT_ROUTINES) { \ 219 cnt[ctr##funcname]++; \ 220 if (cnt[ctr##funcname] == 1) \ 221 _prog_fprintf(stderr, "Entered " TOSTRING(funcname) "\n"); \ 224 #define mRtnCnt(funcname) 236 #define mConvertUsec(timeval_) \ 237 (timeval_.tv_sec*1000000+timeval_.tv_usec) 239 #define _prog_fprintf if (0) fprintf 240 #define _time_fprintf if (0) fprintf 241 #define _time_gettimeofday if (0) gettimeofday 258 static int (*pmLookupName_ptr) (
int numpid,
char **namelist,pmID *pmidlist);
259 static char* (*pmErrStr_ptr) (
int code);
260 static int (*pmTraversePMNS_ptr) (
const char *
name, void(*
func)(
const char *));
261 void (*pmFreeResult_ptr) (pmResult *result);
262 static int (*pmNewContext_ptr) (
int type,
const char *
name);
263 static int (*pmDestroyContext_ptr) (
int handle);
264 static int (*pmFetch_ptr) (
int numpid, pmID *pmidlist, pmResult **result);
265 static int (*pmLookupDesc_ptr) (pmID pmid, pmDesc *desc);
266 static int (*pmGetInDom_ptr) (pmInDom indom,
int **instlist,
char ***namelist);
267 static int (*pmLookupText_ptr) (pmID pmid,
int level,
char **
buffer);
268 static char * (*pmUnitsStr_r_ptr) (
const pmUnits *pu,
char *
buf,
int buflen);
271 static int pcp_pmLookupName (
int numpid,
char **namelist, pmID *pmidlist)
272 {
return ((*pmLookupName_ptr) (numpid, namelist, pmidlist)); }
275 {
return ((*pmErrStr_ptr) (code)); }
278 {
return ((*pmTraversePMNS_ptr) (
name,
func)); }
281 {
return ((*pmFreeResult_ptr) (result)); }
284 {
return ((*pmNewContext_ptr) (type,
name)); }
287 {
return ((*pmDestroyContext_ptr) (handle));}
289 static int pcp_pmFetch (
int numpid, pmID *pmidlist, pmResult **result)
290 {
return ((*pmFetch_ptr) (numpid,pmidlist,result)); }
293 {
return ((*pmLookupDesc_ptr) (pmid,desc)); }
296 {
return ((*pmGetInDom_ptr) (indom,instlist,namelist)); }
299 {
return ((*pmLookupText_ptr) (pmid, level,
buffer)); }
302 {
return ((*pmUnitsStr_r_ptr) (pu,
buf, buflen)); }
315 unsigned long hash = 5381;
317 while ((
c = (*str++))) {
318 hash = ((hash << 5) + hash) +
c;
321 return (hash % tableSize);
356 while (next != NULL) {
375 if (idx < 0)
return(-1);
382 while (next != NULL) {
400 #define mCheck_DL_Status( err, str ) \ 403 strncpy(_pcp_vector.cmp_info.disabled_reason, str, PAPI_MAX_STR_LEN-1); \ 404 return (PAPI_ENOSUPP ); \ 412 #define STRINGIFY(x) #x 413 #define TOSTRING(x) STRINGIFY(x) 414 #define mGet_DL_FPtr(Name) \ 415 Name##_ptr = dlsym(dllib1, TOSTRING(Name)); \ 416 mCheck_DL_Status(dlerror()!=NULL, "PCP library function " \ 417 TOSTRING(Name) " not found in " MYPCPLIB "."); 453 int qsPMID(
const void *arg1,
const void* arg2)
458 if (p1->
pmid < p2->
pmid)
return (-1);
459 if (p1->
pmid > p2->
pmid)
return ( 1);
460 if (p1->
idx < p2->
idx )
return (-1);
461 if (p1->
idx > p2->
idx )
return ( 1);
462 return (strcmp(p1->
name, p2->
name));
504 fprintf(stderr,
"%s:%i:%s realloc denied; " 505 "pcp_event_info=%p at size=%i.\n",
506 __FILE__, __LINE__, __func__,
544 if (
ret == PM_ERR_PMID) {
545 fprintf(stderr,
"%s:%i:%s Invalid PMID.\n",
546 __FILE__, __LINE__, __func__);
550 if (
ret == PM_ERR_NOAGENT) {
551 fprintf(stderr,
"%s:%i:%s PMDA Agent not available to respond..\n",
552 __FILE__, __LINE__, __func__);
557 fprintf(stderr,
"%s:%i:%s Unknown error code ret=%i.\n",
558 __FILE__, __LINE__, __func__,
ret);
577 static int domains=0;
582 if (cachedDomains == NULL)
return(NULL);
583 for (
i=0;
i<domains;
i++) {
584 free(cachedDomains[
i].instances);
585 free(cachedDomains[
i].
names);
590 cachedDomains = NULL;
595 for (
i=0;
i<domains;
i++) {
596 if (indom == cachedDomains[
i].domainId)
break;
606 cachedDomains = realloc(cachedDomains,
610 if (cachedDomains == NULL) {
611 fprintf(stderr,
"%s:%i:%s malloc/realloc denied for " 612 "cachedDomains; size=%i.\n",
613 __FILE__, __LINE__, __func__, domains);
617 cachedDomains[domIdx].
domainId = indom;
619 &cachedDomains[domIdx].instances,
620 &cachedDomains[domIdx].
names);
622 if (cachedDomains[domIdx].
names[
i] == NULL ||
623 strlen(cachedDomains[domIdx].
names[
i]) == 0 ||
625 fprintf(stderr,
"%s:%i:%s ERROR: cachedGetInDom: domain=%u, domIdx=%i, name idx %i invalid string.\n",
626 __FILE__, __LINE__,
FUNC, indom, domIdx,
i);
636 if (cachedDomains[domIdx].instances[
i] == inst)
637 return cachedDomains[domIdx].
names[
i];
640 fprintf(stderr,
"%s:%i:%s ERROR: cachedGetInDom: domain=%u, domIdx=%i, numInstances=%i, failed to find inst=%i.\n",
641 __FILE__, __LINE__,
FUNC, indom, domIdx, cachedDomains[domIdx].numInstances, inst);
654 unsigned long long value;
658 if (vset->valfmt == PM_VAL_INSITU) {
659 convert.
ll = vset->vlist[value_index].value.lval;
662 pmValueBlock *pmvb = vset->vlist[value_index].value.pval;
663 myPtr.
cPtr = pmvb->vbuf;
664 switch (pmvb->vtype) {
666 convert.
ll = myPtr.
iPtr[0];
671 value = myPtr.
uiPtr[0];
684 convert.
d = myPtr.
fPtr[0];
689 convert.
d = myPtr.
dPtr[0];
699 fprintf(stderr,
"%s:%i pmValueBlock (from PCP) contains an unrecognized value type=%i.\n",
700 __FILE__, __LINE__, pmvb->vtype);
737 rawval.
ll -= zero.
ll;
754 fprintf(stderr,
"%s:%i pcp_event_info[%s] contains an unrecognized value type=%i.\n",
782 char errMsg[]=
"Help Text is not available for this event.";
787 if (*helpText != NULL) free(*helpText);
792 if (
ret == PM_ERR_TEXT) {
793 *helpText = strdup(errMsg);
794 }
else if (
ret != 0) {
795 fprintf(stderr,
"%s:%i:%s pmLookupText failed; return=%s.\n",
801 for (p=(*helpText); p[0] != 0; p++) {
802 if (p[0] ==
'\n') p[0] =
'|';
827 #define hostnameLen 512 833 snprintf(reason, rLen,
"Failed attempt to link to PCP " 840 snprintf(reason, rLen,
"Failed system call, gethostname() " 841 "returned %i.",
ret);
846 _prog_fprintf(stderr,
"%s:%i retrieved hostname='%s'\n", __FILE__, __LINE__, hostname);
850 snprintf(reason, rLen,
"Cannot connect to PM Daemon on host \"%s\".\n " 851 "(Ensure this machine has Performance Co-Pilot installed.)\n", hostname);
865 snprintf(reason, rLen,
"pmTraversePMNS failed; ret=%i [%s]\n",
867 if (
ret == PM_ERR_NAME) {
868 snprintf(reason, rLen,
"pmTraversePMNS ret=PM_ERR_NAME: " 869 "Occurs if event filter '%s' unknown to PCP Daemon.\n",
AGENT_NAME);
876 _time_fprintf(stderr,
"pmTraversePMNS PopulateNameOnly took %li uS.\n",
878 _time_fprintf(stderr,
"Final sEventCount=%i, sEventInfoSize=%i, " 879 "sEventInfoBlock=%i.\n",
883 snprintf(reason, rLen,
"pmTraversePMNS returned zero events " 889 char **allNames=calloc(
sEventCount,
sizeof(
char*));
895 if (allPMID == NULL) {
896 snprintf(reason, rLen,
"memory alloc denied for allPMID; " 917 ret = pcp_pmLookupName(j, allNames+
i, allPMID+
i);
919 snprintf(reason, rLen,
"pmLookupName for %i names failed; ret=%i [%s].\n",
921 if (
ret == PM_ERR_IPC) {
922 snprintf(reason, rLen,
"pmLookupName ret=PM_ERR_IPC: one known cause is a readblock too large; reduce LNBLOCK (%s:%i).\n",
935 _time_fprintf(stderr,
"pmLookupName for all took %li uS, ret=%i.\n",
940 pmResult *allFetch = NULL;
944 _time_fprintf(stderr,
"pmFetch for all took %li uS, for %i events; ret=%i.\n",
960 for (
i=0;
i<origEventCount;
i++) {
962 pmValueSet *vset = allFetch->vset[
i];
966 fprintf(stderr,
"%s:%i vset=NULL for name='%s'\n",
972 if (vset->numval == 0) {
979 unsigned long long ullval= (
long long) -1;
982 if (vset->valfmt != PM_VAL_INSITU) {
983 pmValue *pmval = &vset->vlist[0];
984 pmValueBlock *pB = pmval->value.pval;
986 snprintf(reason, rLen,
"Disagreement between var descriptor and fetch on event %s. %i vs %i. Possible version incompatibiity.\n",
1006 convert.
ull = ullval;
1012 case PM_TYPE_DOUBLE:
1013 convert.
ull = ullval;
1025 case PM_TYPE_STRING:
1040 convert.
ull = ullval;
1041 _prog_fprintf(stderr,
"%02X%02X%02X%02X %02X%02X%02X%02X\n", convert.
ch[0], convert.
ch[1], convert.
ch[2], convert.
ch[3], convert.
ch[4], convert.
ch[5], convert.
ch[6], convert.
ch[7]);
1050 for (j=0; j<vset->numval; j++) {
1051 pmValue *pmval = &vset->vlist[j];
1081 snprintf(reason, rLen,
"memory realloc denied for " 1090 _time_fprintf(stderr,
"indexedExplosion for all took %li uS.\n",
1098 unsigned int myHash;
1108 unsigned int current, prev=0;
1109 printf(
"count, hash, name, pmid, value[idx]\n");
1113 if (prev > 0 && current != (prev+1) && current != prev)
1114 printf(
"----,----,----,----\n");
1115 printf(
"%i, %u, \"%s\", 0x%08X, %i\n",
i, myHash,
1127 if (
f !=
i) hashErr++;
1247 #define BlockSize 64 1254 newalloc*
sizeof(
int));
1256 newalloc*
sizeof(
long long));
1317 pmID *allPMID=malloc((myCtl->
numEvents)*
sizeof(pmID));
1332 for (j=0; j<nPMID; j++) {
1333 if (myPMID == allPMID[j])
break;
1337 allPMID[nPMID++] = myPMID;
1342 pmResult *allFetch = NULL;
1344 *results = allFetch;
1347 fprintf(stderr,
"%s:%i:%s pcp_pmFetch failed, return=%s.\n",
1349 if (allPMID != NULL) free(allPMID);
1359 for (
i=0;
i<nPMID;
i++) {
1360 pmValueSet *vset = allFetch->vset[
i];
1361 pmID myPMID = allPMID[
i];
1370 if (thisPMID == myPMID) {
1377 if (allPMID != NULL) free(allPMID);
1390 unsigned long long aValue;
1397 fprintf(stderr,
"%s:%i:%s PCP_ReadList failed, return=%s.\n",
1458 fprintf(stderr,
"%s:%i:%s 'events' is null.\n",
1459 __FILE__, __LINE__,
FUNC);
1465 fprintf(stderr,
"%s:%i:%s PCP_ReadList failed, return=%s.\n",
1576 fprintf(stderr,
"%s:%i:%s CODE 0x%08x IS INVALID " 1577 "OR UNRECOGNIZED.\n", __FILE__, __LINE__,
FUNC, code);
1652 if (
name == NULL || strlen(
name)<1) {
1653 fprintf(stderr,
"%s:%i:%s Invalid name.\n",
1654 __FILE__, __LINE__,
FUNC);
1658 if (event_code == NULL) {
1659 fprintf(stderr,
"%s:%i:%s event_code is not a valid pointer.\n",
1660 __FILE__, __LINE__,
FUNC);
1666 fprintf(stderr,
"%s:%i:%s Failed to find name='%s', hash=%i.\n",
1687 fprintf(stderr,
"%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1688 __FILE__, __LINE__,
FUNC, pcpIdx);
1693 fprintf(stderr,
"%s:%i:%s called with out-of-range descr len=%i.\n",
1694 __FILE__, __LINE__,
FUNC, len);
1716 fprintf(stderr,
"%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1717 __FILE__, __LINE__,
FUNC, pcpIdx);
1722 fprintf(stderr,
"%s:%i:%s called with out-of-range descr len=%i.\n",
1723 __FILE__, __LINE__,
FUNC, len);
1727 char *helpText = NULL;
1730 if (helpText != NULL) free(helpText);
1731 fprintf(stderr,
"%s:%i:%s failed getHelpText; it returned %s.\n",
1736 strncpy(descr, helpText, len);
1770 fprintf(stderr,
"%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1771 __FILE__, __LINE__,
FUNC, pcpIdx);
1775 len=
sizeof(info->
symbol);
1793 if ( strlen(unitStr) == 0) {
1794 sprintf(unitStr,
"fraction");
1798 sprintf(unitStr,
"[%u, %i, %u, %u, %i, %i, %i]",
1810 len =
sizeof(info->
units);
1811 strncpy( info->
units, unitStr, len);
1812 info->
units[len-1] = 0;
1823 case PM_TYPE_STRING:
1828 case PM_TYPE_DOUBLE:
1851 .short_name =
"pcp",
1852 .description =
"Performance Co-Pilot",
static int _pcp_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
static int pcp_pmGetInDom(pmInDom indom, int **instlist, char ***namelist)
void getPMDesc(int pcpIdx)
static int sEventInfoSize
char disabled_reason[PAPI_MAX_STR_LEN]
_papi_int_inherit_t inherit
void subZero(_pcp_control_state_t *myCtl, int event)
#define mGet_DL_FPtr(Name)
unsigned long long * ullPtr
unsigned int addNameHash(char *key, int idx)
char units[PAPI_MIN_STR_LEN]
static int _pcp_init_thread(hwd_context_t *ctx)
unsigned long long zeroValue
static char * cachedGetInDom(pmInDom indom, int inst)
static _pcp_hash_t sNameHash[HASH_SIZE]
unsigned int stringHash(char *str, unsigned int tableSize)
char long_descr[PAPI_HUGE_STR_LEN]
static int _pcp_ntv_code_to_info(unsigned int pcpIdx, PAPI_event_info_t *info)
#define mRtnCnt(funcname)
PAPI_component_info_t cmp_info
static struct timeval t1 t2
static int pcp_pmNewContext(int type, const char *name)
#define mCheck_DL_Status(err, str)
static int sEventInfoBlock
static int _pcp_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _pcp_ntv_code_to_name(unsigned int pcpIdx, char *name, int len)
static int _pcp_set_domain(hwd_control_state_t *ctl, int domain)
static int _pcp_shutdown_component(void)
static int _pcp_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int pcp_pmFetch(int numpid, pmID *pmidlist, pmResult **result)
Return codes and api definitions.
static int pcp_pmDestroyContext(int handle)
char events[MAX_EVENTS][BUFSIZ]
void cbPopulateNameOnly(const char *name)
static int _pcp_shutdown_thread(hwd_context_t *ctx)
static _pcp_event_info_t * pcp_event_info
void(* _dl_non_dynamic_init)(void)
char symbol[PAPI_HUGE_STR_LEN]
static char * pcp_pmErrStr(int code)
static char * pcp_pmUnitsStr_r(const pmUnits *pu, char *buf, int buflen)
__attribute__((constructor))
static int _pcp_init_control_state(hwd_control_state_t *ctl)
int findNameHash(char *key)
static int _pcp_ntv_name_to_code(const char *name, unsigned int *event_code)
#define SUBDBG(format, args...)
_papi_int_granularity_t granularity
static int pcp_pmTraversePMNS(const char *name, void(*func)(const char *))
static int _pcp_ntv_enum_events(unsigned int *EventCode, int modifier)
char name[PAPI_MAX_STR_LEN]
int cnt[ctr_pcp_ntv_code_to_info+1]
static int _pcp_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
static int _pcp_init_component(int cidx)
#define _time_gettimeofday
static int _pcp_ntv_code_to_descr(unsigned int pcpIdx, char *descr, int len)
#define mConvertUsec(timeval_)
char * PAPI_strerror(int errorCode)
static int _pcp_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
static int pcp_pmLookupText(pmID pmid, int level, char **buffer)
#define PAPI_NATIVE_AND_MASK
void pcp_pmFreeResult(pmResult *result)
struct papi_vectors * _papi_hwd[]
static int pcp_pmLookupDesc(pmID pmid, pmDesc *desc)
static int _pcp_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
_papi_int_domain_t domain
int qsPMID(const void *arg1, const void *arg2)
char name[PAPI_MAX_STR_LEN]
papi_vector_t _pcp_vector
void makeQualifiedEvent(int baseEvent, int idx, char *qualifier)
volatile int buf[CACHE_FLUSH_BUFFER_SIZE_INTS]
const char * names[NUM_EVENTS]
int getHelpText(unsigned int pcpIdx, char **helpText)
unsigned long long * pcpValue
int PCP_ReadList(hwd_control_state_t *ctl, pmResult **results)
unsigned long long getULLValue(pmValueSet *vset, int value_index)
int _local_linkDynamicLibraries(void)