PAPI 7.1.0.0
Loading...
Searching...
No Matches
linux-pcp.c File Reference
Include dependency graph for linux-pcp.c:

Go to the source code of this file.

Data Structures

union  uPointer_t
 
union  convert_64_t
 
struct  _pcp_register_t
 
struct  _pcp_event_info_t
 
struct  _pcp_reg_alloc_t
 
struct  _pcp_control_state_t
 
struct  _pcp_context_t
 
struct  _pcp_hash_t
 
struct  _pcp_domain_cache_t
 

Macros

#define FUNC   __func__ /* force it. */
 
#define AGENT_NAME   "perfevent" /* Power9 PCP. */
 
#define PM_OPTFLAG_EXIT   (1<<5)
 
#define PM_CONTEXT_UNDEF   -1
 
#define PM_CONTEXT_HOST   1
 
#define PM_CONTEXT_ARCHIVE   2
 
#define PM_CONTEXT_LOCAL   3
 
#define HANDLE_STRING_ERROR   {fprintf(stderr,"%s:%i unexpected string function error.\n",__FILE__,__LINE__); exit(-1);}
 
#define HASH_SIZE   512 /* very roughly in the range of total events. full Saturn test, had ~ 11,000 events.*/
 
#define COUNT_ROUTINES   1 /* Change to zero to stop counting. */
 
#define mRtnCnt(funcname)   /* .. make macro do nothing. */
 
#define mConvertUsec(timeval_)    (timeval_.tv_sec*1000000+timeval_.tv_usec) /* avoid typos. */
 
#define _prog_fprintf   if (0) fprintf /* change to 1 to enable printing of progress debug messages. */
 
#define _time_fprintf   if (0) fprintf /* change to 1 to enable printing of performance timings. */
 
#define _time_gettimeofday   if (0) gettimeofday /* change to 1 to enable gettimeofday for performance timings. */
 
#define STRINGIFY(x)   #x
 
#define TOSTRING(x)   STRINGIFY(x)
 
#define mGet_DL_FPtr(Name)
 
#define hostnameLen   512 /* constant used multiple times. */
 
#define LNBLOCK   256 /* Power9 gets IPC errors if read block is too large. */
 
#define BlockSize   64 /* constant used multiple times. */
 

Functions

static char * cachedGetInDom (pmInDom indom, int inst)
 
static char * pcp_pmErrStr (int code)
 
static int pcp_pmTraversePMNS (const char *name, void(*func)(const char *))
 
static void pcp_pmFreeResult (pmResult *result)
 
static int pcp_pmNewContext (int type, const char *name)
 
static int pcp_pmDestroyContext (int handle)
 
static int pcp_pmFetch (int numpid, pmID *pmidlist, pmResult **result)
 
static int pcp_pmLookupDesc (pmID pmid, pmDesc *desc)
 
static int pcp_pmGetInDom (pmInDom indom, int **instlist, char ***namelist)
 
static int pcp_pmLookupText (pmID pmid, int level, char **buffer)
 
static char * pcp_pmUnitsStr_r (const pmUnits *pu, char *buf, int buflen)
 
static unsigned int stringHash (char *str, unsigned int tableSize)
 
static unsigned int addNameHash (char *key, int idx)
 
static void freeNameHash (void)
 
static int findNameHash (char *key)
 
static int _local_linkDynamicLibraries (void)
 
static int qsPMID (const void *arg1, const void *arg2)
 
static void cbPopulateNameOnly (const char *name)
 
static void makeQualifiedEvent (int baseEvent, int idx, char *qualifier)
 
static void getPMDesc (int pcpIdx)
 
static unsigned long long getULLValue (pmValueSet *vset, int value_index)
 
static void subZero (_pcp_control_state_t *myCtl, int event)
 
static int getHelpText (unsigned int pcpIdx, char **helpText)
 
static int _pcp_init_component (int cidx)
 
static int _pcp_init_thread (hwd_context_t *ctx)
 
static int _pcp_init_control_state (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_ReadList (hwd_control_state_t *ctl, pmResult **results)
 
static int _pcp_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _pcp_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _pcp_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
 
static int _pcp_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _pcp_shutdown_thread (hwd_context_t *ctx)
 
static int _pcp_shutdown_component (void)
 
static int _pcp_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
 
static int _pcp_set_domain (hwd_control_state_t *ctl, int domain)
 
static int _pcp_ntv_enum_events (unsigned int *EventCode, int modifier)
 
static int _pcp_ntv_name_to_code (const char *name, unsigned int *event_code)
 
static int _pcp_ntv_code_to_name (unsigned int pcpIdx, char *name, int len)
 
static int _pcp_ntv_code_to_descr (unsigned int pcpIdx, char *descr, int len)
 
static int _pcp_ntv_code_to_info (unsigned int pcpIdx, PAPI_event_info_t *info)
 

Variables

papi_vector_t _pcp_vector
 
int _papi_hwi_debug = DEBUG_SUBSTRATE
 
static int sEventInfoSize =0
 
static int sEventInfoBlock = ((8*1024) / sizeof(_pcp_event_info_t))
 
static _pcp_event_info_tpcp_event_info = NULL
 
static int sEventCount = 0
 
static int ctxHandle = -1
 
static _pcp_hash_t sNameHash [HASH_SIZE]
 
static struct timeval t1 t2
 
static void * dl1 = NULL
 
static char pcp_main [] =PAPI_PCP_MAIN
 
void(* _dl_non_dynamic_init )(void)
 

Macro Definition Documentation

◆ _prog_fprintf

#define _prog_fprintf   if (0) fprintf /* change to 1 to enable printing of progress debug messages. */

Definition at line 242 of file linux-pcp.c.

◆ _time_fprintf

#define _time_fprintf   if (0) fprintf /* change to 1 to enable printing of performance timings. */

Definition at line 243 of file linux-pcp.c.

◆ _time_gettimeofday

#define _time_gettimeofday   if (0) gettimeofday /* change to 1 to enable gettimeofday for performance timings. */

Definition at line 244 of file linux-pcp.c.

◆ AGENT_NAME

#define AGENT_NAME   "perfevent" /* Power9 PCP. */

Definition at line 42 of file linux-pcp.c.

◆ BlockSize

#define BlockSize   64 /* constant used multiple times. */

◆ COUNT_ROUTINES

#define COUNT_ROUTINES   1 /* Change to zero to stop counting. */

Definition at line 197 of file linux-pcp.c.

◆ FUNC

#define FUNC   __func__ /* force it. */

Definition at line 36 of file linux-pcp.c.

◆ HANDLE_STRING_ERROR

#define HANDLE_STRING_ERROR   {fprintf(stderr,"%s:%i unexpected string function error.\n",__FILE__,__LINE__); exit(-1);}

Definition at line 65 of file linux-pcp.c.

◆ HASH_SIZE

#define HASH_SIZE   512 /* very roughly in the range of total events. full Saturn test, had ~ 11,000 events.*/

Definition at line 194 of file linux-pcp.c.

◆ hostnameLen

#define hostnameLen   512 /* constant used multiple times. */

◆ LNBLOCK

#define LNBLOCK   256 /* Power9 gets IPC errors if read block is too large. */

◆ mConvertUsec

#define mConvertUsec (   timeval_)     (timeval_.tv_sec*1000000+timeval_.tv_usec) /* avoid typos. */

Definition at line 239 of file linux-pcp.c.

◆ mGet_DL_FPtr

#define mGet_DL_FPtr (   Name)
Value:
Name##_ptr = dlsym(dl1, TOSTRING(Name)); \
if (dlerror() != NULL) { /* If we had an error, */ \
"PCP library function %s not found in lib.", TOSTRING(Name)); \
return(PAPI_ENOSUPP); \
} /* end of macro. */
#define PAPI_ENOSUPP
Definition: f90papi.h:244
#define PAPI_HUGE_STR_LEN
Definition: f90papi.h:120
static void * dl1
Definition: linux-pcp.c:248
#define TOSTRING(x)
Definition: linux-pcp.c:408
#define HANDLE_STRING_ERROR
Definition: linux-pcp.c:65
papi_vector_t _pcp_vector
Definition: linux-pcp.c:182
char disabled_reason[PAPI_HUGE_STR_LEN]
Definition: papi.h:634
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20

Definition at line 409 of file linux-pcp.c.

◆ mRtnCnt

#define mRtnCnt (   funcname)    /* .. make macro do nothing. */

Definition at line 227 of file linux-pcp.c.

◆ PM_CONTEXT_ARCHIVE

#define PM_CONTEXT_ARCHIVE   2

Definition at line 59 of file linux-pcp.c.

◆ PM_CONTEXT_HOST

#define PM_CONTEXT_HOST   1

Definition at line 58 of file linux-pcp.c.

◆ PM_CONTEXT_LOCAL

#define PM_CONTEXT_LOCAL   3

Definition at line 60 of file linux-pcp.c.

◆ PM_CONTEXT_UNDEF

#define PM_CONTEXT_UNDEF   -1

Definition at line 57 of file linux-pcp.c.

◆ PM_OPTFLAG_EXIT

#define PM_OPTFLAG_EXIT   (1<<5)

Definition at line 56 of file linux-pcp.c.

◆ STRINGIFY

#define STRINGIFY (   x)    #x

Definition at line 407 of file linux-pcp.c.

◆ TOSTRING

#define TOSTRING (   x)    STRINGIFY(x)

Definition at line 408 of file linux-pcp.c.

Function Documentation

◆ _local_linkDynamicLibraries()

static int _local_linkDynamicLibraries ( void  )
static

Definition at line 419 of file linux-pcp.c.

