|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* check_events.c - show event encoding
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Copyright (c) 2009 Google, Inc
|
|
Packit |
577717 |
* Contributed by Stephane Eranian <eranian@gmail.com>
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
Packit |
577717 |
* of this software and associated documentation files (the "Software"), to deal
|
|
Packit |
577717 |
* in the Software without restriction, including without limitation the rights
|
|
Packit |
577717 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
Packit |
577717 |
* of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
Packit |
577717 |
* subject to the following conditions:
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The above copyright notice and this permission notice shall be included in all
|
|
Packit |
577717 |
* copies or substantial portions of the Software.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
Packit |
577717 |
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
Packit |
577717 |
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
Packit |
577717 |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
Packit |
577717 |
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
|
Packit |
577717 |
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* This file is part of libpfm, a performance monitoring support library for
|
|
Packit |
577717 |
* applications on Linux.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#include <sys/types.h>
|
|
Packit |
577717 |
#include <inttypes.h>
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <stdlib.h>
|
|
Packit |
577717 |
#include <stdarg.h>
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#include <perfmon/err.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <perfmon/pfmlib.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
pmu_is_present(pfm_pmu_t p)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
pfm_pmu_info_t pinfo;
|
|
Packit |
577717 |
int ret;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset(&pinfo, 0, sizeof(pinfo));
|
|
Packit |
577717 |
ret = pfm_get_pmu_info(p, &pinfo);
|
|
Packit |
577717 |
return ret == PFM_SUCCESS ? pinfo.is_present : 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
main(int argc, const char **argv)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
pfm_pmu_info_t pinfo;
|
|
Packit |
577717 |
pfm_pmu_encode_arg_t e;
|
|
Packit |
577717 |
const char *arg[3];
|
|
Packit |
577717 |
const char **p;
|
|
Packit |
577717 |
char *fqstr;
|
|
Packit |
577717 |
pfm_event_info_t info;
|
|
Packit |
577717 |
int i, j, ret;
|
|
Packit |
577717 |
int total_supported_events = 0;
|
|
Packit |
577717 |
int total_available_events = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Initialize pfm library (required before we can use it)
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
ret = pfm_initialize();
|
|
Packit |
577717 |
if (ret != PFM_SUCCESS)
|
|
Packit |
577717 |
errx(1, "cannot initialize library: %s\n", pfm_strerror(ret));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset(&pinfo, 0, sizeof(pinfo));
|
|
Packit |
577717 |
memset(&info, 0, sizeof(info));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
printf("Supported PMU models:\n");
|
|
Packit |
577717 |
for(i=0; i < PFM_PMU_MAX; i++) {
|
|
Packit |
577717 |
ret = pfm_get_pmu_info(i, &pinfo);
|
|
Packit |
577717 |
if (ret != PFM_SUCCESS)
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
printf("\t[%d, %s, \"%s\"]\n", i, pinfo.name, pinfo.desc);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
printf("Detected PMU models:\n");
|
|
Packit |
577717 |
for(i=0; i < PFM_PMU_MAX; i++) {
|
|
Packit |
577717 |
ret = pfm_get_pmu_info(i, &pinfo);
|
|
Packit |
577717 |
if (ret != PFM_SUCCESS)
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
if (pinfo.is_present) {
|
|
Packit |
577717 |
printf("\t[%d, %s, \"%s\"]\n", i, pinfo.name, pinfo.desc);
|
|
Packit |
577717 |
total_supported_events += pinfo.nevents;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
total_available_events += pinfo.nevents;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
printf("Total events: %d available, %d supported\n", total_available_events, total_supported_events);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* be nice to user!
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if (argc < 2 && pmu_is_present(PFM_PMU_PERF_EVENT)) {
|
|
Packit |
577717 |
arg[0] = "PERF_COUNT_HW_CPU_CYCLES";
|
|
Packit |
577717 |
arg[1] = "PERF_COUNT_HW_INSTRUCTIONS";
|
|
Packit |
577717 |
arg[2] = NULL;
|
|
Packit |
577717 |
p = arg;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
p = argv+1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!*p)
|
|
Packit |
577717 |
errx(1, "you must pass at least one event");
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset(&e, 0, sizeof(e));
|
|
Packit |
577717 |
while(*p) {
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* extract raw event encoding
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* For perf_event encoding, use
|
|
Packit |
577717 |
* #include <perfmon/pfmlib_perf_event.h>
|
|
Packit |
577717 |
* and the function:
|
|
Packit |
577717 |
* pfm_get_perf_event_encoding()
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
fqstr = NULL;
|
|
Packit |
577717 |
e.fstr = &fqstr;
|
|
Packit |
577717 |
ret = pfm_get_os_event_encoding(*p, PFM_PLM0|PFM_PLM3, PFM_OS_NONE, &e);
|
|
Packit |
577717 |
if (ret != PFM_SUCCESS) {
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* codes is too small for this event
|
|
Packit |
577717 |
* free and let the library resize
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if (ret == PFM_ERR_TOOSMALL) {
|
|
Packit |
577717 |
free(e.codes);
|
|
Packit |
577717 |
e.codes = NULL;
|
|
Packit |
577717 |
e.count = 0;
|
|
Packit |
577717 |
free(fqstr);
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (ret == PFM_ERR_NOTFOUND && strstr(*p, "::"))
|
|
Packit |
577717 |
errx(1, "%s: try setting LIBPFM_ENCODE_INACTIVE=1", pfm_strerror(ret));
|
|
Packit |
577717 |
errx(1, "cannot encode event %s: %s", *p, pfm_strerror(ret));
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
ret = pfm_get_event_info(e.idx, PFM_OS_NONE, &info;;
|
|
Packit |
577717 |
if (ret != PFM_SUCCESS)
|
|
Packit |
577717 |
errx(1, "cannot get event info: %s", pfm_strerror(ret));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ret = pfm_get_pmu_info(info.pmu, &pinfo);
|
|
Packit |
577717 |
if (ret != PFM_SUCCESS)
|
|
Packit |
577717 |
errx(1, "cannot get PMU info: %s", pfm_strerror(ret));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
printf("Requested Event: %s\n", *p);
|
|
Packit |
577717 |
printf("Actual Event: %s\n", fqstr);
|
|
Packit |
577717 |
printf("PMU : %s\n", pinfo.desc);
|
|
Packit |
577717 |
printf("IDX : %d\n", e.idx);
|
|
Packit |
577717 |
printf("Codes :");
|
|
Packit |
577717 |
for(j=0; j < e.count; j++)
|
|
Packit |
577717 |
printf(" 0x%"PRIx64, e.codes[j]);
|
|
Packit |
577717 |
putchar('\n');
|
|
Packit |
577717 |
|
|
Packit |
577717 |
free(fqstr);
|
|
Packit |
577717 |
p++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (e.codes)
|
|
Packit |
577717 |
free(e.codes);
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|