summaryrefslogtreecommitdiff
path: root/src/pmdas/papi/papi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmdas/papi/papi.c')
-rw-r--r--src/pmdas/papi/papi.c1497
1 files changed, 1497 insertions, 0 deletions
diff --git a/src/pmdas/papi/papi.c b/src/pmdas/papi/papi.c
new file mode 100644
index 0000000..4977bb1
--- /dev/null
+++ b/src/pmdas/papi/papi.c
@@ -0,0 +1,1497 @@
+/*
+ * PAPI PMDA
+ *
+ * Copyright (c) 2014 Red Hat.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+#include "domain.h"
+#include <papi.h>
+#include <assert.h>
+#if defined(HAVE_GRP_H)
+#include <grp.h>
+#endif
+#include <string.h>
+
+
+enum {
+ CLUSTER_PAPI = 0, // hardware event counters
+ CLUSTER_CONTROL, // control variables
+ CLUSTER_AVAILABLE, // available hardware
+};
+
+typedef struct {
+ unsigned int papi_event_code; //the PAPI_ eventcode
+ char papi_string_code[8];
+ int position;
+ int pmns_position;
+} papi_m_user_tuple;
+
+static papi_m_user_tuple *papi_info;
+
+static char *enable_string;
+static char *disable_string;
+static char isDSO = 1; /* == 0 if I am a daemon */
+static int EventSet = PAPI_NULL;
+static long_long *values;
+struct uid_gid_tuple {
+ char uid_p; char gid_p; /* uid/gid received flags. */
+ int uid; int gid; /* uid/gid received from PCP_ATTR_* */
+};
+static struct uid_gid_tuple *ctxtab;
+static int ctxtab_size;
+static int number_of_counters;
+static unsigned int number_of_active_counters;
+static unsigned int size_of_active_counters;
+static unsigned int number_of_events;
+
+static void
+set_pmns_position(unsigned int i)
+{
+ switch (papi_info[i].papi_event_code) {
+ case PAPI_TOT_INS:
+ papi_info[i].pmns_position = 0;
+ break;
+ case PAPI_TOT_CYC:
+ papi_info[i].pmns_position = 1;
+ break;
+ case PAPI_L1_DCM:
+ papi_info[i].pmns_position = 2;
+ break;
+ case PAPI_L1_ICM:
+ papi_info[i].pmns_position = 3;
+ break;
+ case PAPI_L2_DCM:
+ papi_info[i].pmns_position = 4;
+ break;
+ case PAPI_L2_ICM:
+ papi_info[i].pmns_position = 5;
+ break;
+ case PAPI_L3_DCM:
+ papi_info[i].pmns_position = 6;
+ break;
+ case PAPI_L3_ICM:
+ papi_info[i].pmns_position = 7;
+ break;
+ case PAPI_L1_TCM:
+ papi_info[i].pmns_position = 8;
+ break;
+ case PAPI_L2_TCM:
+ papi_info[i].pmns_position = 9;
+ break;
+ case PAPI_L3_TCM:
+ papi_info[i].pmns_position = 10;
+ break;
+ case PAPI_TLB_DM:
+ papi_info[i].pmns_position = 11;
+ break;
+ case PAPI_TLB_IM:
+ papi_info[i].pmns_position = 12;
+ break;
+ case PAPI_TLB_TL:
+ papi_info[i].pmns_position = 13;
+ break;
+ case PAPI_L1_LDM:
+ papi_info[i].pmns_position = 14;
+ break;
+ case PAPI_L1_STM:
+ papi_info[i].pmns_position = 15;
+ break;
+ case PAPI_L2_LDM:
+ papi_info[i].pmns_position = 16;
+ break;
+ case PAPI_L2_STM:
+ papi_info[i].pmns_position = 17;
+ break;
+ case PAPI_CA_SNP:
+ papi_info[i].pmns_position = 18;
+ break;
+ case PAPI_CA_SHR:
+ papi_info[i].pmns_position = 19;
+ break;
+ case PAPI_CA_CLN:
+ papi_info[i].pmns_position = 20;
+ break;
+ case PAPI_CA_INV:
+ papi_info[i].pmns_position = 21;
+ break;
+ case PAPI_CA_ITV:
+ papi_info[i].pmns_position = 22;
+ break;
+ case PAPI_L3_LDM:
+ papi_info[i].pmns_position = 23;
+ break;
+ case PAPI_L3_STM:
+ papi_info[i].pmns_position = 24;
+ break;
+ case PAPI_BRU_IDL:
+ papi_info[i].pmns_position = 25;
+ break;
+ case PAPI_FXU_IDL:
+ papi_info[i].pmns_position = 26;
+ break;
+ case PAPI_FPU_IDL:
+ papi_info[i].pmns_position = 27;
+ break;
+ case PAPI_LSU_IDL:
+ papi_info[i].pmns_position = 28;
+ break;
+ case PAPI_BTAC_M:
+ papi_info[i].pmns_position = 29;
+ break;
+ case PAPI_PRF_DM:
+ papi_info[i].pmns_position = 30;
+ break;
+ case PAPI_L3_DCH:
+ papi_info[i].pmns_position = 31;
+ break;
+ case PAPI_TLB_SD:
+ papi_info[i].pmns_position = 32;
+ break;
+ case PAPI_CSR_FAL:
+ papi_info[i].pmns_position = 33;
+ break;
+ case PAPI_CSR_SUC:
+ papi_info[i].pmns_position = 34;
+ break;
+ case PAPI_CSR_TOT:
+ papi_info[i].pmns_position = 35;
+ break;
+ case PAPI_MEM_SCY:
+ papi_info[i].pmns_position = 36;
+ break;
+ case PAPI_MEM_RCY:
+ papi_info[i].pmns_position = 37;
+ break;
+ case PAPI_MEM_WCY:
+ papi_info[i].pmns_position = 38;
+ break;
+ case PAPI_STL_ICY:
+ papi_info[i].pmns_position = 39;
+ break;
+ case PAPI_FUL_ICY:
+ papi_info[i].pmns_position = 40;
+ break;
+ case PAPI_STL_CCY:
+ papi_info[i].pmns_position = 41;
+ break;
+ case PAPI_FUL_CCY:
+ papi_info[i].pmns_position = 42;
+ break;
+ case PAPI_HW_INT:
+ papi_info[i].pmns_position = 43;
+ break;
+ case PAPI_BR_UCN:
+ papi_info[i].pmns_position = 44;
+ break;
+ case PAPI_BR_CN:
+ papi_info[i].pmns_position = 45;
+ break;
+ case PAPI_BR_TKN:
+ papi_info[i].pmns_position = 46;
+ break;
+ case PAPI_BR_NTK:
+ papi_info[i].pmns_position = 47;
+ break;
+ case PAPI_BR_MSP:
+ papi_info[i].pmns_position = 48;
+ break;
+ case PAPI_BR_PRC:
+ papi_info[i].pmns_position = 49;
+ break;
+ case PAPI_FMA_INS:
+ papi_info[i].pmns_position = 50;
+ break;
+ case PAPI_TOT_IIS:
+ papi_info[i].pmns_position = 51;
+ break;
+ case PAPI_INT_INS:
+ papi_info[i].pmns_position = 52;
+ break;
+ case PAPI_FP_INS:
+ papi_info[i].pmns_position = 53;
+ break;
+ case PAPI_LD_INS:
+ papi_info[i].pmns_position = 54;
+ break;
+ case PAPI_SR_INS:
+ papi_info[i].pmns_position = 55;
+ break;
+ case PAPI_BR_INS:
+ papi_info[i].pmns_position = 56;
+ break;
+ case PAPI_VEC_INS:
+ papi_info[i].pmns_position = 57;
+ break;
+ case PAPI_RES_STL:
+ papi_info[i].pmns_position = 58;
+ break;
+ case PAPI_FP_STAL:
+ papi_info[i].pmns_position = 59;
+ break;
+ case PAPI_LST_INS:
+ papi_info[i].pmns_position = 60;
+ break;
+ case PAPI_SYC_INS:
+ papi_info[i].pmns_position = 61;
+ break;
+ case PAPI_L1_DCH:
+ papi_info[i].pmns_position = 62;
+ break;
+ case PAPI_L2_DCH:
+ papi_info[i].pmns_position = 63;
+ break;
+ case PAPI_L1_DCA:
+ papi_info[i].pmns_position = 64;
+ break;
+ case PAPI_L2_DCA:
+ papi_info[i].pmns_position = 65;
+ break;
+ case PAPI_L3_DCA:
+ papi_info[i].pmns_position = 66;
+ break;
+ case PAPI_L1_DCR:
+ papi_info[i].pmns_position = 67;
+ break;
+ case PAPI_L2_DCR:
+ papi_info[i].pmns_position = 68;
+ break;
+ case PAPI_L3_DCR:
+ papi_info[i].pmns_position = 69;
+ break;
+ case PAPI_L1_DCW:
+ papi_info[i].pmns_position = 70;
+ break;
+ case PAPI_L2_DCW:
+ papi_info[i].pmns_position = 71;
+ break;
+ case PAPI_L3_DCW:
+ papi_info[i].pmns_position = 72;
+ break;
+ case PAPI_L1_ICH:
+ papi_info[i].pmns_position = 73;
+ break;
+ case PAPI_L2_ICH:
+ papi_info[i].pmns_position = 74;
+ break;
+ case PAPI_L3_ICH:
+ papi_info[i].pmns_position = 75;
+ break;
+ case PAPI_L1_ICA:
+ papi_info[i].pmns_position = 76;
+ break;
+ case PAPI_L2_ICA:
+ papi_info[i].pmns_position = 77;
+ break;
+ case PAPI_L3_ICA:
+ papi_info[i].pmns_position = 78;
+ break;
+ case PAPI_L1_ICR:
+ papi_info[i].pmns_position = 79;
+ break;
+ case PAPI_L2_ICR:
+ papi_info[i].pmns_position = 80;
+ break;
+ case PAPI_L3_ICR:
+ papi_info[i].pmns_position = 81;
+ break;
+ case PAPI_L1_ICW:
+ papi_info[i].pmns_position = 82;
+ break;
+ case PAPI_L2_ICW:
+ papi_info[i].pmns_position = 83;
+ break;
+ case PAPI_L3_ICW:
+ papi_info[i].pmns_position = 84;
+ break;
+ case PAPI_L1_TCH:
+ papi_info[i].pmns_position = 85;
+ break;
+ case PAPI_L2_TCH:
+ papi_info[i].pmns_position = 86;
+ break;
+ case PAPI_L3_TCH:
+ papi_info[i].pmns_position = 87;
+ break;
+ case PAPI_L1_TCA:
+ papi_info[i].pmns_position = 88;
+ break;
+ case PAPI_L2_TCA:
+ papi_info[i].pmns_position = 89;
+ break;
+ case PAPI_L3_TCA:
+ papi_info[i].pmns_position = 90;
+ break;
+ case PAPI_L1_TCR:
+ papi_info[i].pmns_position = 91;
+ break;
+ case PAPI_L2_TCR:
+ papi_info[i].pmns_position = 92;
+ break;
+ case PAPI_L3_TCR:
+ papi_info[i].pmns_position = 93;
+ break;
+ case PAPI_L1_TCW:
+ papi_info[i].pmns_position = 94;
+ break;
+ case PAPI_L2_TCW:
+ papi_info[i].pmns_position = 95;
+ break;
+ case PAPI_L3_TCW:
+ papi_info[i].pmns_position = 96;
+ break;
+ case PAPI_FML_INS:
+ papi_info[i].pmns_position = 97;
+ break;
+ case PAPI_FAD_INS:
+ papi_info[i].pmns_position = 98;
+ break;
+ case PAPI_FDV_INS:
+ papi_info[i].pmns_position = 99;
+ break;
+ case PAPI_FSQ_INS:
+ papi_info[i].pmns_position = 100;
+ break;
+ case PAPI_FNV_INS:
+ papi_info[i].pmns_position = 101;
+ break;
+ case PAPI_FP_OPS:
+ papi_info[i].pmns_position = 102;
+ break;
+ case PAPI_SP_OPS:
+ papi_info[i].pmns_position = 103;
+ break;
+ case PAPI_DP_OPS:
+ papi_info[i].pmns_position = 104;
+ break;
+ case PAPI_VEC_SP:
+ papi_info[i].pmns_position = 105;
+ break;
+ case PAPI_VEC_DP:
+ papi_info[i].pmns_position = 106;
+ break;
+#ifdef PAPI_REF_CYC
+ case PAPI_REF_CYC:
+ papi_info[i].pmns_position = 107;
+ break;
+#endif
+ default:
+ papi_info[i].pmns_position = -1;
+ break;
+ }
+}
+
+static int
+permission_check(int context)
+{
+ if ((ctxtab[context].uid_p && ctxtab[context].uid == 0) ||
+ (ctxtab[context].gid_p && ctxtab[context].gid == 0))
+ return 1;
+ return 0;
+}
+
+static void
+expand_papi_info(int size)
+{
+ if (number_of_events <= size) {
+ size_t new_size = (size + 1) * sizeof(papi_m_user_tuple);
+ papi_info = realloc(papi_info, new_size);
+ if (papi_info == NULL)
+ __pmNoMem("papi_info tuple", new_size, PM_FATAL_ERR);
+ while (number_of_events <= size)
+ memset(&papi_info[number_of_events++], 0, sizeof(papi_m_user_tuple));
+ }
+}
+
+static void
+expand_values(int size)
+{
+ if (size_of_active_counters <= size) {
+ size_t new_size = (size + 1) * sizeof(long_long);
+ values = realloc(values, new_size);
+ if (values == NULL)
+ __pmNoMem("values", new_size, PM_FATAL_ERR);
+ while (size_of_active_counters <= size) {
+ memset(&values[size_of_active_counters++], 0, sizeof(long_long));
+ if (pmDebug & DBG_TRACE_APPL0) {
+ __pmNotifyErr(LOG_DEBUG, "memsetting to zero, %d counters\n",
+ size_of_active_counters);
+ }
+ }
+ }
+}
+
+static void
+enlarge_ctxtab(int context)
+{
+ /* Grow the context table if necessary. */
+ if (ctxtab_size /* cardinal */ <= context /* ordinal */) {
+ size_t need = (context + 1) * sizeof(struct uid_gid_tuple);
+ ctxtab = realloc(ctxtab, need);
+ if (ctxtab == NULL)
+ __pmNoMem("papi ctx table", need, PM_FATAL_ERR);
+ /* Blank out new entries. */
+ while (ctxtab_size <= context)
+ memset(&ctxtab[ctxtab_size++], 0, sizeof(struct uid_gid_tuple));
+ }
+}
+
+static int
+check_papi_state(int state)
+{
+ int retval;
+ retval = PAPI_state(EventSet, &state);
+ if (retval != PAPI_OK)
+ return PM_ERR_NODATA;
+ return state;
+}
+
+static char *
+papi_string_status(void)
+{
+ int state, retval;
+
+ retval = PAPI_state(EventSet, &state);
+ if (retval != PAPI_OK)
+ return "PAPI_state error.";
+ switch (state) {
+ case PAPI_STOPPED:
+ return "Papi is stopped.";
+ case PAPI_RUNNING:
+ return "Papi is running.";
+ case PAPI_PAUSED:
+ return "Papi is paused";
+ case PAPI_NOT_INIT:
+ return "Papi eventset is defined but not initialized.";
+ case PAPI_OVERFLOWING:
+ return "Papi eventset has overflowing enabled";
+ case PAPI_PROFILING:
+ return "Papi eventset has profiling enabled";
+ case PAPI_MULTIPLEXING:
+ return "Papi eventset has multiplexing enabled";
+ case PAPI_ATTACHED:
+ return "Papi is attached to another process/thread";
+ case PAPI_CPU_ATTACHED:
+ return "Papi is attached to a specific CPU.";
+ default:
+ return "PAPI_state error.";
+ }
+}
+
+/*
+ * A list of all the papi metrics we support -
+ */
+static pmdaMetric metrictab[] = {
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,0), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.TOT_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,1), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.TOT_CYC */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,2), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_DCM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,3), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_ICM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,4), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_DCM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,5), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_ICM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,6), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_DCM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,7), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_ICM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,8), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_TCM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,9), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_TCM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,10), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_TCM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,11), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.TLB_DM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,12), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.TLB_IM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,13), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.TLB_TL */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,14), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_LDM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,15), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_STM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,16), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_LDM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,17), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_STM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,18), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.CA_SNP */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,19), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.CA_SHR */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,20), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.CA_CLN */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,21), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.CA_INV */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,22), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.CA_ITV */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,23), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_LDM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,24), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_STM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,25), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.BRU_IDL */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,26), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FXU_IDL */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,27), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FPU_IDL */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,28), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.LSU_IDL */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,29), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.BTAC_M */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,30), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.PRF_DM */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,31), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_DCH */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,32), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.TLB_SD */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,33), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.CSR_FAL */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,34), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.CSR_SUC */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,35), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.CSR_TOT */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,36), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.MEM_SCY */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,37), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.MEM_RCY */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,38), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.MEM_WCY */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,39), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.STL_ICY */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,40), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FUL_ICY */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,41), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.STL_CCY */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,42), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FUL_CCY */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,43), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.HW_INT */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,44), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.BR_UCN */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,45), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.BR_CN */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,46), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.BR_TKN */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,47), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.BR_NTK */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,48), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.BR_MSP */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,49), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.BR_PRC */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,50), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FMA_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,51), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.TOT_IIS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,52), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.INT_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,53), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FP_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,54), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.LD_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,55), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.SR_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,56), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.BR_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,57), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.VEC_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,58), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.RES_STL */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,59), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FP_STAL */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,60), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.LST_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,61), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.SYC_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,62), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_DCH */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,63), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_DCH */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,64), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_DCA */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,65), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_DCA */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,66), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_DCA */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,67), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_DCR */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,68), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_DCR */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,69), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_DCR */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,70), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_DCW */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,71), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_DCW */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,72), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_DCW */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,73), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_ICH */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,74), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_ICH */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,75), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_ICH */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,76), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_ICA */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,77), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_ICA */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,78), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_ICA */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,79), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_ICR */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,80), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_ICR */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,81), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_ICR */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,82), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_ICW */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,83), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_ICW */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,84), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_ICW */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,85), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_TCH */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,86), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_TCH */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,87), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_TCH */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,88), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_TCA */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,89), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_TCA */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,90), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_TCA */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,91), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_TCR */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,92), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_TCR */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,93), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_TCR */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,94), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L1_TCW */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,95), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L2_TCW */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,96), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.L3_TCW */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,97), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FML_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,98), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FAD_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,99), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FDV_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,100), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FSQ_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,101), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FNV_INS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,102), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.FP_OPS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,103), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.SP_OPS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,104), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.DP_OPS */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,105), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.VEC_SP */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,106), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.VEC_DP */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_PAPI,107), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.REF_CYC */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_CONTROL,0), PM_TYPE_STRING, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.control.enable */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_CONTROL,1), PM_TYPE_STRING, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.control.reset */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_CONTROL,2), PM_TYPE_STRING, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.control.disable */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_CONTROL,3), PM_TYPE_STRING, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.control.status */
+
+ { NULL,
+ { PMDA_PMID(CLUSTER_AVAILABLE,0), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0, 0, 0, 0, 0, 0) } }, /* papi.available.num_counters */
+
+};
+
+static void
+papi_endContextCallBack(int context)
+{
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG, "end context %d received\n", context);
+
+ /* ensure clients re-using this slot re-authenticate */
+ if (context >= 0 && context < ctxtab_size) {
+ ctxtab[context].uid_p = 0;
+ ctxtab[context].gid_p = 0;
+ }
+}
+
+static int
+papi_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
+{
+ __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid);
+ int running = 0;
+ int sts = 0;
+ int i;
+
+ sts = check_papi_state(sts);
+ if (sts == PAPI_RUNNING && idp->cluster == CLUSTER_PAPI) {
+ sts = PAPI_read(EventSet, values);
+ if (sts != PAPI_OK) {
+ __pmNotifyErr(LOG_ERR, "PAPI_read: %s\n", PAPI_strerror(sts));
+ return PM_ERR_VALUE;
+ }
+ running = 1;
+ }
+
+ switch (idp->cluster) {
+ case CLUSTER_PAPI:
+ if (!running)
+ return PMDA_FETCH_NOVALUES;
+ if (idp->item >= 0 && idp->item <= 107) {
+ // the 'case' && 'idp->item' value we get is the pmns_position
+ for (i = 0; i < number_of_events; i++) {
+ if (papi_info[i].pmns_position == idp->item) {
+ if(papi_info[i].position >= 0 && papi_info[i].papi_event_code){
+ atom->ull = values[papi_info[i].position];
+ return PMDA_FETCH_STATIC;
+ }
+ else
+ return PMDA_FETCH_NOVALUES;
+ }
+ }
+ }
+ return PM_ERR_PMID;
+
+ case CLUSTER_CONTROL:
+ switch (idp->item) {
+ case 0:
+ atom->cp = enable_string; /* papi.control.enable */
+ return PMDA_FETCH_STATIC;
+
+ case 1:
+ // break; /* papi.control.reset */
+ // atom->cp = reset_string;
+ return PM_ERR_NYI;
+
+ case 2:
+ if ((sts = check_papi_state(sts)) == PAPI_RUNNING) {
+ atom->cp = disable_string; /* papi.control.disable */
+ return PMDA_FETCH_STATIC;
+ }
+ return 0;
+
+ case 3:
+ atom->cp = papi_string_status(); /* papi.control.status */
+ return PMDA_FETCH_STATIC;
+
+ default:
+ return PM_ERR_PMID;
+ }
+ break;
+
+ case CLUSTER_AVAILABLE:
+ if (idp->item == 0) {
+ atom->ul = number_of_counters; /* papi.available.num_counters */
+ return PMDA_FETCH_STATIC;
+ }
+ return PM_ERR_PMID;
+
+ default:
+ return PM_ERR_PMID;
+ }
+
+ return PMDA_FETCH_NOVALUES;
+}
+
+static int
+papi_fetch(int numpmid, pmID pmidlist[], pmResult **resp, pmdaExt *pmda)
+{
+ if (permission_check(pmda->e_context))
+ return pmdaFetch(numpmid, pmidlist, resp, pmda);
+ return PM_ERR_PERMISSION;
+}
+
+static int
+remove_metric(unsigned int event, int position)
+{
+ int retval = 0;
+ int state = 0;
+ int restart = 0; // bool to restart running values at the end
+ int i;
+ long_long new_values[size_of_active_counters];
+
+ retval = PAPI_query_event(event);
+ if (retval != PAPI_OK){
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG, "event not found on this hardware, skipping\n");
+ return retval;
+ }
+
+ /* check to make sure papi is running, otherwise do nothing */
+ state = check_papi_state(state);
+ if (state == PAPI_RUNNING) {
+ restart = 1;
+ retval = PAPI_stop(EventSet, values);
+ if(retval != PAPI_OK)
+ return retval;
+ }
+ state = check_papi_state(state);
+ if (state == PAPI_STOPPED) {
+ /* first, copy the values over to new array */
+ for (i = 0; i < number_of_events; i++)
+ new_values[papi_info[i].position] = values[papi_info[i].position];
+
+ /* workaround a papi bug: fully destroy the eventset and restart it */
+ memset(values, 0, sizeof(values[0])*size_of_active_counters);
+ retval = PAPI_cleanup_eventset(EventSet);
+ if (retval != PAPI_OK)
+ return retval;
+
+ retval = PAPI_destroy_eventset(&EventSet);
+ if (retval != PAPI_OK)
+ return retval;
+
+ number_of_active_counters--;
+ retval = PAPI_create_eventset(&EventSet);
+ if (retval != PAPI_OK)
+ return retval;
+
+ // run through all metrics and adjust position variable as needed
+ for (i = 0; i < number_of_events; i++) {
+ // set event we're removing position to -1
+ if (papi_info[i].position == position) {
+ new_values[papi_info[i].position] = 0;
+ papi_info[i].position = -1;
+ }
+ }
+
+ for (i = 0; i < number_of_events; i++) {
+ if (papi_info[i].position < position)
+ values[papi_info[i].position] = new_values[papi_info[i].position];
+
+ if (papi_info[i].position > position) {
+ papi_info[i].position--;
+ values[papi_info[i].position] = new_values[papi_info[i].position+1];
+ }
+ if (papi_info[i].position >= 0 && papi_info[i].papi_event_code) {
+ retval = PAPI_add_event(EventSet, papi_info[i].papi_event_code);
+ if (retval != PAPI_OK)
+ return retval;
+ }
+ }
+ if (restart && (number_of_active_counters > 0)) {
+ retval = PAPI_start(EventSet);
+ if (retval != PAPI_OK)
+ return retval;
+ }
+ return retval;
+ }
+ return PM_ERR_VALUE;
+}
+
+static int
+add_metric(unsigned int event)
+{
+ int retval = 0;
+ int state = 0;
+ long_long new_values[size_of_active_counters];
+ int i;
+
+ retval = PAPI_query_event(event);
+ if (retval != PAPI_OK){
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG, "event not found on this hardware, skipping\n");
+ return retval;
+ }
+ /* check status of papi */
+ state = check_papi_state(state);
+ /* add check with number_of_counters */
+ /* stop papi if running? */
+ if (state == PAPI_RUNNING) {
+ for (i = 0; i < size_of_active_counters; i++){
+ if(papi_info[i].position >= 0 && papi_info[i].papi_event_code)
+ new_values[papi_info[i].position] = values[papi_info[i].position];
+ }
+ retval = PAPI_stop(EventSet, values);
+ if (retval != PAPI_OK)
+ return retval;
+ }
+ state = check_papi_state(state);
+ if (state == PAPI_STOPPED) {
+ /* add metric */
+ retval = PAPI_add_event(EventSet, event); //XXX possibly switch this to add_events
+ if (retval != PAPI_OK)
+ return retval;
+
+ for (i = 0; i < size_of_active_counters; i++){
+ if(papi_info[i].position >= 0 && papi_info[i].papi_event_code)
+ values[papi_info[i].position] = new_values[papi_info[i].position];
+ }
+ number_of_active_counters++;
+ retval = PAPI_start(EventSet);
+ return retval;
+ }
+ return PM_ERR_VALUE;
+}
+
+static int
+papi_store(pmResult *result, pmdaExt *pmda)
+{
+ int sts;
+ int i, j, len;
+ const char *delim = " ,";
+ char *substring;
+
+ if (!permission_check(pmda->e_context))
+ return PM_ERR_PERMISSION;
+ for (i = 0; i < result->numpmid; i++) {
+ pmValueSet *vsp = result->vset[i];
+ __pmID_int *idp = (__pmID_int *)&(vsp->pmid);
+ pmAtomValue av;
+
+ if (idp->cluster != CLUSTER_CONTROL)
+ return PM_ERR_PERMISSION;
+
+ switch (idp->item) {
+ case 0: //papi.enable
+ if ((sts = pmExtractValue(vsp->valfmt, &vsp->vlist[0],
+ PM_TYPE_STRING, &av, PM_TYPE_STRING)) < 0)
+ return sts;
+ free(enable_string);
+ enable_string = av.cp;
+ len = strlen(enable_string);
+ substring = strtok(enable_string, delim);
+ while (substring != NULL) {
+ for (j = 0; j < number_of_events; j++) {
+ if (!strcmp(substring, papi_info[j].papi_string_code) && papi_info[j].position < 0) {
+ // add the metric to the set if it's not already there
+ sts = add_metric(papi_info[j].papi_event_code);
+ if (sts == PAPI_OK)
+ papi_info[j].position = number_of_active_counters-1;
+ }
+ }
+ substring = strtok(NULL, delim);
+ }
+ for (j = 0; j < len-1; j++) { // recover from tokenisation
+ if (enable_string[j] == '\0')
+ enable_string[j] = delim[0];
+ }
+ break;
+
+ case 1: //papi.reset
+#if 0 /* not yet implemented */
+ sts = check_papi_state(sts);
+ if (sts == PAPI_RUNNING) {
+ if ((sts = pmExtractValue(vsp->valfmt, &vsp->vlist[0],
+ PM_TYPE_STRING, &av, PM_TYPE_STRING)) < 0)
+ return sts;
+ }
+ sts = PAPI_reset(EventSet);
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG, "reset: %d\n", sts);
+ if (sts != PAPI_OK)
+ return PM_ERR_VALUE;
+ break;
+#else
+ return PM_ERR_NYI;
+#endif
+
+ case 2: //papi.disable
+ if ((sts = pmExtractValue(vsp->valfmt, &vsp->vlist[0],
+ PM_TYPE_STRING, &av, PM_TYPE_STRING)) < 0)
+ return sts;
+ free(disable_string);
+ disable_string = av.cp;
+ len = strlen(disable_string);
+ substring = strtok(disable_string, delim);
+ while (substring != NULL) {
+ for (j = 0; j < size_of_active_counters; j++) {
+ if (!strcmp(substring, papi_info[j].papi_string_code)) {
+ // remove the metric from the set
+ sts = remove_metric(papi_info[j].papi_event_code, papi_info[j].position);
+ if (sts == PAPI_OK)
+ papi_info[j].position = -1;
+ break; //we've found the correct metric, break;
+ }
+ }
+ if (j == size_of_active_counters) {
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG, "metric name %s does not match any known metrics\n", substring);
+ sts = 1;
+ }
+ substring = strtok(NULL, delim);
+ }
+ for (j = 0; j < len-1; j++) { // recover from tokenisation
+ if (disable_string[j] == '\0')
+ disable_string[j] = delim[0];
+ }
+ if (sts)
+ return PM_ERR_CONV;
+ break;
+
+ default:
+ return PM_ERR_PMID;
+ }
+ }
+ return 0;
+}
+
+static int
+papi_text(int ident, int type, char **buffer, pmdaExt *ep)
+{
+ int ec;
+ int i;
+ int position = -1;
+ PAPI_event_info_t info;
+ __pmID_int *pmidp = (__pmID_int*)&ident;
+
+ /* no indoms - we only deal with metric help text */
+ if ((type & PM_TEXT_PMID) != PM_TEXT_PMID)
+ return PM_ERR_TEXT;
+
+ ec = 0 | PAPI_PRESET_MASK;
+ PAPI_enum_event(&ec, PAPI_ENUM_FIRST);
+ for (i = 0; i < number_of_events; i++) {
+ if (pmidp->item == papi_info[i].pmns_position) {
+ position = i;
+ break;
+ }
+ }
+
+ do {
+ if (PAPI_get_event_info(ec, &info) == PAPI_OK) {
+ if (info.event_code == papi_info[position].papi_event_code) {
+ if (type & PM_TEXT_ONELINE)
+ *buffer = info.short_descr;
+ else
+ *buffer = info.long_descr;
+ return 0;
+ }
+ }
+ } while (PAPI_enum_event(&ec, 0) == PAPI_OK);
+
+ return pmdaText(ident, type, buffer, ep);
+}
+
+static int
+papi_internal_init(void)
+{
+ int ec;
+ int sts;
+ int addunderscore;
+ PAPI_event_info_t info;
+ char *substr;
+ char concatstr[10] = {};
+ unsigned int i = 0;
+
+ number_of_counters = PAPI_num_counters();
+ if (number_of_counters < 0){
+ __pmNotifyErr(LOG_ERR, "hardware does not support hardware counters\n");
+ return 1;
+ }
+
+ ec = 0 | PAPI_PRESET_MASK;
+ sts = PAPI_library_init(PAPI_VER_CURRENT);
+ if (sts != PAPI_VER_CURRENT) {
+ __pmNotifyErr(LOG_DEBUG, "PAPI_library_init error!\n");
+ return PM_ERR_GENERIC;
+ }
+
+ sts = PAPI_set_domain(PAPI_DOM_ALL);
+ if (sts != PAPI_OK) {
+ __pmNotifyErr(LOG_DEBUG, "Cannot set the domain to PAPI_DOM_ALL.\n");
+ return PM_ERR_GENERIC;
+ }
+
+ enable_string = (char *)calloc(1, 1);
+ disable_string = (char *)calloc(1, 1);
+ PAPI_enum_event(&ec, PAPI_ENUM_FIRST);
+ do {
+ if (PAPI_get_event_info(ec, &info) == PAPI_OK) {
+ i++;
+ expand_papi_info(i);
+ papi_info[i-1].papi_event_code = info.event_code;
+ substr = strtok(info.symbol, "_");
+ while (substr != NULL) {
+ addunderscore = 0;
+ if (strcmp("PAPI",substr)) {
+ addunderscore = 1;
+ strcat(concatstr, substr);
+ }
+ substr = strtok(NULL, "_");
+ if (substr != NULL && addunderscore) {
+ strcat(concatstr, "_");
+ }
+ }
+ strcpy(papi_info[i-1].papi_string_code, concatstr);
+ memset(&concatstr[0], 0, sizeof(concatstr));
+ papi_info[i-1].position = -1;
+ set_pmns_position(i-1);
+ }
+ } while(PAPI_enum_event(&ec, 0) == PAPI_OK);
+ expand_values(i);
+ if (PAPI_create_eventset(&EventSet) != PAPI_OK) {
+ __pmNotifyErr(LOG_ERR, "PAPI_create_eventset error!\n");
+ return PM_ERR_GENERIC;
+ }
+ return 0;
+
+}
+
+/* use documented in pmdaAttribute(3) */
+static int
+papi_contextAttributeCallBack(int context, int attr,
+ const char *value, int length, pmdaExt *pmda)
+{
+ int id = -1;
+
+ enlarge_ctxtab(context);
+ assert(ctxtab != NULL && context < ctxtab_size);
+
+ switch (attr) {
+ case PCP_ATTR_USERID:
+ ctxtab[context].uid_p = 1;
+ id = atoi(value);
+ ctxtab[context].uid = id;
+ break;
+
+ case PCP_ATTR_GROUPID:
+ ctxtab[context].gid_p = 1;
+ id = atoi(value);
+ ctxtab[context].gid = id;
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (id != 0) {
+ if (pmDebug & DBG_TRACE_AUTH)
+ __pmNotifyErr(LOG_DEBUG, "access denied attr=%d id=%d\n", attr, id);
+ return PM_ERR_PERMISSION;
+ }
+ else if (pmDebug & DBG_TRACE_AUTH)
+ __pmNotifyErr(LOG_DEBUG, "access granted attr=%d id=%d\n", attr, id);
+
+ return 0;
+}
+
+void
+__PMDA_INIT_CALL
+papi_init(pmdaInterface *dp)
+{
+ int nummetrics = sizeof(metrictab)/sizeof(metrictab[0]);
+ int sts;
+
+ if (isDSO) {
+ char mypath[MAXPATHLEN];
+ int sep = __pmPathSeparator();
+
+ snprintf(mypath, sizeof(mypath), "%s%c" "papi" "%c" "help",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ pmdaDSO(dp, PMDA_INTERFACE_6, "papi DSO", mypath);
+ }
+
+ if (dp->status != 0)
+ return;
+
+ dp->comm.flags |= PDU_FLAG_AUTH;
+
+ if ((sts = papi_internal_init()) != 0) {
+ __pmNotifyErr(LOG_ERR, "papi_internal_init returned %d\n", sts);
+ dp->status = PM_ERR_GENERIC;
+ return;
+ }
+
+ dp->version.six.fetch = papi_fetch;
+ dp->version.six.store = papi_store;
+ dp->version.six.attribute = papi_contextAttributeCallBack;
+ dp->version.any.text = papi_text;
+ pmdaSetFetchCallBack(dp, papi_fetchCallBack);
+ pmdaSetEndContextCallBack(dp, papi_endContextCallBack);
+ pmdaInit(dp, NULL, 0, metrictab, nummetrics);
+}
+
+static pmLongOptions longopts[] = {
+ PMDA_OPTIONS_HEADER("Options"),
+ PMOPT_DEBUG,
+ PMDAOPT_DOMAIN,
+ PMDAOPT_LOGFILE,
+ PMOPT_HELP,
+ PMDA_OPTIONS_END
+};
+
+static pmdaOptions opts = {
+ .short_options = "D:d:l:?",
+ .long_options = longopts,
+};
+
+/*
+ * Set up agent if running as daemon.
+ */
+int
+main(int argc, char **argv)
+{
+ int sep = __pmPathSeparator();
+ pmdaInterface dispatch;
+ char helppath[MAXPATHLEN];
+
+ isDSO = 0;
+ __pmSetProgname(argv[0]);
+
+ snprintf(helppath, sizeof(helppath), "%s%c" "papi" "%c" "help",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ pmdaDaemon(&dispatch, PMDA_INTERFACE_6, pmProgname, PAPI, "papi.log", helppath);
+ pmdaGetOptions(argc, argv, &opts, &dispatch);
+ if (opts.errors) {
+ pmdaUsageMessage(&opts);
+ exit(1);
+ }
+
+ pmdaOpenLog(&dispatch);
+ papi_init(&dispatch);
+ pmdaConnect(&dispatch);
+ pmdaMain(&dispatch);
+
+ free(ctxtab);
+ free(papi_info);
+ free(values);
+
+ exit(0);
+}