42 #define AGENT_NAME "perfevent"
46#undef PACKAGE_BUGREPORT
56#define PM_OPTFLAG_EXIT (1<<5)
57#define PM_CONTEXT_UNDEF -1
58#define PM_CONTEXT_HOST 1
59#define PM_CONTEXT_ARCHIVE 2
60#define PM_CONTEXT_LOCAL 3
65#define HANDLE_STRING_ERROR {fprintf(stderr,"%s:%i unexpected string function error.\n",__FILE__,__LINE__); exit(-1);}
77 unsigned long long *ullPtr;
86 unsigned long long ull;
95typedef struct _pcp_register
106typedef struct _pcp_event_info
124typedef struct _pcp_reg_alloc
139typedef struct _pcp_control_state
151typedef struct _pcp_context
162typedef struct _pcp_hash
197#define COUNT_ROUTINES 1
198#if (COUNT_ROUTINES == 1)
201ctr_pcp_init_component,
202ctr_pcp_init_control_state,
206ctr_pcp_shutdown_thread,
207ctr_pcp_shutdown_component,
209ctr_pcp_update_control_state,
212ctr_pcp_ntv_enum_events,
213ctr_pcp_ntv_name_to_code,
214ctr_pcp_ntv_code_to_name,
215ctr_pcp_ntv_code_to_descr,
216ctr_pcp_ntv_code_to_info};
218static int cnt[ctr_pcp_ntv_code_to_info+1] = {0};
220#define mRtnCnt(funcname) \
221 if (COUNT_ROUTINES) { \
222 cnt[ctr##funcname]++; \
223 if (cnt[ctr##funcname] == 1) \
224 _prog_fprintf(stderr, "Entered " TOSTRING(funcname) "\n"); \
227#define mRtnCnt(funcname)
239#define mConvertUsec(timeval_) \
240 (timeval_.tv_sec*1000000+timeval_.tv_usec)
242#define _prog_fprintf if (0) fprintf
243#define _time_fprintf if (0) fprintf
244#define _time_gettimeofday if (0) gettimeofday
265static int (*pmLookupName_ptr) (
int numpid,
char **namelist,pmID *pmidlist);
266static char* (*pmErrStr_ptr) (
int code);
267static int (*pmTraversePMNS_ptr) (
const char *
name, void(*func)(
const char *));
268static void (*pmFreeResult_ptr) (pmResult *
result);
269static int (*pmNewContext_ptr) (
int type,
const char *
name);
270static int (*pmDestroyContext_ptr) (
int handle);
271static int (*pmFetch_ptr) (
int numpid, pmID *pmidlist, pmResult **
result);
272static int (*pmLookupDesc_ptr) (pmID pmid, pmDesc *desc);
273static int (*pmGetInDom_ptr) (pmInDom indom,
int **instlist,
char ***namelist);
274static int (*pmLookupText_ptr) (pmID pmid,
int level,
char **buffer);
275static char * (*pmUnitsStr_r_ptr) (
const pmUnits *pu,
char *
buf,
int buflen);
278static int pcp_pmLookupName (
int numpid,
char **namelist, pmID *pmidlist)
279 {
return ((*pmLookupName_ptr) (numpid, namelist, pmidlist)); }
282 {
return ((*pmErrStr_ptr) (code)); }
285 {
return ((*pmTraversePMNS_ptr) (
name, func)); }
288 {(*pmFreeResult_ptr) (
result);
return;}
291 {
return ((*pmNewContext_ptr) (
type,
name)); }
294 {
return ((*pmDestroyContext_ptr) (
handle));}
297 {
return ((*pmFetch_ptr) (numpid,pmidlist,
result)); }
300 {
return ((*pmLookupDesc_ptr) (pmid,desc)); }
303 {
return ((*pmGetInDom_ptr) (indom,instlist,namelist)); }
306 {
return ((*pmLookupText_ptr) (pmid, level, buffer)); }
309 {
return ((*pmUnitsStr_r_ptr) (pu,
buf, buflen)); }
320static unsigned int stringHash(
char *str,
unsigned int tableSize)
322 unsigned long hash = 5381;
324 while ((
c = (*str++))) {
325 hash = ((hash << 5) + hash) +
c;
328 return (hash % tableSize);
363 while (next != NULL) {
382 if (idx < 0)
return(-1);
389 while (next != NULL) {
407#define STRINGIFY(x) #x
408#define TOSTRING(x) STRINGIFY(x)
409#define mGet_DL_FPtr(Name) \
410 Name##_ptr = dlsym(dl1, TOSTRING(Name)); \
411 if (dlerror() != NULL) { \
412 int strErr=snprintf(_pcp_vector.cmp_info.disabled_reason, PAPI_HUGE_STR_LEN, \
413 "PCP library function %s not found in lib.", TOSTRING(Name)); \
414 _pcp_vector.cmp_info.disabled_reason[PAPI_HUGE_STR_LEN-1]=0; \
415 if (strErr > PAPI_HUGE_STR_LEN) HANDLE_STRING_ERROR; \
416 return(PAPI_ENOSUPP); \
428 char path_name[1024];
429 char *pcp_root = getenv(
"PAPI_PCP_ROOT");
445 dl1 = dlopen(
"libpcp.so", RTLD_NOW | RTLD_GLOBAL);
449 if (
dl1 == NULL && pcp_root != NULL) {
450 int strErr=snprintf(path_name, 1024,
"%s/lib64/libpcp.so", pcp_root);
453 dl1 = dlopen(path_name, RTLD_NOW | RTLD_GLOBAL);
490static int qsPMID(
const void *arg1,
const void* arg2)
495 if (p1->
pmid < p2->
pmid)
return (-1);
496 if (p1->
pmid > p2->
pmid)
return ( 1);
497 if (p1->
idx < p2->
idx )
return (-1);
498 if (p1->
idx > p2->
idx )
return ( 1);
499 return (strcmp(p1->
name, p2->
name));
541 fprintf(
stderr,
"%s:%i:%s realloc denied; "
542 "pcp_event_info=%p at size=%i.\n",
543 __FILE__, __LINE__, __func__,
581 if (ret == PM_ERR_PMID) {
582 fprintf(
stderr,
"%s:%i:%s Invalid PMID.\n",
583 __FILE__, __LINE__, __func__);
587 if (ret == PM_ERR_NOAGENT) {
588 fprintf(
stderr,
"%s:%i:%s PMDA Agent not available to respond..\n",
589 __FILE__, __LINE__, __func__);
594 fprintf(
stderr,
"%s:%i:%s Unknown error code ret=%i.\n",
595 __FILE__, __LINE__, __func__, ret);
614 static int domains=0;
619 if (cachedDomains == NULL)
return(NULL);
620 for (
i=0;
i<domains;
i++) {
621 free(cachedDomains[
i].instances);
622 free(cachedDomains[
i].
names);
627 cachedDomains = NULL;
632 for (
i=0;
i<domains;
i++) {
633 if (indom == cachedDomains[
i].domainId)
break;
643 cachedDomains = realloc(cachedDomains,
647 if (cachedDomains == NULL) {
648 fprintf(
stderr,
"%s:%i:%s malloc/realloc denied for "
649 "cachedDomains; size=%i.\n",
650 __FILE__, __LINE__, __func__, domains);
654 cachedDomains[domIdx].
domainId = indom;
656 &cachedDomains[domIdx].instances,
657 &cachedDomains[domIdx].
names);
659 if (cachedDomains[domIdx].
names[
i] == NULL ||
660 strlen(cachedDomains[domIdx].
names[
i]) == 0 ||
662 fprintf(
stderr,
"%s:%i:%s ERROR: cachedGetInDom: domain=%u, domIdx=%i, name idx %i invalid string.\n",
663 __FILE__, __LINE__,
FUNC, indom, domIdx,
i);
673 if (cachedDomains[domIdx].instances[
i] == inst)
674 return cachedDomains[domIdx].
names[
i];
677 fprintf(
stderr,
"%s:%i:%s ERROR: cachedGetInDom: domain=%u, domIdx=%i, numInstances=%i, failed to find inst=%i.\n",
678 __FILE__, __LINE__,
FUNC, indom, domIdx, cachedDomains[domIdx].numInstances, inst);
689static unsigned long long getULLValue(pmValueSet *vset,
int value_index)
691 unsigned long long value;
695 if (vset->valfmt == PM_VAL_INSITU) {
696 convert.
ll = vset->vlist[value_index].value.lval;
699 pmValueBlock *pmvb = vset->vlist[value_index].value.pval;
700 myPtr.
cPtr = pmvb->vbuf;
701 switch (pmvb->vtype) {
703 convert.
ll = myPtr.
iPtr[0];
708 value = myPtr.
uiPtr[0];
721 convert.
d = myPtr.
fPtr[0];
726 convert.
d = myPtr.
dPtr[0];
736 fprintf(
stderr,
"%s:%i pmValueBlock (from PCP) contains an unrecognized value type=%i.\n",
737 __FILE__, __LINE__, pmvb->vtype);
774 rawval.
ll -= zero.
ll;
791 fprintf(
stderr,
"%s:%i pcp_event_info[%s] contains an unrecognized value type=%i.\n",
819 char errMsg[]=
"Help Text is not available for this event.";
824 if (*helpText != NULL) free(*helpText);
829 if (ret == PM_ERR_TEXT) {
830 *helpText = strdup(errMsg);
831 }
else if (ret != 0) {
832 fprintf(
stderr,
"%s:%i:%s pmLookupText failed; return=%s.\n",
838 for (p=(*helpText); p[0] != 0; p++) {
839 if (p[0] ==
'\n') p[0] =
'|';
864 #define hostnameLen 512
876 int strErr=snprintf(reason, rLen,
"Failed system call, gethostname() "
877 "returned %i.", ret);
889 int strErr=snprintf(reason, rLen,
"Cannot connect to PM Daemon on \"%s\".\n "
890 "(Is the Performance Co-Pilot running?)\n", hostname);
892 if (strErr > rLen)
SUBDBG(
"%s:%i Warning! Error's 'reason' string truncated:\n%s\n",__FILE__,__LINE__,reason);
915 int strErr=snprintf(reason, rLen,
"pmTraversePMNS failed; ret=%i [%s]\n",
917 if (ret == PM_ERR_NAME) {
918 strErr=snprintf(reason, rLen,
"pmTraversePMNS ret=PM_ERR_NAME: "
919 "Occurs if event filter '%s' unknown to PCP Daemon.\n",
AGENT_NAME);
931 "sEventInfoBlock=%i.\n",
935 int strErr=snprintf(reason, rLen,
"pmTraversePMNS returned zero events "
944 char **allNames=calloc(
sEventCount,
sizeof(
char*));
950 if (allPMID == NULL) {
951 snprintf(reason, rLen,
"memory alloc denied for allPMID; "
953 int strErr=snprintf(reason, rLen,
"Could not allocate %lu bytes of memory for allPMID.",
sEventCount*
sizeof(pmID));
976 ret = pcp_pmLookupName(j, allNames+
i, allPMID+
i);
978 int strErr=snprintf(reason, rLen,
"pmLookupName for %i names failed; ret=%i [%s].\n",
983 if (ret == PM_ERR_IPC) {
984 strErr=snprintf(reason, rLen,
"pmLookupName ret=PM_ERR_IPC: one known cause is a readblock too large; reduce LNBLOCK (%s:%i).\n",
1006 pmResult *allFetch = NULL;
1011 int strErr=snprintf(reason, rLen,
"pcp_pmFetch failed, retcode=%d.", ret);
1034 for (
i=0;
i<origEventCount;
i++) {
1036 pmValueSet *vset = allFetch->vset[
i];
1040 fprintf(
stderr,
"%s:%i vset=NULL for name='%s'\n",
1046 if (vset->numval == 0) {
1053 unsigned long long ullval= (
long long) -1;
1056 if (vset->valfmt != PM_VAL_INSITU) {
1057 pmValue *pmval = &vset->vlist[0];
1058 pmValueBlock *pB = pmval->value.pval;
1060 int strErr=snprintf(reason, rLen,
"Unexpected value type fetched for %s. %i vs %i. Possible version incompatibiity.\n",
1083 convert.
ull = ullval;
1089 case PM_TYPE_DOUBLE:
1090 convert.
ull = ullval;
1102 case PM_TYPE_STRING:
1117 convert.
ull = ullval;
1118 _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]);
1127 for (j=0; j<vset->numval; j++) {
1128 pmValue *pmval = &vset->vlist[j];
1158 int strErr=snprintf(reason, rLen,
1178 unsigned int myHash;
1188 unsigned int current, prev=0;
1189 printf(
"count, hash, name, pmid, value[idx]\n");
1193 if (prev > 0 && current != (prev+1) && current != prev)
1194 printf(
"----,----,----,----\n");
1195 printf(
"%i, %u, \"%s\", 0x%08X, %i\n",
i, myHash,
1207 if (
f !=
i) hashErr++;
1331 #define BlockSize 64
1338 newalloc*
sizeof(
int));
1340 newalloc*
sizeof(
unsigned long long));
1348 calloc(MyCtl->
maxAllocated,
sizeof(
unsigned long long));
1401 pmID *allPMID=malloc((myCtl->
numEvents)*
sizeof(pmID));
1416 for (j=0; j<nPMID; j++) {
1417 if (myPMID == allPMID[j])
break;
1421 allPMID[nPMID++] = myPMID;
1426 pmResult *allFetch = NULL;
1428 *results = allFetch;
1431 fprintf(
stderr,
"%s:%i:%s pcp_pmFetch failed, return=%s.\n",
1433 if (allPMID != NULL) free(allPMID);
1443 for (
i=0;
i<nPMID;
i++) {
1444 pmValueSet *vset = allFetch->vset[
i];
1445 pmID myPMID = allPMID[
i];
1454 if (thisPMID == myPMID) {
1461 if (allPMID != NULL) free(allPMID);
1474 unsigned long long aValue;
1481 fprintf(
stderr,
"%s:%i:%s PCP_ReadList failed, return=%s.\n",
1542 fprintf(
stderr,
"%s:%i:%s 'events' is null.\n",
1543 __FILE__, __LINE__,
FUNC);
1549 fprintf(
stderr,
"%s:%i:%s PCP_ReadList failed, return=%s.\n",
1606 for (
i=0;
i<=ctr_pcp_ntv_code_to_info;
i++)
1660 fprintf(
stderr,
"%s:%i:%s CODE 0x%08x IS INVALID "
1661 "OR UNRECOGNIZED.\n", __FILE__, __LINE__,
FUNC, code);
1736 if (
name == NULL || strlen(
name)<1) {
1737 fprintf(
stderr,
"%s:%i:%s Invalid name.\n",
1738 __FILE__, __LINE__,
FUNC);
1742 if (event_code == NULL) {
1743 fprintf(
stderr,
"%s:%i:%s event_code is not a valid pointer.\n",
1744 __FILE__, __LINE__,
FUNC);
1750 fprintf(
stderr,
"%s:%i:%s Failed to find name='%s', hash=%i.\n",
1771 fprintf(
stderr,
"%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1772 __FILE__, __LINE__,
FUNC, pcpIdx);
1777 fprintf(
stderr,
"%s:%i:%s called with out-of-range descr len=%i.\n",
1778 __FILE__, __LINE__,
FUNC, len);
1800 fprintf(
stderr,
"%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1801 __FILE__, __LINE__,
FUNC, pcpIdx);
1806 fprintf(
stderr,
"%s:%i:%s called with out-of-range descr len=%i.\n",
1807 __FILE__, __LINE__,
FUNC, len);
1811 char *helpText = NULL;
1814 if (helpText != NULL) free(helpText);
1815 fprintf(
stderr,
"%s:%i:%s failed getHelpText; it returned %s.\n",
1820 strncpy(
descr, helpText, len);
1854 fprintf(
stderr,
"%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1855 __FILE__, __LINE__,
FUNC, pcpIdx);
1859 len=
sizeof(info->
symbol);
1865 if (ret !=
PAPI_OK)
return(ret);
1877 if ( strlen(unitStr) == 0) {
1878 sprintf(unitStr,
"fraction");
1882 sprintf(unitStr,
"[%u, %i, %u, %u, %i, %i, %i]",
1894 len =
sizeof(info->
units);
1895 strncpy( info->
units, unitStr, len);
1896 info->
units[len-1] = 0;
1907 case PM_TYPE_STRING:
1912 case PM_TYPE_DOUBLE:
1935 .short_name =
"pcp",
1936 .description =
"Performance Co-Pilot",
static papi_handle_t handle
const char * names[NUM_EVENTS]
Returns a string describing the PAPI error code.
struct papi_vectors * _papi_hwd[]
volatile int buf[CACHE_FLUSH_BUFFER_SIZE_INTS]
#define PAPI_TIMESCOPE_POINT
#define PAPI_DATATYPE_FP64
#define PAPI_DATATYPE_UINT64
#define PAPI_NTV_ENUM_UMASKS
#define PAPI_TIMESCOPE_SINCE_START
#define PAPI_DATATYPE_INT64
#define PAPI_HUGE_STR_LEN
char events[MAX_EVENTS][BUFSIZ]
static double c[MATRIX_SIZE][MATRIX_SIZE]
static int _pcp_ntv_name_to_code(const char *name, unsigned int *event_code)
static unsigned long long getULLValue(pmValueSet *vset, int value_index)
static int _local_linkDynamicLibraries(void)
#define mConvertUsec(timeval_)
#define _time_gettimeofday
static int pcp_pmLookupDesc(pmID pmid, pmDesc *desc)
static int _pcp_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
static unsigned int stringHash(char *str, unsigned int tableSize)
static void pcp_pmFreeResult(pmResult *result)
static int getHelpText(unsigned int pcpIdx, char **helpText)
static int _pcp_shutdown_component(void)
static int _pcp_shutdown_thread(hwd_context_t *ctx)
static char * pcp_pmErrStr(int code)
static int _pcp_init_thread(hwd_context_t *ctx)
static int sEventInfoBlock
static int _pcp_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
static void makeQualifiedEvent(int baseEvent, int idx, char *qualifier)
static int _pcp_init_component(int cidx)
static int _pcp_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
static void subZero(_pcp_control_state_t *myCtl, int event)
static int pcp_pmDestroyContext(int handle)
static void cbPopulateNameOnly(const char *name)
static int _pcp_ntv_code_to_name(unsigned int pcpIdx, char *name, int len)
static int _pcp_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int pcp_pmTraversePMNS(const char *name, void(*func)(const char *))
static int _pcp_ntv_enum_events(unsigned int *EventCode, int modifier)
static int _pcp_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _pcp_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
static int pcp_pmGetInDom(pmInDom indom, int **instlist, char ***namelist)
static _pcp_hash_t sNameHash[HASH_SIZE]
static unsigned int addNameHash(char *key, int idx)
static int findNameHash(char *key)
static int sEventInfoSize
static _pcp_event_info_t * pcp_event_info
void(* _dl_non_dynamic_init)(void)
static int _pcp_ntv_code_to_descr(unsigned int pcpIdx, char *descr, int len)
static int pcp_pmLookupText(pmID pmid, int level, char **buffer)
static struct timeval t1 t2
static char * pcp_pmUnitsStr_r(const pmUnits *pu, char *buf, int buflen)
static int _pcp_init_control_state(hwd_control_state_t *ctl)
static int PCP_ReadList(hwd_control_state_t *ctl, pmResult **results)
static void freeNameHash(void)
static int pcp_pmNewContext(int type, const char *name)
static int _pcp_set_domain(hwd_control_state_t *ctl, int domain)
static void getPMDesc(int pcpIdx)
static int qsPMID(const void *arg1, const void *arg2)
static int pcp_pmFetch(int numpid, pmID *pmidlist, pmResult **result)
#define mGet_DL_FPtr(Name)
static char * cachedGetInDom(pmInDom indom, int inst)
#define mRtnCnt(funcname)
static int _pcp_ntv_code_to_info(unsigned int pcpIdx, PAPI_event_info_t *info)
#define HANDLE_STRING_ERROR
papi_vector_t _pcp_vector
unsigned long AO_t __attribute__((__aligned__(4)))
#define PAPI_NATIVE_AND_MASK
Return codes and api definitions.
#define SUBDBG(format, args...)
char name[PAPI_MAX_STR_LEN]
char disabled_reason[PAPI_HUGE_STR_LEN]
char units[PAPI_MIN_STR_LEN]
char symbol[PAPI_HUGE_STR_LEN]
char long_descr[PAPI_HUGE_STR_LEN]
unsigned long long * pcpValue
char name[PAPI_MAX_STR_LEN]
unsigned long long zeroValue
PAPI_component_info_t cmp_info
_papi_int_domain_t domain
_papi_int_granularity_t granularity
_papi_int_inherit_t inherit
unsigned long long * ullPtr