diff options
author | Kuriakose Kuruvilla <Kuriakose.Kuruvilla@Sun.COM> | 2009-04-25 16:18:07 -0700 |
---|---|---|
committer | Kuriakose Kuruvilla <Kuriakose.Kuruvilla@Sun.COM> | 2009-04-25 16:18:07 -0700 |
commit | e850fb0196638a06a748477ed1b45c68bb830271 (patch) | |
tree | 5b6dee6ac9441b911a24b7a3762f48f298295fd6 /usr/src/lib/libcpc/common/libcpc.c | |
parent | 815eca69df2a0b561d179d0e5e4aab944d89283c (diff) | |
download | illumos-joyent-e850fb0196638a06a748477ed1b45c68bb830271.tar.gz |
6672329 New performance counter events in Griffin processor
6671120 Add new performance events for Shanghai processor
6770238 Add new performance events for Istanbul processor
Contributed by Boris Ostrovsky <Boris.Ostrovsky@amd.com>
Diffstat (limited to 'usr/src/lib/libcpc/common/libcpc.c')
-rw-r--r-- | usr/src/lib/libcpc/common/libcpc.c | 159 |
1 files changed, 56 insertions, 103 deletions
diff --git a/usr/src/lib/libcpc/common/libcpc.c b/usr/src/lib/libcpc/common/libcpc.c index ad9e288781..5bdba39fda 100644 --- a/usr/src/lib/libcpc/common/libcpc.c +++ b/usr/src/lib/libcpc/common/libcpc.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -783,13 +783,14 @@ cpc_walk_requests(cpc_t *cpc, cpc_set_t *set, void *arg, } /*ARGSUSED*/ -void -cpc_walk_events_all(cpc_t *cpc, void *arg, - void (*action)(void *arg, const char *event)) +static void +cpc_walk_events_impl(cpc_t *cpc, void *arg, + void (*action)(void *arg, const char *event), int is_generic) { char **list; char *p, *e; int i; + int is_papi; int ncounters = cpc_npic(cpc); cpc_strhash_t *hash; @@ -808,17 +809,24 @@ cpc_walk_events_all(cpc_t *cpc, void *arg, while ((e = strchr(p, ',')) != NULL) { *e = '\0'; - /* Skip any generic event names we find. */ - if ((strncmp(p, "PAPI", 4)) == 0) { + /* + * Based on is_generic flag, skip appropriate + * event names. + */ + is_papi = (strncmp(p, "PAPI", 4) == 0); + if (is_generic != is_papi) { p = e + 1; continue; } if (__cpc_strhash_add(hash, p) == -1) goto err; + p = e + 1; } - if ((strncmp(p, "PAPI", 4)) != 0) { + + is_papi = (strncmp(p, "PAPI", 4) == 0); + if (is_generic == is_papi) { if (__cpc_strhash_add(hash, p) == -1) goto err; } @@ -836,64 +844,30 @@ err: /*ARGSUSED*/ void -cpc_walk_generic_events_all(cpc_t *cpc, void *arg, - void (*action)(void *arg, const char *event)) +cpc_walk_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; - } - } + cpc_walk_events_impl(cpc, arg, action, 0); +} - 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)) +{ + cpc_walk_events_impl(cpc, arg, action, 1); } /*ARGSUSED*/ -void -cpc_walk_events_pic(cpc_t *cpc, uint_t picno, void *arg, - void (*action)(void *arg, uint_t picno, const char *event)) +static void +cpc_walk_events_pic_impl(cpc_t *cpc, uint_t picno, void *arg, + void (*action)(void *arg, uint_t picno, const char *event), int is_generic) { char *p; char *e; char *list; + int is_papi; if (picno >= cpc->cpc_npic) { errno = EINVAL; @@ -911,8 +885,12 @@ cpc_walk_events_pic(cpc_t *cpc, uint_t picno, void *arg, while ((e = strchr(p, ',')) != NULL) { *e = '\0'; - /* Skip any generic event names we find. */ - if ((strncmp(p, "PAPI", 4)) == 0) { + /* + * Based on is_generic flag, skip appropriate + * event names. + */ + is_papi = (strncmp(p, "PAPI", 4) == 0); + if (is_generic != is_papi) { p = e + 1; continue; } @@ -921,57 +899,27 @@ cpc_walk_events_pic(cpc_t *cpc, uint_t picno, void *arg, p = e + 1; } - if ((strncmp(p, "PAPI", 4)) == 0) - goto out; - - action(arg, picno, p); + is_papi = (strncmp(p, "PAPI", 4) == 0); + if (is_generic == is_papi) + action(arg, picno, p); -out: free(list); } /*ARGSUSED*/ void -cpc_walk_generic_events_pic(cpc_t *cpc, uint_t picno, void *arg, +cpc_walk_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); + cpc_walk_events_pic_impl(cpc, picno, arg, action, 0); +} -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)) +{ + cpc_walk_events_pic_impl(cpc, picno, arg, action, 1); } /*ARGSUSED*/ @@ -1190,6 +1138,7 @@ cpc_valid_event(cpc_t *cpc, uint_t pic, const char *ev) { struct priv pr = { NULL, 0 }; char *end_ev; + int err; pr.name = ev; cpc_walk_events_pic(cpc, pic, &pr, ev_walker); @@ -1202,18 +1151,22 @@ cpc_valid_event(cpc_t *cpc, uint_t pic, const char *ev) /* * 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 - * already has a corresponding event name in existing backends and it - * is the only reasonable way to know if strtol() succeeded. + * a raw event code. * Check the second argument of strtol() to ensure invalid events * beginning with number do not go through. */ - if ((strtol(ev, &end_ev, 0) != 0) && (*end_ev == '\0')) + err = errno; + errno = 0; + (void) strtol(ev, &end_ev, 0); + if ((errno == 0) && (*end_ev == '\0')) { /* * Success - this is a valid raw code in hex, decimal, or octal. */ + errno = err; return (1); + } + errno = err; return (0); } |