summaryrefslogtreecommitdiff
path: root/usr/src/lib/libcpc/common/libcpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libcpc/common/libcpc.c')
-rw-r--r--usr/src/lib/libcpc/common/libcpc.c125
1 files changed, 122 insertions, 3 deletions
diff --git a/usr/src/lib/libcpc/common/libcpc.c b/usr/src/lib/libcpc/common/libcpc.c
index df431abcc4..ad9e288781 100644
--- a/usr/src/lib/libcpc/common/libcpc.c
+++ b/usr/src/lib/libcpc/common/libcpc.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <libcpc.h>
#include <stdio.h>
#include <stdlib.h>
@@ -809,12 +807,73 @@ cpc_walk_events_all(cpc_t *cpc, void *arg,
p = list[i];
while ((e = strchr(p, ',')) != NULL) {
*e = '\0';
+
+ /* Skip any generic event names we find. */
+ if ((strncmp(p, "PAPI", 4)) == 0) {
+ p = e + 1;
+ continue;
+ }
+
if (__cpc_strhash_add(hash, p) == -1)
goto err;
p = e + 1;
}
- if (__cpc_strhash_add(hash, p) == -1)
+ if ((strncmp(p, "PAPI", 4)) != 0) {
+ if (__cpc_strhash_add(hash, p) == -1)
+ goto err;
+ }
+ }
+
+ while ((p = __cpc_strhash_next(hash)) != NULL)
+ action(arg, p);
+
+err:
+ __cpc_strhash_free(hash);
+ for (i = 0; i < ncounters; i++)
+ free(list[i]);
+ free(list);
+}
+
+/*ARGSUSED*/
+void
+cpc_walk_generic_events_all(cpc_t *cpc, void *arg,
+ void (*action)(void *arg, const char *event))
+{
+ char **list;
+ char *p, *e;
+ int i;
+ int ncounters = cpc_npic(cpc);
+ cpc_strhash_t *hash;
+
+ if ((list = malloc(ncounters * sizeof (char *))) == NULL)
+ return;
+
+ if ((hash = __cpc_strhash_alloc()) == NULL) {
+ free(list);
+ return;
+ }
+
+ for (i = 0; i < ncounters; i++) {
+ if ((list[i] = strdup(cpc->cpc_evlist[i])) == NULL)
goto err;
+ p = list[i];
+ while ((e = strchr(p, ',')) != NULL) {
+ *e = '\0';
+
+ /* Skip any platform specific event names we find. */
+ if ((strncmp(p, "PAPI", 4)) != 0) {
+ p = e + 1;
+ continue;
+ }
+
+ if (__cpc_strhash_add(hash, p) == -1)
+ goto err;
+ p = e + 1;
+ }
+ if ((strncmp(p, "PAPI", 4)) == 0) {
+ if (__cpc_strhash_add(hash, p) == -1)
+ goto err;
+ }
}
while ((p = __cpc_strhash_next(hash)) != NULL)
@@ -851,11 +910,67 @@ cpc_walk_events_pic(cpc_t *cpc, uint_t picno, void *arg,
p = list;
while ((e = strchr(p, ',')) != NULL) {
*e = '\0';
+
+ /* Skip any generic event names we find. */
+ if ((strncmp(p, "PAPI", 4)) == 0) {
+ p = e + 1;
+ continue;
+ }
+
action(arg, picno, p);
p = e + 1;
}
+
+ if ((strncmp(p, "PAPI", 4)) == 0)
+ goto out;
+
action(arg, picno, p);
+out:
+ free(list);
+}
+
+/*ARGSUSED*/
+void
+cpc_walk_generic_events_pic(cpc_t *cpc, uint_t picno, void *arg,
+ void (*action)(void *arg, uint_t picno, const char *event))
+{
+ char *p;
+ char *e;
+ char *list;
+
+ if (picno >= cpc->cpc_npic) {
+ errno = EINVAL;
+ return;
+ }
+
+ if ((list = strdup(cpc->cpc_evlist[picno])) == NULL)
+ return;
+
+ /*
+ * List now points to a comma-separated list of events supported by
+ * the designated pic.
+ */
+ p = list;
+ while ((e = strchr(p, ',')) != NULL) {
+ *e = '\0';
+
+ /* Skip any platform specific event names we find. */
+ if ((strncmp(p, "PAPI", 4)) != 0) {
+ p = e + 1;
+ continue;
+ }
+
+ action(arg, picno, p);
+ p = e + 1;
+ }
+
+ if ((strncmp(p, "PAPI", 4)) != 0)
+ goto out;
+
+ action(arg, picno, p);
+
+out:
free(list);
}
@@ -1081,6 +1196,10 @@ cpc_valid_event(cpc_t *cpc, uint_t pic, const char *ev)
if (pr.found)
return (1);
+ cpc_walk_generic_events_pic(cpc, pic, &pr, ev_walker);
+ if (pr.found)
+ return (1);
+
/*
* Before assuming this is an invalid event, see if we have been given
* a raw event code. An event code of '0' is not recognized, as it