420{
421 if ( _dl_non_dynamic_init != NULL ) { // If weak var present, statically linked insted of dynamic.
422 char *strCpy=strncpy( _pcp_vector.cmp_info.disabled_reason, "The pcp component REQUIRES dynamic linking capabilities.", PAPI_HUGE_STR_LEN);
424 if (strCpy == NULL) HANDLE_STRING_ERROR;
425 return PAPI_ENOSUPP; // EXIT not supported.
426 }
427
428 char path_name[1024];
429 char *pcp_root = getenv("PAPI_PCP_ROOT");
430
431 dl1 = NULL;
432 // Step 1: Process override if given.
433 if (strlen(pcp_main) > 0) { // If override given, it has to work.
434 dl1 = dlopen(pcp_main, RTLD_NOW | RTLD_GLOBAL); // Try to open that path.
435 if (dl1 == NULL) {
436 int strErr=snprintf(_pcp_vector.cmp_info.disabled_reason, PAPI_HUGE_STR_LEN, "PAPI_PCP_MAIN override '%s' given in Rules.pcp not found.", pcp_main);
439 return(PAPI_ENOSUPP); // Override given but not found.
440 }
441 }
442
443 // Step 2: Try system paths, will work with Spack, LD_LIBRARY_PATH, default paths.
444 if (dl1 == NULL) { // No override,
445 dl1 = dlopen("libpcp.so", RTLD_NOW | RTLD_GLOBAL); // Try system paths.
446 }
447
448 // Step 3: Try the explicit install default.
449 if (dl1 == NULL && pcp_root != NULL) { // if root given, try it.
450 int strErr=snprintf(path_name, 1024, "%s/lib64/libpcp.so", pcp_root); // PAPI Root check.
451 path_name[1024-1]=0;
453 dl1 = dlopen(path_name, RTLD_NOW | RTLD_GLOBAL); // Try to open that path.
454 }
455
456 // Check for failure.
457 if (dl1 == NULL) {
458 int strErr=snprintf(_pcp_vector.cmp_info.disabled_reason, PAPI_HUGE_STR_LEN, "libpcp.so not found.");
461 return(PAPI_ENOSUPP);
462 }
463
464 // We have dl1.
465
466//-----------------------------------------------------------------------------
467// Collect pointers for routines in shared library. All below will abort this
468// routine with PAPI_ENOSUPP, if the routine is not found in the dynamic
469// library.
470//-----------------------------------------------------------------------------
471
472 mGet_DL_FPtr(pmLookupName);
473 mGet_DL_FPtr(pmErrStr);
474 mGet_DL_FPtr(pmTraversePMNS);
475 mGet_DL_FPtr(pmFreeResult);
476 mGet_DL_FPtr(pmNewContext);
477 mGet_DL_FPtr(pmDestroyContext);
478 mGet_DL_FPtr(pmFetch);
479 mGet_DL_FPtr(pmLookupDesc);
480 mGet_DL_FPtr(pmGetInDom);
481 mGet_DL_FPtr(pmLookupText);
482 mGet_DL_FPtr(pmUnitsStr_r);
483 return PAPI_OK; // If we get here, all above succeeded.
484} // end routine.
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
static char pcp_main[]
Definition: linux-pcp.c:251
void(* _dl_non_dynamic_init)(void)
Definition: linux-pcp.c:260
#define mGet_DL_FPtr(Name)
Definition: linux-pcp.c:409
Here is the caller graph for this function:

◆ _pcp_ctl()

static int _pcp_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
)
static

Definition at line 1631 of file linux-pcp.c.

1632{
1633 mRtnCnt(_pcp_ctl); // count this function.
1634 ( void ) ctx; // avoid var unused warning.
1635 ( void ) code; // avoid var unused warning.
1636 ( void ) option; // avoid var unused warning.
1637
1638 switch (code) {
1639 case PAPI_DEFDOM:
1640 SUBDBG("PAPI_DEFDOM, option.domain=0x%08X\n", (unsigned int) option->domain.domain);
1641 break;
1642
1643 case PAPI_DOMAIN:
1644 SUBDBG("PAPI_DOMAIN, option.domain=0x%08X\n", (unsigned int) option->domain.domain);
1645 break;
1646
1647 case PAPI_DEFGRN:
1648 SUBDBG("PAPI_DEFGRN, option.granularity=0x%08X\n", (unsigned int) option->granularity.granularity);
1649 break;
1650
1651 case PAPI_GRANUL:
1652 SUBDBG("PAPI_GRANUL, option.granularity=0x%08X\n", (unsigned int) option->granularity.granularity);
1653 break;
1654
1655 case PAPI_INHERIT:
1656 SUBDBG("PAPI_INHERIT, option.inherit=0x%08X\n", (unsigned int) option->inherit.inherit);
1657 break;
1658
1659 default:
1660 fprintf(stderr, "%s:%i:%s CODE 0x%08x IS INVALID "
1661 "OR UNRECOGNIZED.\n", __FILE__, __LINE__, FUNC, code);
1662 return PAPI_EINVAL; // Invalid code.
1663 break;
1664 } // end switch by code.
1665
1666 return PAPI_OK;
1667} // end routine.
#define PAPI_DEFGRN
Definition: f90papi.h:26
#define PAPI_GRANUL
Definition: f90papi.h:179
#define PAPI_EINVAL
Definition: f90papi.h:115
#define PAPI_DOMAIN
Definition: f90papi.h:159
#define PAPI_INHERIT
Definition: f90papi.h:76
#define PAPI_DEFDOM
Definition: f90papi.h:188
#define FUNC
Definition: linux-pcp.c:36
static int _pcp_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
Definition: linux-pcp.c:1631
#define mRtnCnt(funcname)
Definition: linux-pcp.c:227
#define SUBDBG(format, args...)
Definition: papi_debug.h:64
FILE * stderr
_papi_int_domain_t domain
_papi_int_granularity_t granularity
_papi_int_inherit_t inherit
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_init_component()

static int _pcp_init_component ( int  cidx)
static

Definition at line 856 of file linux-pcp.c.

857{
858 int retval = PAPI_OK;
859 char *reason = _papi_hwd[cidx]->cmp_info.disabled_reason; // For error messages.
860 int rLen = PAPI_HUGE_STR_LEN; // Most I will print.
861 reason[rLen-1]=0; // last resort terminator.
862
863 mRtnCnt(_pcp_init_component); // count the routine.
864 #define hostnameLen 512 /* constant used multiple times. */
865 char hostname[hostnameLen]; // host name.
866 int ret;
867
869 if ( ret != PAPI_OK ) { // Failure to get lib.
871 goto fn_fail;
872 }
873
874 ret = gethostname(hostname, hostnameLen); // Try to get the host hame.
875 if (ret != 0) { // If we can't get the hostname,
876 int strErr=snprintf(reason, rLen, "Failed system call, gethostname() "
877 "returned %i.", ret);
878 reason[rLen-1]=0;
879 if (strErr > rLen) HANDLE_STRING_ERROR;
881 goto fn_fail;
882 }
883 #undef hostnameLen /* done with it. */
884
885 _prog_fprintf(stderr, "%s:%i retrieved hostname='%s'\n", __FILE__, __LINE__, hostname); // show progress.
886
887 ctxHandle = pcp_pmNewContext(PM_CONTEXT_HOST, "local:"); // Set the new context to local host.
888 if (ctxHandle < 0) {
889 int strErr=snprintf(reason, rLen, "Cannot connect to PM Daemon on \"%s\".\n "
890 "(Is the Performance Co-Pilot running?)\n", hostname);
891 reason[rLen-1]=0;
892 if (strErr > rLen) SUBDBG("%s:%i Warning! Error's 'reason' string truncated:\n%s\n",__FILE__,__LINE__,reason);
894 goto fn_fail;
895 }
896
897 _prog_fprintf(stderr, "%s:%i Found ctxHandle=%i\n", __FILE__, __LINE__, ctxHandle); // show progress.
898
899 sEventInfoSize = sEventInfoBlock; // first allocation.
901 calloc(sEventInfoSize, sizeof(_pcp_event_info_t)); // Make room for all events.
902 if (pcp_event_info == NULL) {
904 "Could not allocate %lu bytes of memory for pcp_event_info.", sEventInfoSize*sizeof(_pcp_event_info_t));
905 _pcp_vector.cmp_info.disabled_reason[PAPI_HUGE_STR_LEN-1]=0; // force null termination.
908 goto fn_fail;
909 }
910
911 sEventCount = 0; // begin at zero.
912 _time_gettimeofday(&t1, NULL);
913 ret = pcp_pmTraversePMNS(AGENT_NAME, cbPopulateNameOnly); // Timed on Saturn [Intel Xeon 2.0GHz]; typical 9ms, range 8.5-10.5ms.
914 if (ret < 0) { // Failure...
915 int strErr=snprintf(reason, rLen, "pmTraversePMNS failed; ret=%i [%s]\n",
916 ret, pcp_pmErrStr(ret));
917 if (ret == PM_ERR_NAME) { // We know what this one is,
918 strErr=snprintf(reason, rLen, "pmTraversePMNS ret=PM_ERR_NAME: "
919 "Occurs if event filter '%s' unknown to PCP Daemon.\n", AGENT_NAME);
920 }
921 reason[rLen-1]=0;
922 if (strErr >rLen) HANDLE_STRING_ERROR;
924 goto fn_fail;
925 }
926
927 _time_gettimeofday(&t2, NULL);
928 _time_fprintf(stderr, "pmTraversePMNS PopulateNameOnly took %li uS.\n",
930 _time_fprintf(stderr, "Final sEventCount=%i, sEventInfoSize=%i, "
931 "sEventInfoBlock=%i.\n",
933
934 if (sEventCount < 1) { // Failure...
935 int strErr=snprintf(reason, rLen, "pmTraversePMNS returned zero events "
936 "for AGENT=\"%s\".\n", AGENT_NAME);
937 reason[rLen-1]=0;
938 if (strErr >rLen) HANDLE_STRING_ERROR;
940 goto fn_fail;
941 }
942
943 int i,j,k;
944 char **allNames=calloc(sEventCount, sizeof(char*)); // Make an array for all names.
945 for (i=0; i<sEventCount; i++) { // ..
946 allNames[i] = pcp_event_info[i].name; // copy pointer into array.
947 } // end for each event.
948
949 pmID *allPMID=calloc(sEventCount, sizeof(pmID)); // Make an array for results.
950 if (allPMID == NULL) { // If we failed,
951 snprintf(reason, rLen, "memory alloc denied for allPMID; "
952 "size=%i.\n", sEventCount);
953 int strErr=snprintf(reason, rLen, "Could not allocate %lu bytes of memory for allPMID.", sEventCount*sizeof(pmID));
954 free(allNames);
955 if (strErr > rLen) HANDLE_STRING_ERROR;
957 goto fn_fail;
958 } // end if calloc failed.
959
960 //----------------------------------------------------------------
961 // Unlike Saturn, on the Power9 we get an 'IPC protocol failure'
962 // if we try to read more than 946 names at a time. This is some
963 // limitation on a communication packet size. On our test system
964 // Power9; the maximum number we can read is 946. To allow leeway
965 // for other possible values; we read in blocks of 256.
966 //----------------------------------------------------------------
967 #define LNBLOCK 256 /* Power9 gets IPC errors if read block is too large. */
968 k = (__LINE__)-1; // where LNBLOCK is defined.
969
970 _time_gettimeofday(&t1, NULL);
971
972 i=0; // Starting index for allPMID.
973 while (i<sEventCount) { // read in blocks of LNBLOCK.
974 j = sEventCount-i; // .. presume we can read the rest.
975 if (j > LNBLOCK) j=LNBLOCK; // .. reduce if we cannot.
976 ret = pcp_pmLookupName(j, allNames+i, allPMID+i); // .. Get a block of PMIDs for a block of names.
977 if (ret < 0) { // .. Failure...
978 int strErr=snprintf(reason, rLen, "pmLookupName for %i names failed; ret=%i [%s].\n",
979 sEventCount, ret, pcp_pmErrStr(ret));
980 reason[rLen-1]=0;
981 if (strErr > rLen) HANDLE_STRING_ERROR;
982
983 if (ret == PM_ERR_IPC) { // .. If we know it, rewrite.
984 strErr=snprintf(reason, rLen, "pmLookupName ret=PM_ERR_IPC: one known cause is a readblock too large; reduce LNBLOCK (%s:%i).\n",
985 __FILE__,k);
986 reason[rLen-1]=0;
987 if (strErr > rLen) HANDLE_STRING_ERROR;
989 goto fn_fail;
990 }
991
993 goto fn_fail;
994 }
995
996 i+=j; // .. Adjust the pointer forward by what we read.
997 } // end while to read names in chunks, and avoid IPC error.
998 #undef LNBLOCK /* Discard constant; no further use. */
999
1000 _time_gettimeofday(&t2, NULL);
1001 _time_fprintf(stderr, "pmLookupName for all took %li uS, ret=%i.\n",
1002 (mConvertUsec(t2)-mConvertUsec(t1)), ret );
1003
1004 for (i=0; i<sEventCount; i++) pcp_event_info[i].pmid = allPMID[i]; // copy all the pmid over to array.
1005
1006 pmResult *allFetch = NULL; // result of pmFetch.
1007 _time_gettimeofday(&t1, NULL);
1008 ret = pcp_pmFetch(sEventCount, allPMID, &allFetch); // Fetch (read) all the events.
1009 _time_gettimeofday(&t2, NULL);
1010 if (ret != 0) {
1011 int strErr=snprintf(reason, rLen, "pcp_pmFetch failed, retcode=%d.", ret);
1012 reason[rLen-1]=0;
1013 if (strErr > rLen) HANDLE_STRING_ERROR;
1015 goto fn_fail;
1016 }
1017
1018 _time_fprintf(stderr, "pmFetch for all took %li uS, for %i events; ret=%i.\n",
1020
1021 //-------------------------------------------------------------------
1022 // In processing fetches, if we find a multi-valued event, we need
1023 // to force an event for every value (PAPI only returns 1 value per
1024 // event; not an array). In experiments thus far, all multi-valued
1025 // events have had domain descriptor names; so we just concat with
1026 // the name and make a new Event. We use a helper for that,
1027 // afterward we set the number of values in the original 'base name'
1028 // to zero; so it will be deleted by the cleanup routine.
1029 //-------------------------------------------------------------------
1030
1031 _time_gettimeofday(&t1, NULL); // time this index explosion.
1032 int origEventCount = sEventCount; // sEventCount may change in below routine.
1033
1034 for (i=0; i<origEventCount; i++) { // process all the fetch results.
1035 pcp_event_info[i].desc.pmid = PM_ID_NULL; // This indicates the description is NOT loaded yet.
1036 pmValueSet *vset = allFetch->vset[i]; // get the result for event[i].
1037
1038 // On Saturn test system, never saw this happen.
1039 if (vset == NULL) { // .. should not happen. leave numVal=0 for deletion.
1040 fprintf(stderr, "%s:%i vset=NULL for name='%s'\n",
1041 __FILE__, __LINE__, pcp_event_info[i].name);
1042 continue; // .. next in loop.
1043 }
1044
1045 pcp_event_info[i].numVal = vset->numval; // Show we have a value.
1046 if (vset->numval == 0) { // If the value is zero,
1047// _prog_fprintf(stderr, "%s:%i Discarding, no values for event '%s'.\n", __FILE__, __LINE__, pcp_event_info[i].name);
1048 continue; // If no values, leave numVal = 0 for deletion. (We do see this in tests).
1049 }
1050
1051 pcp_event_info[i].valfmt = vset->valfmt; // Get the value format. (INSITU or not).
1052 getPMDesc(i); // Get the value descriptor.
1053 unsigned long long ullval= (long long) -1; // debug stuff.
1054 convert_64_t convert;
1055
1056 if (vset->valfmt != PM_VAL_INSITU) { // If not in situ, must get the type.
1057 pmValue *pmval = &vset->vlist[0]; // .. Get the first value.
1058 pmValueBlock *pB = pmval->value.pval; // .. get it.
1059 if (pcp_event_info[i].valType != pB->vtype) {
1060 int strErr=snprintf(reason, rLen, "Unexpected value type fetched for %s. %i vs %i. Possible version incompatibiity.\n",
1061 pcp_event_info[i].name, pcp_event_info[i].valType, pB->vtype);
1062 reason[rLen-1]=0;
1063 if( strErr > rLen) HANDLE_STRING_ERROR;
1065 goto fn_fail;
1066 }
1067
1068// pcp_event_info[i].valType = pB->vtype; // .. get the type.
1069 ullval = getULLValue(vset, 0); // .. get the first value.
1070
1071 switch(pB->vtype) { // PCP's variable type; an int flag.
1072 case PM_TYPE_32: // 32-bit signed integer
1073 _prog_fprintf(stderr, "type I32, desc.sem=%i, event '%s'=", pcp_event_info[i].desc.sem, pcp_event_info[i].name);
1074 break;
1075 case PM_TYPE_U32: // 32-bit unsigned integer
1076 _prog_fprintf(stderr, "type U32, desc.sem=%i, event '%s'=", pcp_event_info[i].desc.sem, pcp_event_info[i].name);
1077 break;
1078 case PM_TYPE_FLOAT: // 32-bit floating point
1079 _prog_fprintf(stderr, "type F32, desc.sem=%i, event '%s'=", pcp_event_info[i].desc.sem, pcp_event_info[i].name);
1080 break; // END CASE.
1081
1082 case PM_TYPE_64: // 64-bit signed integer
1083 convert.ull = ullval;
1084 _prog_fprintf(stderr, "type I64, desc.sem=%i, event '%s'= (ll) %lli =", pcp_event_info[i].desc.sem, pcp_event_info[i].name, convert.ll);
1085 break;
1086 case PM_TYPE_U64: // 64-bit unsigned integer
1087 _prog_fprintf(stderr, "type U64, desc.sem=%i, event '%s'= (ull) %llu =", pcp_event_info[i].desc.sem, pcp_event_info[i].name, convert.ull);
1088 break;
1089 case PM_TYPE_DOUBLE: // 64-bit floating point
1090 convert.ull = ullval;
1091 _prog_fprintf(stderr, "type U64, desc.sem=%i, event '%s'= (double) %f =", pcp_event_info[i].desc.sem, pcp_event_info[i].name, convert.d);
1092 break; // END CASE.
1093
1094 // IF YOU want to return string values, this is a place
1095 // to change; currently all string-valued events are
1096 // rejected. But, pB->vbuf is the string value. I would
1097 // copy it into a new pcp_event_info[] field; it would
1098 // need to be malloc'd here and free'd at component
1099 // shutdown. Also PAPI would need a new way to accept a
1100 // char* or void*.
1101
1102 case PM_TYPE_STRING: // pB->vbuf is char* to string value.
1103 _prog_fprintf(stderr, "%s:%i Discarding PM_TYPE_STRING event, desc.sem=%i, event '%s'=", __FILE__, __LINE__, pcp_event_info[i].desc.sem, pcp_event_info[i].name);
1104 pcp_event_info[i].numVal = 0; // .. .. set numVal = 0 for deletion.
1105 break;
1106
1107 default: // If we don't recognize the type,
1108 _prog_fprintf(stderr, "%s:%i Dsicarding PM_UNKNOWN_TYPE event, desc.sem=%i, event '%s'=", __FILE__, __LINE__, pcp_event_info[i].desc.sem, pcp_event_info[i].name);
1109 pcp_event_info[i].numVal = 0; // .. set numVal = 0 for deletion.
1110 break;
1111 } // end switch.
1112 } // If not In Situ.
1113 else {
1114 _prog_fprintf(stderr, "type IST, desc.sem=%i, event '%s'=", pcp_event_info[i].desc.sem, pcp_event_info[i].name);
1115 }
1116
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]);
1119 // Lookup description takes time; so we only do it for
1120 // multi-valued events here. For other events, we will do it
1121 // as needed for EventInfo filling.
1122
1123 if (pcp_event_info[i].numVal > 1) { // If a domain qualifier is possible;
1124 getPMDesc(i); // .. Get the event descriptor.
1125 _prog_fprintf(stderr, "Event %s has %i values, indom=%i.\n", pcp_event_info[i].name, pcp_event_info[i].numVal, pcp_event_info[i].desc.indom);
1126 if (pcp_event_info[i].desc.indom != PM_INDOM_NULL) { // .. If we have a non-null domain,
1127 for (j=0; j<vset->numval; j++) { // .. for every value present,
1128 pmValue *pmval = &vset->vlist[j]; // .. .. get that guy.
1129
1130 char *dname = cachedGetInDom( // .. .. read from cached domains (and populate it when needed).
1131 pcp_event_info[i].desc.indom,
1132 pmval->inst); // .. .. get the name. Not malloced so don't free dName.
1133
1134 makeQualifiedEvent(i, j, dname); // .. .. helper routine; may realloc pcp_event_info[], change sEventCount.
1135 } // end value list.
1136
1137 pcp_event_info[i].numVal = 0; // .. let the base event be discarded.
1138 } // end if we have a domain.
1139 } // end if multiple valued.
1140 } // end for each event.
1141
1142 // Trim the fat! We get rid of everything with numVal == 0.
1143 // We do that by compaction; moving valid entries to backfill
1144 // invalid ones.
1145
1146 j=0; // first destination.
1147 for (i=0; i<sEventCount; i++) { // loop thorugh all old and new.
1148 if (pcp_event_info[i].numVal > 0) { // If we have a valid entry,
1149 if (i != j) pcp_event_info[j] = pcp_event_info[i]; // move if it isn't already there.
1150 j++; // count one moved; new count of valid ones.
1151 }
1152 }
1153
1154 sEventCount = j; // this is our new count.
1155 pcp_event_info = realloc(pcp_event_info, // release any extra memory.
1156 sEventCount*sizeof(_pcp_event_info_t)); // ..
1157 if (pcp_event_info == NULL) {
1158 int strErr=snprintf(reason, rLen,
1159 "Could not reallocate %lu bytes of memory for pcp_event_info.", sEventCount*sizeof(_pcp_event_info_t));
1160 reason[rLen-1]=0; // force null termination.
1161 if (strErr > rLen) HANDLE_STRING_ERROR;
1163 goto fn_fail;
1164 } // end if realloc failed.
1165
1166 qsort(pcp_event_info, sEventCount, // sort by PMID, idx, name.
1167 sizeof(_pcp_event_info_t), qsPMID); // ..
1168
1169 _time_gettimeofday(&t2, NULL); // done with index explosion.
1170 _time_fprintf(stderr, "indexedExplosion for all took %li uS.\n",
1172
1173 for (i=0; i<HASH_SIZE; i++) { // init hash table.
1174 sNameHash[i].idx = -1; // unused entry.
1175 sNameHash[i].next = NULL; // ..
1176 }
1177
1178 unsigned int myHash;
1179 for (i=0; i<sEventCount; i++) {
1180 myHash = addNameHash(pcp_event_info[i].name, i); // Point this hash to this entry.
1181 }
1182
1183 //-----------------------------------------------------------------------------------------------------------------------
1184 // *************************************** DEBUG REPORT OF INFORMATION DISCOVERED ***************************************
1185 //-----------------------------------------------------------------------------------------------------------------------
1186 // We use -O2, but even in -O0, if(0){...} is completely removed from code. It costs us nothing to leave this code in.
1187 if (0) { // change to 1 to enable debug report.
1188 unsigned int current, prev=0;
1189 printf("count, hash, name, pmid, value[idx]\n");
1190 for (i=0; i<sEventCount; i++) {
1191 myHash = stringHash(pcp_event_info[i].name, HASH_SIZE); // Get the hash value.
1192 current = pcp_event_info[i].pmid;
1193 if (prev > 0 && current != (prev+1) && current != prev) // print separators.
1194 printf("----,----,----,----\n");
1195 printf("%i, %u, \"%s\", 0x%08X, %i\n", i, myHash, // quote name, may contain \,/,comma, etc.
1197 pcp_event_info[i].pmid,
1198 pcp_event_info[i].idx);
1199 prev=current; // for finding pmid skips.
1200 }
1201
1202 // Test hashing.
1203 int hashErr = 0;
1204 _time_gettimeofday(&t1, NULL);
1205 for (i=0; i<sEventCount; i++) {
1206 int f = findNameHash(pcp_event_info[i].name); // Try to find this name.
1207 if (f != i) hashErr++;
1208 }
1209
1210 _time_gettimeofday(&t2, NULL);
1211
1212 _time_fprintf(stderr, "HashLookup avg uS: %3.6f\n", ((double) (mConvertUsec(t2)-mConvertUsec(t1)) )/((double) sEventCount) );
1213 _time_fprintf(stderr, "Hash Errors: %i of %i.\n", hashErr, sEventCount);
1214
1215 } // END DEBUG REPORT.
1216 //-----------------------------------------------------------------------------------------------------------------------
1217 // *************************************** END DEBUG REPORT INFORMATION DISCOVERED **************************************
1218 //-----------------------------------------------------------------------------------------------------------------------
1219
1220 free(allNames); // Locals allocations not needed anymore.
1221 free(allPMID); // .. the pmIDs we read.
1222 pcp_pmFreeResult(allFetch); // .. release the results we fetched.
1223
1224// For PCP, we can read any number of events at once
1225// in a single event set. Set vector elements for PAPI.
1226
1227 _pcp_vector.cmp_info.num_native_events = sEventCount; // Setup our pcp vector.
1230 _pcp_vector.cmp_info.CmpIdx = cidx; // export the component ID.
1231
1232 fn_exit:
1233 _papi_hwd[cidx]->cmp_info.disabled = retval;
1234 return retval;
1235 fn_fail:
1236 goto fn_exit;
1237} // end routine.
int i
struct papi_vectors * _papi_hwd[]
double f(double a)
Definition: cpi.c:23
volatile double t1
#define PAPI_ESYS
Definition: f90papi.h:136
#define PAPI_ENOMEM
Definition: f90papi.h:16
#define PAPI_EBUF
Definition: f90papi.h:253
#define PAPI_ENOIMPL
Definition: f90papi.h:219
static unsigned long long getULLValue(pmValueSet *vset, int value_index)
Definition: linux-pcp.c:689
static int _local_linkDynamicLibraries(void)
Definition: linux-pcp.c:419
#define mConvertUsec(timeval_)
Definition: linux-pcp.c:239
#define _time_gettimeofday
Definition: linux-pcp.c:244
static unsigned int stringHash(char *str, unsigned int tableSize)
Definition: linux-pcp.c:320
static void pcp_pmFreeResult(pmResult *result)
Definition: linux-pcp.c:287
static char * pcp_pmErrStr(int code)
Definition: linux-pcp.c:281
#define LNBLOCK
#define _prog_fprintf
Definition: linux-pcp.c:242
static int ctxHandle
Definition: linux-pcp.c:192
static int sEventInfoBlock
Definition: linux-pcp.c:189
#define AGENT_NAME
Definition: linux-pcp.c:42
static void makeQualifiedEvent(int baseEvent, int idx, char *qualifier)
Definition: linux-pcp.c:532
static int _pcp_init_component(int cidx)
Definition: linux-pcp.c:856
static int sEventCount
Definition: linux-pcp.c:191
static void cbPopulateNameOnly(const char *name)
Definition: linux-pcp.c:511
static int pcp_pmTraversePMNS(const char *name, void(*func)(const char *))
Definition: linux-pcp.c:284
#define hostnameLen
#define PM_CONTEXT_HOST
Definition: linux-pcp.c:58
#define _time_fprintf
Definition: linux-pcp.c:243
static _pcp_hash_t sNameHash[HASH_SIZE]
Definition: linux-pcp.c:195
static unsigned int addNameHash(char *key, int idx)
Definition: linux-pcp.c:336
static int findNameHash(char *key)
Definition: linux-pcp.c:377
static int sEventInfoSize
Definition: linux-pcp.c:188
static _pcp_event_info_t * pcp_event_info
Definition: linux-pcp.c:190
static struct timeval t1 t2
Definition: linux-pcp.c:238
#define HASH_SIZE
Definition: linux-pcp.c:194
static int pcp_pmNewContext(int type, const char *name)
Definition: linux-pcp.c:290
static void getPMDesc(int pcpIdx)
Definition: linux-pcp.c:576
static int qsPMID(const void *arg1, const void *arg2)
Definition: linux-pcp.c:490
static int pcp_pmFetch(int numpid, pmID *pmidlist, pmResult **result)
Definition: linux-pcp.c:296
static char * cachedGetInDom(pmInDom indom, int inst)
Definition: linux-pcp.c:612
static int cidx
const char * name
Definition: rocs.c:225
long long int long long
Definition: sde_internal.h:85
char name[PAPI_MAX_STR_LEN]
Definition: linux-pcp.c:108
void * next
Definition: linux-pcp.c:165
unsigned long long ull
Definition: benchSANVML.c:138
unsigned char ch[8]
Definition: benchSANVML.c:141
long long ll
Definition: benchSANVML.c:137
int retval
Definition: zero_fork.c:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_init_control_state()

static int _pcp_init_control_state ( hwd_control_state_t ctl)
static

Definition at line 1262 of file linux-pcp.c.

1263{
1264 mRtnCnt(_pcp_init_control_state); // count this function.
1265 _pcp_control_state_t* control = ( _pcp_control_state_t* ) ctl;
1266 // contents: _pcp_control_state state at this writing:
1267 // contents of state:
1268 // int numEvents; // The number of events we have.
1269 // int maxAllocated; // the current entries in pcpIndex.
1270 // int *pcpIndex; // array of indices into pcp_event_info[].
1271 // long long *values; // Values read from our PCP events.
1272
1273 memset(control, 0, sizeof(_pcp_control_state_t)); // zero it.
1274
1275 return PAPI_OK;
1276} // end routine.
static int _pcp_init_control_state(hwd_control_state_t *ctl)
Definition: linux-pcp.c:1262
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_init_thread()

static int _pcp_init_thread ( hwd_context_t ctx)
static

Definition at line 1250 of file linux-pcp.c.

1251{
1252 mRtnCnt(_pcp_init_thread); // count this function.
1253 _pcp_context_t* myCtx = (_pcp_context_t*) ctx; // recast.
1254 myCtx->initDone = 1; // Nothing else to do for init.
1255 return PAPI_OK;
1256} // end routine.
static int _pcp_init_thread(hwd_context_t *ctx)
Definition: linux-pcp.c:1250
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_ntv_code_to_descr()

static int _pcp_ntv_code_to_descr ( unsigned int  pcpIdx,
char *  descr,
int  len 
)
static

Definition at line 1794 of file linux-pcp.c.

1795{
1796 mRtnCnt(_pcp_ntv_code_to_descr); // count this function.
1797
1798 pcpIdx &= PAPI_NATIVE_AND_MASK; // We might be called with the NATIVE bit set.
1799 if (pcpIdx >= (unsigned int) sEventCount) { // out of range?
1800 fprintf(stderr, "%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1801 __FILE__, __LINE__, FUNC, pcpIdx);
1802 return PAPI_EINVAL; // exit with error.
1803 }
1804
1805 if (len < 1) { // If length is ridiculous,
1806 fprintf(stderr, "%s:%i:%s called with out-of-range descr len=%i.\n",
1807 __FILE__, __LINE__, FUNC, len);
1808 return PAPI_EINVAL; // exit with error.
1809 }
1810
1811 char *helpText = NULL; // pointer to receive the result.
1812 int ret = getHelpText(pcpIdx, &helpText); // get it.
1813 if (ret != PAPI_OK) { // If there is any error,
1814 if (helpText != NULL) free(helpText); // .. no memory leak.
1815 fprintf(stderr, "%s:%i:%s failed getHelpText; it returned %s.\n",
1816 __FILE__, __LINE__, FUNC, PAPI_strerror(ret));
1817 return ret; // exit with whatever PAPI error routine had.
1818 }
1819
1820 strncpy(descr, helpText, len); // copy it over.
1821 descr[len-1] = 0; // force a z-terminator.
1822 free(helpText); // release text alloc by pm routine.
1823 return PAPI_OK; // EXIT, all good.
1824} // end routine.
Returns a string describing the PAPI error code.
static int getHelpText(unsigned int pcpIdx, char **helpText)
Definition: linux-pcp.c:815
static int _pcp_ntv_code_to_descr(unsigned int pcpIdx, char *descr, int len)
Definition: linux-pcp.c:1794
#define PAPI_NATIVE_AND_MASK
char * descr
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_ntv_code_to_info()

static int _pcp_ntv_code_to_info ( unsigned int  pcpIdx,
PAPI_event_info_t info 
)
static

Definition at line 1847 of file linux-pcp.c.

1848{
1849 mRtnCnt(_pcp_ntv_code_to_info); // count this function.
1850 int len, ret;
1851
1852 pcpIdx &= PAPI_NATIVE_AND_MASK; // remove any high order bits.
1853 if (pcpIdx >= (unsigned int) sEventCount) { // out of range?
1854 fprintf(stderr, "%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1855 __FILE__, __LINE__, FUNC, pcpIdx);
1856 return PAPI_EINVAL; // exit with error.
1857 }
1858
1859 len=sizeof(info->symbol); // get length.
1860 strncpy(info->symbol, pcp_event_info[pcpIdx].name, len); // Copy.
1861 info->symbol[len-1] = 0; // force z-terminator.
1862
1863 len=sizeof(info->long_descr); // get length.
1864 ret = _pcp_ntv_code_to_descr(pcpIdx, info->long_descr, len); // copy to info.
1865 if (ret != PAPI_OK) return(ret); // return on failure. _pcp_ntv_code_to_descr already printed error.
1866
1867 // Units resides in pmDesc; we need to get it if we don't already
1868 // have it (multi-valued events got it during init).
1869
1870 getPMDesc(pcpIdx); // get the description.
1871
1872 char unitStr[64];
1873 // This routine has been timed over 19600 trials on Saturn;
1874 // it requires an average of 2 uS. No daemon comm needed.
1875
1876 pcp_pmUnitsStr_r(&pcp_event_info[pcpIdx].desc.units, unitStr, 64); // Construct the unit string; needs at least 60 char.
1877 if ( strlen(unitStr) == 0) {
1878 sprintf(unitStr, "fraction"); // Only ever seen for 'dutycycle' events.
1879
1880 // Following is for debug purposes.
1881 if (0) { // Alternatively, show the details of the PCP units descriptor.
1882 sprintf(unitStr, "[%u, %i, %u, %u, %i, %i, %i]",
1883 pcp_event_info[pcpIdx].desc.units.pad,
1884 pcp_event_info[pcpIdx].desc.units.scaleCount,
1885 pcp_event_info[pcpIdx].desc.units.scaleTime,
1886 pcp_event_info[pcpIdx].desc.units.scaleSpace,
1887 pcp_event_info[pcpIdx].desc.units.dimCount,
1888 pcp_event_info[pcpIdx].desc.units.dimTime,
1889 pcp_event_info[pcpIdx].desc.units.dimSpace
1890 );
1891 }
1892 }
1893
1894 len = sizeof(info->units); // length of destination.
1895 strncpy( info->units, unitStr, len); // copy it over.
1896 info->units[len-1] = 0; // ensure a z-terminator.
1897
1898 switch (pcp_event_info[pcpIdx].valType) { // Translate this to a papi value.
1899
1900 case PM_TYPE_32: // 32 bit was converted to long long.
1901 case PM_TYPE_64: // long long.
1902 info->data_type = PAPI_DATATYPE_INT64; // What papi needs.
1903 break; // END CASE.
1904
1905 case PM_TYPE_U32: // 32-bit was converted to 64 bit.
1906 case PM_TYPE_U64: // 64-bit unsigned integer
1907 case PM_TYPE_STRING: // array of char pointer.
1908 info->data_type = PAPI_DATATYPE_UINT64; // What papi needs.
1909 break; // END CASE.
1910
1911 case PM_TYPE_FLOAT: // 32-bit was converted to double.
1912 case PM_TYPE_DOUBLE: // 64-bit floating point
1913 info->data_type = PAPI_DATATYPE_FP64; // What papi needs.
1914 break; // END CASE.
1915 };
1916
1917 if (pcp_event_info[pcpIdx].desc.sem == PM_SEM_COUNTER) { // If we have a counter,
1918 info->timescope = PAPI_TIMESCOPE_SINCE_START; // .. normal stuff.
1919 } else { // An instantaneous value.
1920 info->timescope = PAPI_TIMESCOPE_POINT; // .. What PAPI calls that.
1921 }
1922
1923 return PAPI_OK; // exit.
1924} // end routine.
#define PAPI_TIMESCOPE_POINT
Definition: f90papi.h:63
#define PAPI_DATATYPE_FP64
Definition: f90papi.h:171
#define PAPI_DATATYPE_UINT64
Definition: f90papi.h:278
#define PAPI_TIMESCOPE_SINCE_START
Definition: f90papi.h:124
#define PAPI_DATATYPE_INT64
Definition: f90papi.h:227
static char * pcp_pmUnitsStr_r(const pmUnits *pu, char *buf, int buflen)
Definition: linux-pcp.c:308
static int _pcp_ntv_code_to_info(unsigned int pcpIdx, PAPI_event_info_t *info)
Definition: linux-pcp.c:1847
char units[PAPI_MIN_STR_LEN]
Definition: papi.h:969
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:960
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:963
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_ntv_code_to_name()

static int _pcp_ntv_code_to_name ( unsigned int  pcpIdx,
char *  name,
int  len 
)
static

Definition at line 1765 of file linux-pcp.c.

1766{
1767 mRtnCnt(_pcp_ntv_code_to_name); // count this function.
1768
1769 pcpIdx &= PAPI_NATIVE_AND_MASK; // We can be called with the NATIVE bit set.
1770 if (pcpIdx >= (unsigned int) sEventCount) { // out of range?
1771 fprintf(stderr, "%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1772 __FILE__, __LINE__, FUNC, pcpIdx);
1773 return PAPI_EINVAL; // exit with error.
1774 }
1775
1776 if (len < 1) { // If length is ridiculous,
1777 fprintf(stderr, "%s:%i:%s called with out-of-range descr len=%i.\n",
1778 __FILE__, __LINE__, FUNC, len);
1779 return PAPI_EINVAL; // exit with error.
1780 }
1781
1782 strncpy(name, pcp_event_info[pcpIdx].name, len); // just copy the name.
1783 name[len-1]=0; // force z-termination.
1784
1785 return PAPI_OK;
1786} // end routine.
static int _pcp_ntv_code_to_name(unsigned int pcpIdx, char *name, int len)
Definition: linux-pcp.c:1765
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_ntv_enum_events()

static int _pcp_ntv_enum_events ( unsigned int EventCode,
int  modifier 
)
static

Definition at line 1698 of file linux-pcp.c.

1699{
1700 mRtnCnt(_pcp_ntv_enum_events); // count this function.
1701 int idx;
1702
1703 switch (modifier) { // modifier is type of enum operation desired.
1704 case PAPI_ENUM_FIRST: // Returns event code of first event created.
1705 EventCode[0] = 0; // Return 0 as event code after a start.
1706 return PAPI_OK; // EXIT.
1707 break; // END CASE.
1708
1709 // return EventCode of next available event.
1710 case PAPI_ENUM_EVENTS: // enum base events (which is all events).
1711 idx = EventCode[0] & PAPI_NATIVE_AND_MASK; // Take off any hi order flag bits.
1712 if ((++idx) >= sEventCount) return PAPI_ENOEVNT; // If we reach an invalid idx for pcp_event_info[], exit. Does nothing to EventCode.
1713 EventCode[0] = idx | PAPI_NATIVE_MASK; // If index was valid, we return it.
1714 return PAPI_OK; // And exit.
1715 break; // END CASE.
1716
1717 case PAPI_NTV_ENUM_UMASKS: // Note we HAVE no qualifiers or masks.
1718 return PAPI_ENOEVNT; // There are no qualifiers to list.
1719
1720 default: // If we don't understand the modifier,
1721 return PAPI_ENOEVNT; // .. Presets or other stuff, just say we have none.
1722 break; // END CASE.
1723 } // end switch(modifier).
1724
1725 return PAPI_EBUG; // Dummy return; should have exited from inside switch.
1726} // end routine.
#define PAPI_ENUM_EVENTS
Definition: f90papi.h:224
#define PAPI_EBUG
Definition: f90papi.h:176
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_NTV_ENUM_UMASKS
Definition: f90papi.h:66
static int _pcp_ntv_enum_events(unsigned int *EventCode, int modifier)
Definition: linux-pcp.c:1698
#define PAPI_NATIVE_MASK
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_ntv_name_to_code()

static int _pcp_ntv_name_to_code ( const char *  name,
unsigned int event_code 
)
static

Definition at line 1732 of file linux-pcp.c.

1733{
1734 mRtnCnt(_pcp_ntv_name_to_code); // count this function.
1735
1736 if (name == NULL || strlen(name)<1) { // Invalid name argument.
1737 fprintf(stderr, "%s:%i:%s Invalid name.\n", // .. report it.
1738 __FILE__, __LINE__, FUNC);
1739 return PAPI_EINVAL; // .. Invalid argument.
1740 }
1741
1742 if (event_code == NULL) { // Invalid event_code pointer.
1743 fprintf(stderr, "%s:%i:%s event_code is not a valid pointer.\n", // .. report it.
1744 __FILE__, __LINE__, FUNC);
1745 return PAPI_EINVAL; // .. Invalid argument.
1746 }
1747
1748 int idx = findNameHash((char*) name); // Use our hash to find it.
1749 if (idx < 0) { // If we failed,
1750 fprintf(stderr, "%s:%i:%s Failed to find name='%s', hash=%i.\n", // .. report it.
1751 __FILE__, __LINE__, FUNC, name,
1752 stringHash((char*) name, HASH_SIZE)); // ..
1753 return PAPI_EINVAL; // .. Invalid argument.
1754 }
1755
1756 *event_code = idx; // return with the index we found.
1757 return PAPI_OK;
1758} // end routine.
static int _pcp_ntv_name_to_code(const char *name, unsigned int *event_code)
Definition: linux-pcp.c:1732
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_read()

static int _pcp_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
)
static

Definition at line 1529 of file linux-pcp.c.

1533{
1534 mRtnCnt(_pcp_read); // count this function.
1535 (void) ctx; // avoid unused var warning.
1536 (void) flags; // ..
1537
1538 _pcp_control_state_t* myCtl = ( _pcp_control_state_t* ) ctl; // make a shortcut.
1539 int i, ret;
1540 pmResult *allFetch; // vars to be allocated by call.
1541 if (events == NULL) {
1542 fprintf(stderr, "%s:%i:%s 'events' is null.\n",
1543 __FILE__, __LINE__, FUNC); // report error.
1544 return(PAPI_EINVAL); // invalid argument.
1545 }
1546
1547 ret = PCP_ReadList(ctl, &allFetch); // Read the list of events we were given.
1548 if (ret != PAPI_OK) { // If that failed,
1549 fprintf(stderr, "%s:%i:%s PCP_ReadList failed, return=%s.\n",
1550 __FILE__, __LINE__, FUNC, PAPI_strerror(ret)); // report error.
1551 return(ret); // exit with that error.
1552 }
1553
1554 // We have all the results and values extracted from them.
1555 // Now subtract zero value from them.
1556
1557 for (i=0; i<myCtl->numEvents; i++) { // for each event,
1558 subZero(myCtl, i); // .. subtract zero value in proper type. [TONY DON"T COMMENT OUT, JUST DEBUG]
1559 } // end loop through all events in this event set.
1560
1561 // Done, point the caller to our results list.
1562 *events = (long long *) myCtl->pcpValue; // pointer the caller needs.
1563 pcp_pmFreeResult(allFetch); // Clean up.
1564 return PAPI_OK; // exit, all okay.
1565} // end routine.
char events[MAX_EVENTS][BUFSIZ]
static int _pcp_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
Definition: linux-pcp.c:1529
static void subZero(_pcp_control_state_t *myCtl, int event)
Definition: linux-pcp.c:763
static int PCP_ReadList(hwd_control_state_t *ctl, pmResult **results)
Definition: linux-pcp.c:1392
unsigned long long * pcpValue
Definition: linux-pcp.c:144
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_reset()

static int _pcp_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Definition at line 1469 of file linux-pcp.c.

1470{
1471 mRtnCnt(_pcp_reset); // count this function.
1472 ( void ) ctx; // avoid unused var warning.
1473 int i, k, ret;
1474 unsigned long long aValue;
1475
1476 pmResult *allFetch; // vars to be allocated by call.
1477 _pcp_control_state_t* myCtl = ( _pcp_control_state_t* ) ctl; // make a shortcut.
1478
1479 ret = PCP_ReadList(ctl, &allFetch); // Read the list of events we were given.
1480 if (ret != PAPI_OK) { // If that failed,
1481 fprintf(stderr, "%s:%i:%s PCP_ReadList failed, return=%s.\n",
1482 __FILE__, __LINE__, FUNC, PAPI_strerror(ret)); // report error.
1483 if (allFetch != NULL) pcp_pmFreeResult(allFetch); // free if it was allocated.
1484 return(ret); // exit with that error.
1485 }
1486
1487 // We have all the results; the values read have been extracted
1488 // and stored the control state. Now set them as the zeroValue
1489 // in each pcp_event_info[].
1490
1491 for (i=0; i<myCtl->numEvents; i++) { // for each event,
1492 k = myCtl->pcpIndex[i]; // .. get pcp_event_info[] index.
1493 aValue = myCtl->pcpValue[i]; // .. get the value for that event.
1494 pcp_event_info[k].zeroValue = aValue; // .. reset the counter.
1495 } // end loop through all events in this event set.
1496
1497 // That is all we do; reset the zeroValue to the current value.
1498 // For efficiency we do not check if it is a counter, instantaneous
1499 // or discrete value; that is done in subZero.
1500 pcp_pmFreeResult(allFetch); // .. Clean up.
1501 return PAPI_OK;
1502} // end routine.
static int _pcp_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-pcp.c:1469
unsigned long long zeroValue
Definition: linux-pcp.c:116
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_set_domain()

static int _pcp_set_domain ( hwd_control_state_t ctl,
int  domain 
)
static

Definition at line 1678 of file linux-pcp.c.

1679{
1680 mRtnCnt(_pcp_set_domain); // count this function.
1681 (void) ctl; // avoid var unused warning.
1682 if ( PAPI_DOM_ALL != domain ) return PAPI_EINVAL; // Reject if not this one.
1683 return PAPI_OK; // Otherwise, OK, nothing to do.
1684} // end routine.
#define PAPI_DOM_ALL
Definition: f90papi.h:261
static int _pcp_set_domain(hwd_control_state_t *ctl, int domain)
Definition: linux-pcp.c:1678
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_shutdown_component()

static int _pcp_shutdown_component ( void  )
static

Definition at line 1595 of file linux-pcp.c.

1596{
1597 int i;
1598 mRtnCnt(_pcp_shutdown_component); // count this function.
1599 pcp_pmDestroyContext(ctxHandle); // context handle; fails to free malloced memory, says valgrind.
1600 ctxHandle = -1; // reset to prevent reuse.
1601 free(pcp_event_info); pcp_event_info=NULL; // then pcp_event_info, reset.
1602 freeNameHash(); // free sNameHash. resets itself.
1603 cachedGetInDom(PM_INDOM_NULL, -1); // -1 for inst == free its local static mallocs.
1604 sEventCount = 0; // clear number of events.
1605
1606 for (i=0; i<=ctr_pcp_ntv_code_to_info; i++)
1607 _prog_fprintf(stderr, "routine counter %i = %i.\n", i, cnt[i]);
1608
1609 return PAPI_OK;
1610} // end routine.
static int _pcp_shutdown_component(void)
Definition: linux-pcp.c:1595
static int pcp_pmDestroyContext(int handle)
Definition: linux-pcp.c:293
static void freeNameHash(void)
Definition: linux-pcp.c:358
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_shutdown_thread()

static int _pcp_shutdown_thread ( hwd_context_t ctx)
static

Definition at line 1583 of file linux-pcp.c.

1584{
1585 mRtnCnt(_pcp_shutdown_thread); // count this function.
1586 ( void ) ctx; // avoid var unused warning.
1587
1588 return PAPI_OK;
1589} // end routine.
static int _pcp_shutdown_thread(hwd_context_t *ctx)
Definition: linux-pcp.c:1583
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_start()

static int _pcp_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Definition at line 1510 of file linux-pcp.c.

1511{
1512 mRtnCnt(_pcp_start); // count this function.
1513 _pcp_reset(ctx, ctl); // Just reset counters.
1514 return PAPI_OK;
1515} // end routine.
static int _pcp_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-pcp.c:1510
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_stop()

static int _pcp_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Definition at line 1571 of file linux-pcp.c.

1572{
1573 mRtnCnt(_pcp_stop); // count this function.
1574 (void) ctx; // avoid var unused warning.
1575 (void) ctl; // avoid var unused warning.
1576 return PAPI_OK;
1577} // end routine.
static int _pcp_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-pcp.c:1571
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _pcp_update_control_state()

static int _pcp_update_control_state ( hwd_control_state_t ctl,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
)
static

Definition at line 1305 of file linux-pcp.c.

1310{
1311 mRtnCnt(_pcp_update_control_state); // count this function.
1312 int i, index = 0;
1313 ( void ) ctx;
1314
1315 _pcp_control_state_t* MyCtl = ( _pcp_control_state_t* ) ctl; // Recast ctl.
1316
1317 MyCtl->numEvents = count; // remember how many there are.
1318 if (count == 0) { // If we are deleting a set,
1319 if (MyCtl->pcpIndex != NULL) { // If we have space allocated,
1320 free(MyCtl->pcpIndex); // .. discard it,
1321 free(MyCtl->pcpValue); // .. and values.
1322 MyCtl->pcpIndex = NULL; // .. never free it again.
1323 MyCtl->pcpValue = NULL; // .. never free it again.
1324 }
1325
1326 MyCtl->maxAllocated = 0; // .. no longer tracking max.
1327 return PAPI_OK; // .. get out.
1328 }
1329
1330 // henceforth, count != 0.
1331 #define BlockSize 64 /* constant used multiple times. */
1332 int newalloc = ((count/BlockSize)*BlockSize+BlockSize); // .. pick next up multiple of BlockSize.
1333 #undef BlockSize /*prevent bugs if same name used elsewhere.*/
1334
1335 if (MyCtl->pcpIndex != NULL) { // If I have a previous list of variables,
1336 if (count > MyCtl->maxAllocated) { // .. If I will need more room,
1337 MyCtl->pcpIndex = realloc(MyCtl->pcpIndex, // .. .. reallocate to make more room.
1338 newalloc*sizeof(int)); // .. .. ..
1339 MyCtl->pcpValue = realloc(MyCtl->pcpValue, // .. .. reallocate to make more room.
1340 newalloc*sizeof(unsigned long long));// .. .. ..
1341 MyCtl->maxAllocated = newalloc; // .. .. remember what we've got.
1342 }
1343 } else { // If NULL then I have no previous set,
1344 MyCtl->maxAllocated = newalloc; // .. pick next up multiple of BlockSize.
1345 MyCtl->pcpIndex = // .. make room for 'count' indices,
1346 calloc(MyCtl->maxAllocated, sizeof(int)); // ..
1347 MyCtl->pcpValue = // .. make room for 'count' values.
1348 calloc(MyCtl->maxAllocated, sizeof(unsigned long long)); // ..
1349 }
1350
1351 if (MyCtl->pcpIndex == NULL) { // If malloc failed,
1352 return PAPI_ENOMEM; // .. out of memory.
1353 } // end if malloc failed.
1354
1355 //------------------------------------------------------------------
1356 // pcpIndex alloc managed, now process all events passed in.
1357 // pcpIndex[i] holds the event pcp_event_info[] index for
1358 // EventSet[i], and we populate the caller's ni_position for
1359 // EventSet[i] with the index into pcpIndex[].
1360 //------------------------------------------------------------------
1361
1362 for (i=0; i<count; i++) { // for each event passed in,
1363 index = native[i].ni_event & PAPI_NATIVE_AND_MASK; // get index.
1364 if (index < 0 || index >= sEventCount) { // if something is wrong,
1365 return PAPI_ENOEVNT; // no such event.
1366 } // end if index invalid.
1367
1368 MyCtl->pcpIndex[i]=index; // remember the index.
1369 MyCtl->pcpValue[i]=0; // clear the value.
1370 native[i].ni_position = i; // Tell PAPI about its location (doesn't matter to us), we have no restrictions on position.
1371 getPMDesc(index); // Any time an event is added, ensure we have its variable descriptor.
1372 } // end for each event listed.
1373
1374 return PAPI_OK;
1375} // end routine.
static long count
#define BlockSize
static int _pcp_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
Definition: linux-pcp.c:1305
static int native
Here is the call graph for this function:
Here is the caller graph for this function:

◆ addNameHash()

static unsigned int addNameHash ( char *  key,
int  idx 
)
static

Definition at line 336 of file linux-pcp.c.

337{
338 unsigned int slot = stringHash(key, HASH_SIZE); // compute hash code.
339 if (sNameHash[slot].idx < 0) { // If not occupied,
340 sNameHash[slot].idx = idx; // ..Now it is.
341 return(slot); // and we are done.
342 }
343
344 // slot was occupied (collision).
345 _pcp_hash_t *newGuy = calloc(1, sizeof(_pcp_hash_t)); // make a new entry.
346 newGuy->idx = sNameHash[slot].idx; // copy the idx sitting in table.
347 newGuy->next = sNameHash[slot].next; // copy the chain pointer.
348 sNameHash[slot].idx = idx; // this one goes into table.
349 sNameHash[slot].next = (void*) newGuy; // and chains to that new guy.
350 return(slot); // and we are done.
351} // end routine.
static pthread_key_t key
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cachedGetInDom()

static char * cachedGetInDom ( pmInDom  indom,
int  inst 
)
static

Definition at line 612 of file linux-pcp.c.

613{
614 static int domains=0; // None cached to begin.
615 static _pcp_domain_cache_t* cachedDomains = NULL; // Empty pointer.
616 int i, domIdx;
617
618 if (inst == -1) { // If we are shutting down,
619 if (cachedDomains == NULL) return(NULL); // exit if we never built an array.
620 for (i=0; i<domains; i++) { // for every one cached,
621 free(cachedDomains[i].instances); // .. free malloced memory.
622 free(cachedDomains[i].names); // .. free malloced memory.
623 }
624
625 free(cachedDomains); // discard our table.
626 domains = 0; // reset.
627 cachedDomains = NULL; // never free twice.
628 return(NULL); // exit.
629 } // end if shutting down.
630
631 // Check if we have it already.
632 for (i=0; i<domains; i++) {
633 if (indom == cachedDomains[i].domainId) break; // Exit loop if found.
634 }
635
636 domIdx = i; // The domain index.
637 if (i == domains) { // If not found; make a new one and read it.
638 domains++; // .. add one to count.
639
640 if (domains == 1) { // for first domain,
641 cachedDomains = malloc(sizeof(_pcp_domain_cache_t)); // ..malloc.
642 } else { // for subsequent domains,
643 cachedDomains = realloc(cachedDomains,
644 domains*sizeof(_pcp_domain_cache_t)); // realloc, retain first.
645 }
646
647 if (cachedDomains == NULL) { // If we failed malloc/realloc,
648 fprintf(stderr, "%s:%i:%s malloc/realloc denied for "
649 "cachedDomains; size=%i.\n",
650 __FILE__, __LINE__, __func__, domains);
651 exit(-1);
652 } // end if realloc failed.
653
654 cachedDomains[domIdx].domainId = indom; // .. The domain we are getting.
655 cachedDomains[domIdx].numInstances = pcp_pmGetInDom(indom,
656 &cachedDomains[domIdx].instances, // .. store pointer lists in struct too.
657 &cachedDomains[domIdx].names); // ..
658 for (i=0; i<cachedDomains[domIdx].numInstances; i++) { // DEBUG, vet the strings.
659 if (cachedDomains[domIdx].names[i] == NULL ||
660 strlen(cachedDomains[domIdx].names[i]) == 0 ||
661 strlen(cachedDomains[domIdx].names[i]) >= PAPI_MAX_STR_LEN) {
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);
664 exit(-1);
665 } // end if domain string is nonsense.
666 }
667 } // end if we need to cache a new domain.
668
669 // We got the domain index, Now we can try to look up the
670 // instance name.
671
672 for (i=0; i < cachedDomains[domIdx].numInstances; i++) { // look through all instances.
673 if (cachedDomains[domIdx].instances[i] == inst) // .. If found,
674 return cachedDomains[domIdx].names[i]; // .. .. return matching name.
675 } // end search for inst.
676
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);
679 exit(-1); // Cannot continue; should not have happened.
680
681 return NULL; // Code cannot be reached. Couldn't find it.
682} // end routine.
const char * names[NUM_EVENTS]
static int pcp_pmGetInDom(pmInDom indom, int **instlist, char ***namelist)
Definition: linux-pcp.c:302
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cbPopulateNameOnly()

static void cbPopulateNameOnly ( const char *  name)
static

Definition at line 511 of file linux-pcp.c.

512{
513 if (sEventCount >= sEventInfoSize) { // If we must realloc,
514 sEventInfoSize += sEventInfoBlock; // .. Add another page.
515 pcp_event_info = realloc(pcp_event_info, // .. do realloc.
516 sEventInfoSize*sizeof(_pcp_event_info_t)); // ..
517 memset(&pcp_event_info[sEventCount], 0, // .. clear to zeros.
518 sEventInfoBlock*sizeof(_pcp_event_info_t)); // ..
519 }
520
521 strncpy(pcp_event_info[sEventCount].name, name, PAPI_MAX_STR_LEN-1); // copy name.
522 sEventCount++; // increment our count of events.
523} // end routine.
Here is the caller graph for this function:

◆ findNameHash()

static int findNameHash ( char *  key)
static

Definition at line 377 of file linux-pcp.c.

378{
379 int idx;
380 unsigned int slot = stringHash(key, HASH_SIZE); // compute hash code.
381 idx = sNameHash[slot].idx; // get the index.
382 if (idx < 0) return(-1); // No good slot for it.
383 if (strcmp(key, pcp_event_info[idx].name) == 0) { // If we found it straight away,
384 return(idx); // .. quick return.
385 }
386
387 _pcp_hash_t *next = (_pcp_hash_t*) sNameHash[slot].next; // get the next guy.
388
389 while (next != NULL) { // follow the chain.
390 idx = next->idx; // .. get the idx.
391 if (strcmp(key, pcp_event_info[idx].name) == 0) { // If we found a match,
392 return(idx); // .. return with answer.
393 }
394
395 next = next->next; // get the next guy in the link.
396 } // end chain follow for collisions.
397
398 return(-1); // did not find it.
399} // end routine.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ freeNameHash()

static void freeNameHash ( void  )
static

Definition at line 358 of file linux-pcp.c.

359{
360 int i;
361 for (i=0; i<HASH_SIZE; i++) { // loop through table.
362 void *next = sNameHash[i].next; // Get any pointer.
363 while (next != NULL) { // follow the chain.
364 void *tofree = next; // remember what we have to free.
365 next = ((_pcp_hash_t*) next)->next; // follow the chain.
366 free(tofree); // free the one we are standing on.
367 }
368 }
369} // end routine.
Here is the caller graph for this function:

◆ getHelpText()

static int getHelpText ( unsigned int  pcpIdx,
char **  helpText 
)
static

Definition at line 815 of file linux-pcp.c.

816{
817 char *p;
818 int ret;
819 char errMsg[]="Help Text is not available for this event."; // for an error we have seen.
820
821 pmID myPMID = pcp_event_info[pcpIdx].pmid; // collect the pmid.
822 ret = pcp_pmLookupText(myPMID, PM_TEXT_HELP, helpText); // collect a line of text, routine mallocs helpText.
823 if (ret != 0) { // If larger help is not available, Try oneline.
824 if (*helpText != NULL) free(*helpText); // .. Free anything allocated.
825 *helpText = NULL; // .. start it as null.
826 ret = pcp_pmLookupText(myPMID, PM_TEXT_ONELINE, helpText); // .. collect a line of text, routine mallocs helpText.
827 }
828
829 if (ret == PM_ERR_TEXT) { // If not available,
830 *helpText = strdup(errMsg); // duplicate this error message.
831 } else if (ret != 0) { // If PCP has any other error, report and exit.
832 fprintf(stderr, "%s:%i:%s pmLookupText failed; return=%s.\n",
833 __FILE__, __LINE__, FUNC, pcp_pmErrStr(ret));
834 return PAPI_EATTR; // .. invalid or missing event attribute.
835 }
836
837 // Replace all /n with '|'.
838 for (p=(*helpText); p[0] != 0; p++) { // loop through string routine allocated,
839 if (p[0] == '\n') p[0] = '|'; // .. If we found a \n, replace with '|'.
840 } // end scan for \n.
841
842 return PAPI_OK; // Presumably all went well.
843} // end routine.
#define PAPI_EATTR
Definition: f90papi.h:97
static int pcp_pmLookupText(pmID pmid, int level, char **buffer)
Definition: linux-pcp.c:305
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getPMDesc()

static void getPMDesc ( int  pcpIdx)
static

Definition at line 576 of file linux-pcp.c.

576 { // Reads the variable descriptor.
577 int ret;
578 if (pcp_event_info[pcpIdx].pmid == PM_ID_NULL) return; // Already have it.
579 ret = pcp_pmLookupDesc(pcp_event_info[pcpIdx].pmid, // Get the event descriptor.
580 &pcp_event_info[pcpIdx].desc); // .. into the table; will set desc.pmid to not null.
581 if (ret == PM_ERR_PMID) { // If we failed for PMID,
582 fprintf(stderr, "%s:%i:%s Invalid PMID.\n",
583 __FILE__, __LINE__, __func__);
584 exit(-1);
585 } // end if realloc failed.
586
587 if (ret == PM_ERR_NOAGENT) { // If we failed for agent,
588 fprintf(stderr, "%s:%i:%s PMDA Agent not available to respond..\n",
589 __FILE__, __LINE__, __func__);
590 exit(-1);
591 } // end if realloc failed.
592
593 if (ret != 0) { // Unknown error,
594 fprintf(stderr, "%s:%i:%s Unknown error code ret=%i.\n",
595 __FILE__, __LINE__, __func__, ret);
596 exit(-1);
597 } // end if realloc failed.
598
599 pcp_event_info[pcpIdx].valType = pcp_event_info[pcpIdx].desc.type; // Always copy type over.
600 return; // No error.
601} // END code.
static int pcp_pmLookupDesc(pmID pmid, pmDesc *desc)
Definition: linux-pcp.c:299
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getULLValue()

static unsigned long long getULLValue ( pmValueSet *  vset,
int  value_index 
)
static

Definition at line 689 of file linux-pcp.c.

690{
691 unsigned long long value; // our return value.
692 convert_64_t convert; // union for conversion.
693 uPointer_t myPtr; // a union helper to avoid warnings.
694
695 if (vset->valfmt == PM_VAL_INSITU) { // If the value format is in situ; a 32 bit value.
696 convert.ll = vset->vlist[value_index].value.lval; // .. we can just collect the value immediately.
697 value = convert.ull; // ..
698 } else { // If it is either static or dynamic alloc table,
699 pmValueBlock *pmvb = vset->vlist[value_index].value.pval; // .. value given is a pointer to value block.
700 myPtr.cPtr = pmvb->vbuf; // .. use cPtr because vbuf defined as char[1] in pmValueBlock.
701 switch (pmvb->vtype) { // Note we restricted the types in init; these cases should agree.
702 case PM_TYPE_32: // 32-bit signed integer
703 convert.ll = myPtr.iPtr[0];
704 value = convert.ull;
705 break;
706
707 case PM_TYPE_U32: // 32-bit unsigned integer
708 value = myPtr.uiPtr[0];
709 break;
710
711 case PM_TYPE_64: // 64-bit signed integer
712 convert.ll = myPtr.llPtr[0];
713 value = convert.ull;
714 break;
715
716 case PM_TYPE_U64: // 64-bit unsigned integer
717 value = myPtr.ullPtr[0];
718 break;
719
720 case PM_TYPE_FLOAT: // 32-bit floating point
721 convert.d = myPtr.fPtr[0]; // convert first.
722 value = convert.ull;
723 break;
724
725 case PM_TYPE_DOUBLE: // 64-bit floating point
726 convert.d = myPtr.dPtr[0];
727 value = convert.ull;
728 break;
729
730 case PM_TYPE_STRING: // array of char
731 convert.vp = myPtr.cPtr;
732 value = convert.ull;
733 break;
734
735 default:
736 fprintf(stderr, "%s:%i pmValueBlock (from PCP) contains an unrecognized value type=%i.\n",
737 __FILE__, __LINE__, pmvb->vtype);
738 convert.ll = -1; // A flag besides zero
739 value = convert.ull;
740 } // end switch on type.
741 } // if pmValueBlock value.
742
743 return(value); // exit with result.
744} // end routine.
unsigned long long * ullPtr
Definition: benchSANVML.c:129
char * cPtr
Definition: benchSANVML.c:132
int * iPtr
Definition: benchSANVML.c:125
float * fPtr
Definition: benchSANVML.c:130
double * dPtr
Definition: benchSANVML.c:131
long long * llPtr
Definition: benchSANVML.c:128
unsigned int * uiPtr
Definition: benchSANVML.c:126
Here is the caller graph for this function:

◆ makeQualifiedEvent()

static void makeQualifiedEvent ( int  baseEvent,
int  idx,
char *  qualifier 
)
static

Definition at line 532 of file linux-pcp.c.

533{
534 int prevSize;
535 if (sEventCount >= sEventInfoSize) { // If we must realloc,
536 prevSize = sEventInfoSize;
537 sEventInfoSize += sEventInfoBlock; // .. Add another block.
538 pcp_event_info = realloc(pcp_event_info, // .. attempt reallocation.
539 sEventInfoSize*sizeof(_pcp_event_info_t)); // .. ..
540 if (pcp_event_info == NULL) { // If realloc failed, report it.
541 fprintf(stderr, "%s:%i:%s realloc denied; "
542 "pcp_event_info=%p at size=%i.\n",
543 __FILE__, __LINE__, __func__,
545 exit(-1);
546 } // end if realloc failed.
547
548 memset(&pcp_event_info[prevSize], 0, // .. clear the new block to zeros..
549 sEventInfoBlock*sizeof(_pcp_event_info_t)); // ..
550 } // end if realloc needed.
551
552 pcp_event_info[sEventCount] = pcp_event_info[baseEvent]; // copy the structure.
553 pcp_event_info[sEventCount].numVal = 1; // Just one value.
554 pcp_event_info[sEventCount].idx = idx; // Set the right index.
555 pcp_event_info[sEventCount].zeroValue = 0; // Set the base value.
556 int slen = strlen(pcp_event_info[sEventCount].name); // get length of user name.
557 char *c = qualifier; // point at qualifier.
558 pcp_event_info[sEventCount].name[slen++] = ':'; // place a colon.
559
560 while ( (*c) != 0 && slen < PAPI_MAX_STR_LEN-1) { // .. appending qualifier,
561 char v=*c++; // .. what we intend to append, point at next.
562 // your chance to invalidate any chars, right here!
563 pcp_event_info[sEventCount].name[slen++] = v; // .. add to name, inc slen.
564 }
565
566 pcp_event_info[sEventCount].name[slen] = 0; // ensure z-terminator.
567 sEventCount++; // increment our count of events.
568} // end routine.
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
Here is the caller graph for this function:

◆ pcp_pmDestroyContext()

static int pcp_pmDestroyContext ( int  handle)
static

Definition at line 293 of file linux-pcp.c.

294 { return ((*pmDestroyContext_ptr) (handle));}
static papi_handle_t handle
Definition: Gamum.c:21
Here is the caller graph for this function:

◆ pcp_pmErrStr()

static char * pcp_pmErrStr ( int  code)
static

Definition at line 281 of file linux-pcp.c.

282 { return ((*pmErrStr_ptr) (code)); }
Here is the caller graph for this function:

◆ pcp_pmFetch()

static int pcp_pmFetch ( int  numpid,
pmID *  pmidlist,
pmResult **  result 
)
static

Definition at line 296 of file linux-pcp.c.

297 { return ((*pmFetch_ptr) (numpid,pmidlist,result)); }
volatile int result
Here is the caller graph for this function:

◆ pcp_pmFreeResult()

static void pcp_pmFreeResult ( pmResult *  result)
static

Definition at line 287 of file linux-pcp.c.

288 {(*pmFreeResult_ptr) (result); return;}
Here is the caller graph for this function:

◆ pcp_pmGetInDom()

static int pcp_pmGetInDom ( pmInDom  indom,
int **  instlist,
char ***  namelist 
)
static

Definition at line 302 of file linux-pcp.c.

303 { return ((*pmGetInDom_ptr) (indom,instlist,namelist)); }
Here is the caller graph for this function:

◆ pcp_pmLookupDesc()

static int pcp_pmLookupDesc ( pmID  pmid,
pmDesc *  desc 
)
static

Definition at line 299 of file linux-pcp.c.

300 { return ((*pmLookupDesc_ptr) (pmid,desc)); }
Here is the caller graph for this function:

◆ pcp_pmLookupText()

static int pcp_pmLookupText ( pmID  pmid,
int  level,
char **  buffer 
)
static

Definition at line 305 of file linux-pcp.c.

306 { return ((*pmLookupText_ptr) (pmid, level, buffer)); }
Here is the caller graph for this function:

◆ pcp_pmNewContext()

static int pcp_pmNewContext ( int  type,
const char *  name 
)
static

Definition at line 290 of file linux-pcp.c.

291 { return ((*pmNewContext_ptr) (type,name)); }
uint16_t type
Here is the caller graph for this function:

◆ pcp_pmTraversePMNS()

static int pcp_pmTraversePMNS ( const char *  name,
void(*)(const char *)  func 
)
static

Definition at line 284 of file linux-pcp.c.

285 { return ((*pmTraversePMNS_ptr) (name, func)); }
Here is the caller graph for this function:

◆ pcp_pmUnitsStr_r()

static char * pcp_pmUnitsStr_r ( const pmUnits *  pu,
char *  buf,
int  buflen 
)
static

Definition at line 308 of file linux-pcp.c.

309 {return ((*pmUnitsStr_r_ptr) (pu, buf, buflen)); }
volatile int buf[CACHE_FLUSH_BUFFER_SIZE_INTS]
Definition: do_loops.c:12
Here is the caller graph for this function:

◆ PCP_ReadList()

static int PCP_ReadList ( hwd_control_state_t ctl,
pmResult **  results 
)
static

Definition at line 1392 of file linux-pcp.c.

1394{
1395 int i, j, ret;
1397 *results = NULL; // Nothing allocated.
1398 if (myCtl->numEvents < 1) return PAPI_ENOEVNT; // No events to start.
1399 int nPMID = 0; // To count number of **unique** PMIDs.
1400
1401 pmID *allPMID=malloc((myCtl->numEvents)*sizeof(pmID)); // Make maximum possible room.
1402
1403 // We build a list of all *unique* PMIDs. Because PMID can return
1404 // an array of N values for a single event (e.g. one per CPU), we
1405 // 'explode' such events into N events for PAPI, which can only
1406 // return 1 value per event. Thus PAPI could add several to an
1407 // EventSet that all have the same PMID (PCP's ID). We only need
1408 // to read those once, our pcp_event_info[] contains the index
1409 // for each exploded event into the array returned for that PMID.
1410
1411 allPMID[nPMID++] = pcp_event_info[myCtl->pcpIndex[0]].pmid; // Move the first, increment total so far.
1412
1413 for (i=1; i<myCtl->numEvents; i++) { // For every event in the event set,
1414 int myIdx = myCtl->pcpIndex[i]; // .. Get pcp_event_info[] index of the event,
1415 pmID myPMID = pcp_event_info[myIdx].pmid; // .. get the PMID for that event,
1416 for (j=0; j<nPMID; j++) { // .. Search the unique PMID list for a match.
1417 if (myPMID == allPMID[j]) break; // .. .. found it. break out.
1418 }
1419
1420 if (j == nPMID) { // full loop ==> myPMID was not found in list,
1421 allPMID[nPMID++] = myPMID; // .. store the unique pmid in list, inc count.
1422 }
1423 } // done building list of unique pmid.
1424
1425 // nPMID is # of unique PMID, now ready to read all the pmid needed.
1426 pmResult *allFetch = NULL; // result of pmFetch.
1427 ret = pcp_pmFetch(nPMID, allPMID, &allFetch); // Fetch them all.
1428 *results = allFetch; // For either success or failure.
1429
1430 if( ret != PAPI_OK) { // If fetch failed ..
1431 fprintf(stderr, "%s:%i:%s pcp_pmFetch failed, return=%s.\n",
1432 __FILE__, __LINE__, FUNC, PAPI_strerror(ret)); // .. report error.
1433 if (allPMID != NULL) free(allPMID); // .. no memory leak.
1434 allPMID = NULL; // .. prevent future use.
1435 return(ret); // .. exit with that error.
1436 }
1437
1438 // For each unique PMID we just read, we must map it to the event
1439 // sets, which may contain multiple entries with that same PMID.
1440 // This is because PCP returns arrays, and PAPI does not, so each
1441 // of our names translates to a PMID + an index.
1442
1443 for (i=0; i<nPMID; i++) { // process all the fetch results.
1444 pmValueSet *vset = allFetch->vset[i]; // get the result for event[i].
1445 pmID myPMID = allPMID[i]; // get the pmid from this read.
1446
1447 // Now we must search for any events with this pmid, and get
1448 // the corresponding value (may be more than one, since we
1449 // treat each idx as its own value).
1450
1451 for (j=0; j<myCtl->numEvents; j++) { // for each event,
1452 int myPCPIdx = myCtl->pcpIndex[j]; // .. get my pcp_event_info[] index.
1453 pmID thisPMID = pcp_event_info[myPCPIdx].pmid; // .. collect its pmid.
1454 if (thisPMID == myPMID) { // .. If this result services that event,
1455 int myArrayIdx = pcp_event_info[myPCPIdx].idx; // .. .. get array index within result array, for result value list.
1456 myCtl->pcpValue[j] = getULLValue(vset, myArrayIdx); // .. .. translate as needed, put back into pcpValue array.
1457 } // end if counter was found for this PMID.
1458 } // end loop through all events in this event set.
1459 } // end for each pmID read.
1460
1461 if (allPMID != NULL) free(allPMID); // Done with this work area; no memory leak.
1462 return PAPI_OK; // All done.
1463} // end routine.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ qsPMID()

static int qsPMID ( const void *  arg1,
const void *  arg2 
)
static

Definition at line 490 of file linux-pcp.c.

491{
494
495 if (p1->pmid < p2->pmid) return (-1); // 1 comes before 2.
496 if (p1->pmid > p2->pmid) return ( 1); // 1 comes after 2.
497 if (p1->idx < p2->idx ) return (-1); // same pmid, try idx into vlist.
498 if (p1->idx > p2->idx ) return ( 1); // 1 comes after 2.
499 return (strcmp(p1->name, p2->name)); // sort by name if same PMID and idx.
500} // end routine.
Here is the caller graph for this function:

◆ stringHash()

static unsigned int stringHash ( char *  str,
unsigned int  tableSize 
)
static

Definition at line 320 of file linux-pcp.c.

321{
322 unsigned long hash = 5381; // seed value.
323 int c;
324 while ((c = (*str++))) { // ends when c == 0.
325 hash = ((hash << 5) + hash) + c; // hash * 33 + c.
326 }
327
328 return (hash % tableSize); // compute index and exit.
329} // end function.
Here is the caller graph for this function:

◆ subZero()

static void subZero ( _pcp_control_state_t myCtl,
int  event 
)
static

Definition at line 763 of file linux-pcp.c.

764{
765 int k = myCtl->pcpIndex[event]; // get pcp_event_info[] index.
766 if (pcp_event_info[k].desc.sem != PM_SEM_COUNTER) return; // Don't subtract from instantaneous values.
767
768 convert_64_t zero, rawval;
769 rawval.ull = myCtl->pcpValue[event]; // collect the raw value.
770 zero.ull = pcp_event_info[k].zeroValue; // collect the zero (base) value.
771 switch (pcp_event_info[k].valType) { // Note we restricted the types in init; these cases should agree.
772 case PM_TYPE_32: // 32 bit was converted to long long.
773 case PM_TYPE_64: // long long.
774 rawval.ll -= zero.ll; // converted.
775 break;
776
777 case PM_TYPE_U32: // 32-bit was converted to 64 bit.
778 case PM_TYPE_U64: // 64-bit unsigned integer
779 rawval.ull -= zero.ull; // converted.
780 break;
781
782 case PM_TYPE_FLOAT: // 32-bit was converted to double.
783 case PM_TYPE_DOUBLE: // 64-bit floating point
784 rawval.d -= zero.d; // converted.
785 break;
786
787 case PM_TYPE_STRING: // array of char, do nothing for pointer.
788 break;
789
790 default:
791 fprintf(stderr, "%s:%i pcp_event_info[%s] contains an unrecognized value type=%i.\n",
792 __FILE__, __LINE__, pcp_event_info[k].name, pcp_event_info[k].valType);
793 exit(-1); // Quit, this shouldn't happen; something needs updating.
794 break;
795 } // end switch on type.
796
797 myCtl->pcpValue[event] = rawval.ull; // The adjusted value.
798} // end routine.
Here is the caller graph for this function:

Variable Documentation

◆ _dl_non_dynamic_init

void(* _dl_non_dynamic_init) (void) ( void  )

Definition at line 260 of file linux-pcp.c.

279 { return ((*pmLookupName_ptr) (numpid, namelist, pmidlist)); }

◆ _papi_hwi_debug

int _papi_hwi_debug = DEBUG_SUBSTRATE

Definition at line 187 of file linux-pcp.c.

◆ _pcp_vector

papi_vector_t _pcp_vector

Definition at line 182 of file linux-pcp.c.

◆ ctxHandle

int ctxHandle = -1
static

Definition at line 192 of file linux-pcp.c.

◆ dl1

void* dl1 = NULL
static

Definition at line 248 of file linux-pcp.c.

◆ pcp_event_info

_pcp_event_info_t* pcp_event_info = NULL
static

Definition at line 190 of file linux-pcp.c.

◆ pcp_main

char pcp_main[] =PAPI_PCP_MAIN
static

Definition at line 251 of file linux-pcp.c.

◆ sEventCount

int sEventCount = 0
static

Definition at line 191 of file linux-pcp.c.

◆ sEventInfoBlock

int sEventInfoBlock = ((8*1024) / sizeof(_pcp_event_info_t))
static

Definition at line 189 of file linux-pcp.c.

◆ sEventInfoSize

int sEventInfoSize =0
static

Definition at line 188 of file linux-pcp.c.

◆ sNameHash

_pcp_hash_t sNameHash[HASH_SIZE]
static

Definition at line 195 of file linux-pcp.c.

◆ t2

struct timeval t1 t2
static

Definition at line 238 of file linux-pcp.c.