|
Packit Service |
a1973e |
/*
|
|
Packit Service |
a1973e |
* showevtinfo.c - show event information
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* Copyright (c) 2010 Google, Inc
|
|
Packit Service |
a1973e |
* Contributed by Stephane Eranian <eranian@gmail.com>
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
Packit Service |
a1973e |
* of this software and associated documentation files (the "Software"), to deal
|
|
Packit Service |
a1973e |
* in the Software without restriction, including without limitation the rights
|
|
Packit Service |
a1973e |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
Packit Service |
a1973e |
* of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
Packit Service |
a1973e |
* subject to the following conditions:
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* The above copyright notice and this permission notice shall be included in all
|
|
Packit Service |
a1973e |
* copies or substantial portions of the Software.
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
Packit Service |
a1973e |
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
Packit Service |
a1973e |
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
Packit Service |
a1973e |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
Packit Service |
a1973e |
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
|
Packit Service |
a1973e |
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* This file is part of libpfm, a performance monitoring support library for
|
|
Packit Service |
a1973e |
* applications on Linux.
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
#include <sys/types.h>
|
|
Packit Service |
a1973e |
#include <stdio.h>
|
|
Packit Service |
a1973e |
#include <stdlib.h>
|
|
Packit Service |
a1973e |
#include <inttypes.h>
|
|
Packit Service |
a1973e |
#include <stdarg.h>
|
|
Packit Service |
a1973e |
#include <errno.h>
|
|
Packit Service |
a1973e |
#include <unistd.h>
|
|
Packit Service |
a1973e |
#include <string.h>
|
|
Packit Service |
a1973e |
#include <regex.h>
|
|
Packit Service |
a1973e |
#include <perfmon/err.h>
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include <perfmon/pfmlib.h>
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define MAXBUF 1024
|
|
Packit Service |
a1973e |
#define COMBO_MAX 18
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static struct {
|
|
Packit Service |
a1973e |
int compact;
|
|
Packit Service |
a1973e |
int sort;
|
|
Packit Service |
a1973e |
uint8_t encode;
|
|
Packit Service |
a1973e |
uint8_t combo;
|
|
Packit Service |
a1973e |
uint8_t combo_lim;
|
|
Packit Service |
a1973e |
uint8_t name_only;
|
|
Packit Service |
a1973e |
uint8_t desc;
|
|
Packit Service |
a1973e |
char *csv_sep;
|
|
Packit Service |
a1973e |
pfm_event_info_t efilter;
|
|
Packit Service |
a1973e |
pfm_event_attr_info_t ufilter;
|
|
Packit Service |
a1973e |
pfm_os_t os;
|
|
Packit Service |
a1973e |
uint64_t mask;
|
|
Packit Service |
a1973e |
} options;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
typedef struct {
|
|
Packit Service |
a1973e |
uint64_t code;
|
|
Packit Service |
a1973e |
int idx;
|
|
Packit Service |
a1973e |
} code_info_t;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void show_event_info_compact(pfm_event_info_t *info);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static const char *srcs[PFM_ATTR_CTRL_MAX]={
|
|
Packit Service |
a1973e |
[PFM_ATTR_CTRL_UNKNOWN] = "???",
|
|
Packit Service |
a1973e |
[PFM_ATTR_CTRL_PMU] = "PMU",
|
|
Packit Service |
a1973e |
[PFM_ATTR_CTRL_PERF_EVENT] = "perf_event",
|
|
Packit Service |
a1973e |
};
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef PFMLIB_WINDOWS
|
|
Packit Service |
a1973e |
int set_env_var(const char *var, const char *value, int ov)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
size_t len;
|
|
Packit Service |
a1973e |
char *str;
|
|
Packit Service |
a1973e |
int ret;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
len = strlen(var) + 1 + strlen(value) + 1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
str = malloc(len);
|
|
Packit Service |
a1973e |
if (!str)
|
|
Packit Service |
a1973e |
return PFM_ERR_NOMEM;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
sprintf(str, "%s=%s", var, value);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = putenv(str);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
free(str);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return ret ? PFM_ERR_INVAL : PFM_SUCCESS;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#else
|
|
Packit Service |
a1973e |
static inline int
|
|
Packit Service |
a1973e |
set_env_var(const char *var, const char *value, int ov)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
return setenv(var, value, ov);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
event_has_pname(char *s)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
char *p;
|
|
Packit Service |
a1973e |
return (p = strchr(s, ':')) && *(p+1) == ':';
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
print_codes(char *buf, int plm, int max_encoding)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
uint64_t *codes = NULL;
|
|
Packit Service |
a1973e |
int j, ret, count = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = pfm_get_event_encoding(buf, PFM_PLM0|PFM_PLM3, NULL, NULL, &codes, &count);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS) {
|
|
Packit Service |
a1973e |
if (ret == PFM_ERR_NOTFOUND)
|
|
Packit Service |
a1973e |
errx(1, "encoding failed, try setting env variable LIBPFM_ENCODE_INACTIVE=1");
|
|
Packit Service |
a1973e |
return -1;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
for(j = 0; j < max_encoding; j++) {
|
|
Packit Service |
a1973e |
if (j < count)
|
|
Packit Service |
a1973e |
printf("0x%"PRIx64, codes[j]);
|
|
Packit Service |
a1973e |
printf("%s", options.csv_sep);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
free(codes);
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
check_valid(char *buf, int plm)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
uint64_t *codes = NULL;
|
|
Packit Service |
a1973e |
int ret, count = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = pfm_get_event_encoding(buf, PFM_PLM0|PFM_PLM3, NULL, NULL, &codes, &count);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
return -1;
|
|
Packit Service |
a1973e |
free(codes);
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
match_ufilters(pfm_event_attr_info_t *info)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
uint32_t ufilter1 = 0;
|
|
Packit Service |
a1973e |
uint32_t ufilter2 = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (options.ufilter.is_dfl)
|
|
Packit Service |
a1973e |
ufilter1 |= 0x1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (info->is_dfl)
|
|
Packit Service |
a1973e |
ufilter2 |= 0x1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (options.ufilter.is_precise)
|
|
Packit Service |
a1973e |
ufilter1 |= 0x2;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (info->is_precise)
|
|
Packit Service |
a1973e |
ufilter2 |= 0x2;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (!ufilter1)
|
|
Packit Service |
a1973e |
return 1;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* at least one filter matches */
|
|
Packit Service |
a1973e |
return ufilter1 & ufilter2;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
match_efilters(pfm_event_info_t *info)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pfm_event_attr_info_t ainfo;
|
|
Packit Service |
a1973e |
int n = 0;
|
|
Packit Service |
a1973e |
int i, ret;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (options.efilter.is_precise && !info->is_precise)
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset(&ainfo, 0, sizeof(ainfo));
|
|
Packit Service |
a1973e |
ainfo.size = sizeof(ainfo);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pfm_for_each_event_attr(i, info) {
|
|
Packit Service |
a1973e |
ret = pfm_get_event_attr_info(info->idx, i, options.os, &ainfo);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
if (match_ufilters(&ainfo))
|
|
Packit Service |
a1973e |
return 1;
|
|
Packit Service |
a1973e |
if (ainfo.type == PFM_ATTR_UMASK)
|
|
Packit Service |
a1973e |
n++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
return n ? 0 : 1;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
show_event_info_combo(pfm_event_info_t *info)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pfm_event_attr_info_t *ainfo;
|
|
Packit Service |
a1973e |
pfm_pmu_info_t pinfo;
|
|
Packit Service |
a1973e |
char buf[MAXBUF];
|
|
Packit Service |
a1973e |
size_t len;
|
|
Packit Service |
a1973e |
int numasks = 0;
|
|
Packit Service |
a1973e |
int i, j, ret;
|
|
Packit Service |
a1973e |
uint64_t total, m, u;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset(&pinfo, 0, sizeof(pinfo));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pinfo.size = sizeof(pinfo);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = pfm_get_pmu_info(info->pmu, &pinfo);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
errx(1, "cannot get PMU info");
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ainfo = calloc(info->nattrs, sizeof(*ainfo));
|
|
Packit Service |
a1973e |
if (!ainfo)
|
|
Packit Service |
a1973e |
err(1, "event %s : ", info->name);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/*
|
|
Packit Service |
a1973e |
* extract attribute information and count number
|
|
Packit Service |
a1973e |
* of umasks
|
|
Packit Service |
a1973e |
*
|
|
Packit Service |
a1973e |
* we cannot just drop non umasks because we need
|
|
Packit Service |
a1973e |
* to keep attributes in order for the enumeration
|
|
Packit Service |
a1973e |
* of 2^n
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
pfm_for_each_event_attr(i, info) {
|
|
Packit Service |
a1973e |
ainfo[i].size = sizeof(*ainfo);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = pfm_get_event_attr_info(info->idx, i, options.os, &ainfo[i]);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
errx(1, "cannot get attribute info: %s", pfm_strerror(ret));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (ainfo[i].type == PFM_ATTR_UMASK)
|
|
Packit Service |
a1973e |
numasks++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if (numasks > options.combo_lim) {
|
|
Packit Service |
a1973e |
warnx("event %s has too many umasks to print all combinations, dropping to simple enumeration", info->name);
|
|
Packit Service |
a1973e |
free(ainfo);
|
|
Packit Service |
a1973e |
show_event_info_compact(info);
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (numasks) {
|
|
Packit Service |
a1973e |
if (info->nattrs > (int)((sizeof(total)<<3))) {
|
|
Packit Service |
a1973e |
warnx("too many umasks, cannot show all combinations for event %s", info->name);
|
|
Packit Service |
a1973e |
goto end;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
total = 1ULL << info->nattrs;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for (u = 1; u < total; u++) {
|
|
Packit Service |
a1973e |
len = sizeof(buf);
|
|
Packit Service |
a1973e |
len -= snprintf(buf, len, "%s::%s", pinfo.name, info->name);
|
|
Packit Service |
a1973e |
if (len <= 0) {
|
|
Packit Service |
a1973e |
warnx("event name too long%s", info->name);
|
|
Packit Service |
a1973e |
goto end;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
for(m = u, j = 0; m; m >>=1, j++) {
|
|
Packit Service |
a1973e |
if (m & 0x1ULL) {
|
|
Packit Service |
a1973e |
/* we have hit a non umasks attribute, skip */
|
|
Packit Service |
a1973e |
if (ainfo[j].type != PFM_ATTR_UMASK)
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (len < (1 + strlen(ainfo[j].name))) {
|
|
Packit Service |
a1973e |
warnx("umasks combination too long for event %s", buf);
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
strncat(buf, ":", len-1);buf[len-1] = '\0'; len--;
|
|
Packit Service |
a1973e |
strncat(buf, ainfo[j].name, len-1);buf[len-1] = '\0';
|
|
Packit Service |
a1973e |
len -= strlen(ainfo[j].name);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
/* if found a valid umask combination, check encoding */
|
|
Packit Service |
a1973e |
if (m == 0) {
|
|
Packit Service |
a1973e |
if (options.encode)
|
|
Packit Service |
a1973e |
ret = print_codes(buf, PFM_PLM0|PFM_PLM3, pinfo.max_encoding);
|
|
Packit Service |
a1973e |
else
|
|
Packit Service |
a1973e |
ret = check_valid(buf, PFM_PLM0|PFM_PLM3);
|
|
Packit Service |
a1973e |
if (!ret)
|
|
Packit Service |
a1973e |
printf("%s\n", buf);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
snprintf(buf, sizeof(buf)-1, "%s::%s", pinfo.name, info->name);
|
|
Packit Service |
a1973e |
buf[sizeof(buf)-1] = '\0';
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = options.encode ? print_codes(buf, PFM_PLM0|PFM_PLM3, pinfo.max_encoding) : 0;
|
|
Packit Service |
a1973e |
if (!ret)
|
|
Packit Service |
a1973e |
printf("%s\n", buf);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
end:
|
|
Packit Service |
a1973e |
free(ainfo);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
show_event_info_compact(pfm_event_info_t *info)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pfm_event_attr_info_t ainfo;
|
|
Packit Service |
a1973e |
pfm_pmu_info_t pinfo;
|
|
Packit Service |
a1973e |
char buf[MAXBUF];
|
|
Packit Service |
a1973e |
int i, ret, um = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset(&ainfo, 0, sizeof(ainfo));
|
|
Packit Service |
a1973e |
memset(&pinfo, 0, sizeof(pinfo));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pinfo.size = sizeof(pinfo);
|
|
Packit Service |
a1973e |
ainfo.size = sizeof(ainfo);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = pfm_get_pmu_info(info->pmu, &pinfo);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
errx(1, "cannot get pmu info: %s", pfm_strerror(ret));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (options.name_only) {
|
|
Packit Service |
a1973e |
if (options.encode)
|
|
Packit Service |
a1973e |
printf("0x%-10"PRIx64, info->code);
|
|
Packit Service |
a1973e |
printf("%s\n", info->name);
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
pfm_for_each_event_attr(i, info) {
|
|
Packit Service |
a1973e |
ret = pfm_get_event_attr_info(info->idx, i, options.os, &ainfo);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
errx(1, "cannot get attribute info: %s", pfm_strerror(ret));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (ainfo.type != PFM_ATTR_UMASK)
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (!match_ufilters(&ainfo))
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
snprintf(buf, sizeof(buf)-1, "%s::%s:%s", pinfo.name, info->name, ainfo.name);
|
|
Packit Service |
a1973e |
buf[sizeof(buf)-1] = '\0';
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = 0;
|
|
Packit Service |
a1973e |
if (options.encode) {
|
|
Packit Service |
a1973e |
ret = print_codes(buf, PFM_PLM0|PFM_PLM3, pinfo.max_encoding);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if (!ret) {
|
|
Packit Service |
a1973e |
printf("%s", buf);
|
|
Packit Service |
a1973e |
if (options.desc) {
|
|
Packit Service |
a1973e |
printf("%s", options.csv_sep);
|
|
Packit Service |
a1973e |
printf("\"%s. %s.\"", info->desc, ainfo.desc);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
putchar('\n');
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
um++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if (um == 0) {
|
|
Packit Service |
a1973e |
if (!match_efilters(info))
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
snprintf(buf, sizeof(buf)-1, "%s::%s", pinfo.name, info->name);
|
|
Packit Service |
a1973e |
buf[sizeof(buf)-1] = '\0';
|
|
Packit Service |
a1973e |
if (options.encode) {
|
|
Packit Service |
a1973e |
ret = print_codes(buf, PFM_PLM0|PFM_PLM3, pinfo.max_encoding);
|
|
Packit Service |
a1973e |
if (ret)
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
printf("%s", buf);
|
|
Packit Service |
a1973e |
if (options.desc) {
|
|
Packit Service |
a1973e |
printf("%s", options.csv_sep);
|
|
Packit Service |
a1973e |
printf("\"%s.\"", info->desc);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
putchar('\n');
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int compare_codes(const void *a, const void *b)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
const code_info_t *aa = a;
|
|
Packit Service |
a1973e |
const code_info_t *bb = b;
|
|
Packit Service |
a1973e |
uint64_t m = options.mask;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ((aa->code & m) < (bb->code &m))
|
|
Packit Service |
a1973e |
return -1;
|
|
Packit Service |
a1973e |
if ((aa->code & m) == (bb->code & m))
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
return 1;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
print_event_flags(pfm_event_info_t *info)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int n = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (info->is_precise) {
|
|
Packit Service |
a1973e |
printf("[precise] ");
|
|
Packit Service |
a1973e |
n++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if (!n)
|
|
Packit Service |
a1973e |
printf("None");
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
print_attr_flags(pfm_event_attr_info_t *info)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int n = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (info->is_dfl) {
|
|
Packit Service |
a1973e |
printf("[default] ");
|
|
Packit Service |
a1973e |
n++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (info->is_precise) {
|
|
Packit Service |
a1973e |
printf("[precise] ");
|
|
Packit Service |
a1973e |
n++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (!n)
|
|
Packit Service |
a1973e |
printf("None ");
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
show_event_info(pfm_event_info_t *info)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pfm_event_attr_info_t ainfo;
|
|
Packit Service |
a1973e |
pfm_pmu_info_t pinfo;
|
|
Packit Service |
a1973e |
int mod = 0, um = 0;
|
|
Packit Service |
a1973e |
int i, ret;
|
|
Packit Service |
a1973e |
const char *src;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (options.name_only) {
|
|
Packit Service |
a1973e |
printf("%s\n", info->name);
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset(&ainfo, 0, sizeof(ainfo));
|
|
Packit Service |
a1973e |
memset(&pinfo, 0, sizeof(pinfo));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pinfo.size = sizeof(pinfo);
|
|
Packit Service |
a1973e |
ainfo.size = sizeof(ainfo);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (!match_efilters(info))
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
ret = pfm_get_pmu_info(info->pmu, &pinfo);
|
|
Packit Service |
a1973e |
if (ret)
|
|
Packit Service |
a1973e |
errx(1, "cannot get pmu info: %s", pfm_strerror(ret));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
printf("#-----------------------------\n"
|
|
Packit Service |
a1973e |
"IDX : %d\n"
|
|
Packit Service |
a1973e |
"PMU name : %s (%s)\n"
|
|
Packit Service |
a1973e |
"Name : %s\n"
|
|
Packit Service |
a1973e |
"Equiv : %s\n",
|
|
Packit Service |
a1973e |
info->idx,
|
|
Packit Service |
a1973e |
pinfo.name,
|
|
Packit Service |
a1973e |
pinfo.desc,
|
|
Packit Service |
a1973e |
info->name,
|
|
Packit Service |
a1973e |
info->equiv ? info->equiv : "None");
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
printf("Flags : ");
|
|
Packit Service |
a1973e |
print_event_flags(info);
|
|
Packit Service |
a1973e |
putchar('\n');
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
printf("Desc : %s\n", info->desc ? info->desc : "no description available");
|
|
Packit Service |
a1973e |
printf("Code : 0x%"PRIx64"\n", info->code);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pfm_for_each_event_attr(i, info) {
|
|
Packit Service |
a1973e |
ret = pfm_get_event_attr_info(info->idx, i, options.os, &ainfo);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
errx(1, "cannot retrieve event %s attribute info: %s", info->name, pfm_strerror(ret));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX) {
|
|
Packit Service |
a1973e |
warnx("event: %s has unsupported attribute source %d", info->name, ainfo.ctrl);
|
|
Packit Service |
a1973e |
ainfo.ctrl = PFM_ATTR_CTRL_UNKNOWN;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
src = srcs[ainfo.ctrl];
|
|
Packit Service |
a1973e |
switch(ainfo.type) {
|
|
Packit Service |
a1973e |
case PFM_ATTR_UMASK:
|
|
Packit Service |
a1973e |
if (!match_ufilters(&ainfo))
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
printf("Umask-%02u : 0x%02"PRIx64" : %s : [%s] : ",
|
|
Packit Service |
a1973e |
um,
|
|
Packit Service |
a1973e |
ainfo.code,
|
|
Packit Service |
a1973e |
src,
|
|
Packit Service |
a1973e |
ainfo.name);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
print_attr_flags(&ainfo);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
putchar(':');
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (ainfo.equiv)
|
|
Packit Service |
a1973e |
printf(" Alias to %s", ainfo.equiv);
|
|
Packit Service |
a1973e |
else
|
|
Packit Service |
a1973e |
printf(" %s", ainfo.desc);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
putchar('\n');
|
|
Packit Service |
a1973e |
um++;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case PFM_ATTR_MOD_BOOL:
|
|
Packit Service |
a1973e |
printf("Modif-%02u : 0x%02"PRIx64" : %s : [%s] : %s (boolean)\n", mod, ainfo.code, src, ainfo.name, ainfo.desc);
|
|
Packit Service |
a1973e |
mod++;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case PFM_ATTR_MOD_INTEGER:
|
|
Packit Service |
a1973e |
printf("Modif-%02u : 0x%02"PRIx64" : %s : [%s] : %s (integer)\n", mod, ainfo.code, src, ainfo.name, ainfo.desc);
|
|
Packit Service |
a1973e |
mod++;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
default:
|
|
Packit Service |
a1973e |
printf("Attr-%02u : 0x%02"PRIx64" : %s : [%s] : %s\n", i, ainfo.code, ainfo.name, src, ainfo.desc);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
show_info(char *event, regex_t *preg)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pfm_pmu_info_t pinfo;
|
|
Packit Service |
a1973e |
pfm_event_info_t info;
|
|
Packit Service |
a1973e |
int i, j, ret, match = 0, pname;
|
|
Packit Service |
a1973e |
size_t len, l = 0;
|
|
Packit Service |
a1973e |
char *fullname = NULL;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset(&pinfo, 0, sizeof(pinfo));
|
|
Packit Service |
a1973e |
memset(&info, 0, sizeof(info));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pinfo.size = sizeof(pinfo);
|
|
Packit Service |
a1973e |
info.size = sizeof(info);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pname = event_has_pname(event);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/*
|
|
Packit Service |
a1973e |
* scan all supported events, incl. those
|
|
Packit Service |
a1973e |
* from undetected PMU models
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
pfm_for_all_pmus(j) {
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = pfm_get_pmu_info(j, &pinfo);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* no pmu prefix, just look for detected PMU models */
|
|
Packit Service |
a1973e |
if (!pname && !pinfo.is_present)
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for (i = pinfo.first_event; i != -1; i = pfm_get_event_next(i)) {
|
|
Packit Service |
a1973e |
ret = pfm_get_event_info(i, options.os, &info;;
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
errx(1, "cannot get event info: %s", pfm_strerror(ret));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
len = strlen(info.name) + strlen(pinfo.name) + 1 + 2;
|
|
Packit Service |
a1973e |
if (len > l) {
|
|
Packit Service |
a1973e |
l = len;
|
|
Packit Service |
a1973e |
fullname = realloc(fullname, l);
|
|
Packit Service |
a1973e |
if (!fullname)
|
|
Packit Service |
a1973e |
err(1, "cannot allocate memory");
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
sprintf(fullname, "%s::%s", pinfo.name, info.name);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (regexec(preg, fullname, 0, NULL, 0) == 0) {
|
|
Packit Service |
a1973e |
if (options.compact)
|
|
Packit Service |
a1973e |
if (options.combo)
|
|
Packit Service |
a1973e |
show_event_info_combo(&info;;
|
|
Packit Service |
a1973e |
else
|
|
Packit Service |
a1973e |
show_event_info_compact(&info;;
|
|
Packit Service |
a1973e |
else
|
|
Packit Service |
a1973e |
show_event_info(&info;;
|
|
Packit Service |
a1973e |
match++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if (fullname)
|
|
Packit Service |
a1973e |
free(fullname);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return match;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
show_info_sorted(char *event, regex_t *preg)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pfm_pmu_info_t pinfo;
|
|
Packit Service |
a1973e |
pfm_event_info_t info;
|
|
Packit Service |
a1973e |
unsigned int j;
|
|
Packit Service |
a1973e |
int i, ret, n, match = 0;
|
|
Packit Service |
a1973e |
size_t len, l = 0;
|
|
Packit Service |
a1973e |
char *fullname = NULL;
|
|
Packit Service |
a1973e |
code_info_t *codes;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset(&pinfo, 0, sizeof(pinfo));
|
|
Packit Service |
a1973e |
memset(&info, 0, sizeof(info));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pinfo.size = sizeof(pinfo);
|
|
Packit Service |
a1973e |
info.size = sizeof(info);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pfm_for_all_pmus(j) {
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = pfm_get_pmu_info(j, &pinfo);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
codes = malloc(pinfo.nevents * sizeof(*codes));
|
|
Packit Service |
a1973e |
if (!codes)
|
|
Packit Service |
a1973e |
err(1, "cannot allocate memory\n");
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* scans all supported events */
|
|
Packit Service |
a1973e |
n = 0;
|
|
Packit Service |
a1973e |
for (i = pinfo.first_event; i != -1; i = pfm_get_event_next(i)) {
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = pfm_get_event_info(i, options.os, &info;;
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
errx(1, "cannot get event info: %s", pfm_strerror(ret));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (info.pmu != j)
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
codes[n].idx = info.idx;
|
|
Packit Service |
a1973e |
codes[n].code = info.code;
|
|
Packit Service |
a1973e |
n++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
qsort(codes, n, sizeof(*codes), compare_codes);
|
|
Packit Service |
a1973e |
for(i=0; i < n; i++) {
|
|
Packit Service |
a1973e |
ret = pfm_get_event_info(codes[i].idx, options.os, &info;;
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
errx(1, "cannot get event info: %s", pfm_strerror(ret));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
len = strlen(info.name) + strlen(pinfo.name) + 1 + 2;
|
|
Packit Service |
a1973e |
if (len > l) {
|
|
Packit Service |
a1973e |
l = len;
|
|
Packit Service |
a1973e |
fullname = realloc(fullname, l);
|
|
Packit Service |
a1973e |
if (!fullname)
|
|
Packit Service |
a1973e |
err(1, "cannot allocate memory");
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
sprintf(fullname, "%s::%s", pinfo.name, info.name);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (regexec(preg, fullname, 0, NULL, 0) == 0) {
|
|
Packit Service |
a1973e |
if (options.compact)
|
|
Packit Service |
a1973e |
show_event_info_compact(&info;;
|
|
Packit Service |
a1973e |
else
|
|
Packit Service |
a1973e |
show_event_info(&info;;
|
|
Packit Service |
a1973e |
match++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
free(codes);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if (fullname)
|
|
Packit Service |
a1973e |
free(fullname);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return match;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
usage(void)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
printf("showevtinfo [-L] [-E] [-h] [-s] [-m mask]\n"
|
|
Packit Service |
a1973e |
"-L\t\tlist one event per line (compact mode)\n"
|
|
Packit Service |
a1973e |
"-E\t\tlist one event per line with encoding (compact mode)\n"
|
|
Packit Service |
a1973e |
"-M\t\tdisplay all valid unit masks combination (use with -L or -E)\n"
|
|
Packit Service |
a1973e |
"-h\t\tget help\n"
|
|
Packit Service |
a1973e |
"-s\t\tsort event by PMU and by code based on -m mask\n"
|
|
Packit Service |
a1973e |
"-l\t\tmaximum number of umasks to list all combinations (default: %d)\n"
|
|
Packit Service |
a1973e |
"-F\t\tshow only events and attributes with certain flags (precise,...)\n"
|
|
Packit Service |
a1973e |
"-m mask\t\thexadecimal event code mask, bits to match when sorting\n"
|
|
Packit Service |
a1973e |
"-x sep\t\tuse sep as field separator in compact mode\n"
|
|
Packit Service |
a1973e |
"-D\t\t\tprint event description in compact mode\n"
|
|
Packit Service |
a1973e |
"-O os\t\tshow attributes for the specific operating system\n",
|
|
Packit Service |
a1973e |
COMBO_MAX);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/*
|
|
Packit Service |
a1973e |
* keep: [pmu::]event
|
|
Packit Service |
a1973e |
* drop everything else
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
drop_event_attributes(char *str)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
char *p;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
p = strchr(str, ':');
|
|
Packit Service |
a1973e |
if (!p)
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
str = p+1;
|
|
Packit Service |
a1973e |
/* keep PMU name */
|
|
Packit Service |
a1973e |
if (*str == ':')
|
|
Packit Service |
a1973e |
str++;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* stop string at 1st attribute */
|
|
Packit Service |
a1973e |
p = strchr(str, ':');
|
|
Packit Service |
a1973e |
if (p)
|
|
Packit Service |
a1973e |
*p = '\0';
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define EVENT_FLAGS(n, f, l) { .name = n, .ebit = f, .ubit = l }
|
|
Packit Service |
a1973e |
struct attr_flags {
|
|
Packit Service |
a1973e |
const char *name;
|
|
Packit Service |
a1973e |
int ebit; /* bit position in pfm_event_info_t.flags, -1 means ignore */
|
|
Packit Service |
a1973e |
int ubit; /* bit position in pfm_event_attr_info_t.flags, -1 means ignore */
|
|
Packit Service |
a1973e |
};
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static const struct attr_flags event_flags[]={
|
|
Packit Service |
a1973e |
EVENT_FLAGS("precise", 0, 1),
|
|
Packit Service |
a1973e |
EVENT_FLAGS("pebs", 0, 1),
|
|
Packit Service |
a1973e |
EVENT_FLAGS("default", -1, 0),
|
|
Packit Service |
a1973e |
EVENT_FLAGS("dfl", -1, 0),
|
|
Packit Service |
a1973e |
EVENT_FLAGS(NULL, 0, 0)
|
|
Packit Service |
a1973e |
};
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
parse_filters(char *arg)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
const struct attr_flags *attr;
|
|
Packit Service |
a1973e |
char *p;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
while (arg) {
|
|
Packit Service |
a1973e |
p = strchr(arg, ',');
|
|
Packit Service |
a1973e |
if (p)
|
|
Packit Service |
a1973e |
*p++ = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for (attr = event_flags; attr->name; attr++) {
|
|
Packit Service |
a1973e |
if (!strcasecmp(attr->name, arg)) {
|
|
Packit Service |
a1973e |
switch(attr->ebit) {
|
|
Packit Service |
a1973e |
case 0:
|
|
Packit Service |
a1973e |
options.efilter.is_precise = 1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case -1:
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
default:
|
|
Packit Service |
a1973e |
errx(1, "unknown event flag %d", attr->ebit);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
switch (attr->ubit) {
|
|
Packit Service |
a1973e |
case 0:
|
|
Packit Service |
a1973e |
options.ufilter.is_dfl = 1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 1:
|
|
Packit Service |
a1973e |
options.ufilter.is_precise = 1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case -1:
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
default:
|
|
Packit Service |
a1973e |
errx(1, "unknown umaks flag %d", attr->ubit);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
arg = p;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static const struct {
|
|
Packit Service |
a1973e |
char *name;
|
|
Packit Service |
a1973e |
pfm_os_t os;
|
|
Packit Service |
a1973e |
} supported_oses[]={
|
|
Packit Service |
a1973e |
{ .name = "none", .os = PFM_OS_NONE },
|
|
Packit Service |
a1973e |
{ .name = "raw", .os = PFM_OS_NONE },
|
|
Packit Service |
a1973e |
{ .name = "pmu", .os = PFM_OS_NONE },
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
{ .name = "perf", .os = PFM_OS_PERF_EVENT},
|
|
Packit Service |
a1973e |
{ .name = "perf_ext", .os = PFM_OS_PERF_EVENT_EXT},
|
|
Packit Service |
a1973e |
{ .name = NULL, }
|
|
Packit Service |
a1973e |
};
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static const char *pmu_types[]={
|
|
Packit Service |
a1973e |
"unknown type",
|
|
Packit Service |
a1973e |
"core",
|
|
Packit Service |
a1973e |
"uncore",
|
|
Packit Service |
a1973e |
"OS generic",
|
|
Packit Service |
a1973e |
};
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
setup_os(char *ostr)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int i;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for (i = 0; supported_oses[i].name; i++) {
|
|
Packit Service |
a1973e |
if (!strcmp(supported_oses[i].name, ostr)) {
|
|
Packit Service |
a1973e |
options.os = supported_oses[i].os;
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
fprintf(stderr, "unknown OS layer %s, choose from:", ostr);
|
|
Packit Service |
a1973e |
for (i = 0; supported_oses[i].name; i++) {
|
|
Packit Service |
a1973e |
if (i)
|
|
Packit Service |
a1973e |
fputc(',', stderr);
|
|
Packit Service |
a1973e |
fprintf(stderr, " %s", supported_oses[i].name);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
fputc('\n', stderr);
|
|
Packit Service |
a1973e |
exit(1);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
main(int argc, char **argv)
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
static char *argv_all[2] = { ".*", NULL };
|
|
Packit Service |
a1973e |
pfm_pmu_info_t pinfo;
|
|
Packit Service |
a1973e |
char *endptr = NULL;
|
|
Packit Service |
a1973e |
char default_sep[2] = "\t";
|
|
Packit Service |
a1973e |
char *ostr = NULL;
|
|
Packit Service |
a1973e |
char **args;
|
|
Packit Service |
a1973e |
int i, match;
|
|
Packit Service |
a1973e |
regex_t preg;
|
|
Packit Service |
a1973e |
int ret, c;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memset(&pinfo, 0, sizeof(pinfo));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pinfo.size = sizeof(pinfo);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
while ((c=getopt(argc, argv,"hELsm:MNl:F:x:DO:")) != -1) {
|
|
Packit Service |
a1973e |
switch(c) {
|
|
Packit Service |
a1973e |
case 'L':
|
|
Packit Service |
a1973e |
options.compact = 1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 'F':
|
|
Packit Service |
a1973e |
parse_filters(optarg);
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 'E':
|
|
Packit Service |
a1973e |
options.compact = 1;
|
|
Packit Service |
a1973e |
options.encode = 1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 'M':
|
|
Packit Service |
a1973e |
options.combo = 1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 'N':
|
|
Packit Service |
a1973e |
options.name_only = 1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 's':
|
|
Packit Service |
a1973e |
options.sort = 1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 'D':
|
|
Packit Service |
a1973e |
options.desc = 1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 'l':
|
|
Packit Service |
a1973e |
options.combo_lim = atoi(optarg);
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 'x':
|
|
Packit Service |
a1973e |
options.csv_sep = optarg;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 'O':
|
|
Packit Service |
a1973e |
ostr = optarg;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 'm':
|
|
Packit Service |
a1973e |
options.mask = strtoull(optarg, &endptr, 16);
|
|
Packit Service |
a1973e |
if (*endptr)
|
|
Packit Service |
a1973e |
errx(1, "mask must be in hexadecimal\n");
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
case 'h':
|
|
Packit Service |
a1973e |
usage();
|
|
Packit Service |
a1973e |
exit(0);
|
|
Packit Service |
a1973e |
default:
|
|
Packit Service |
a1973e |
errx(1, "unknown option error");
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
/* to allow encoding of events from non detected PMU models */
|
|
Packit Service |
a1973e |
ret = set_env_var("LIBPFM_ENCODE_INACTIVE", "1", 1);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
errx(1, "cannot force inactive encoding");
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ret = pfm_initialize();
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
errx(1, "cannot initialize libpfm: %s", pfm_strerror(ret));
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (options.mask == 0)
|
|
Packit Service |
a1973e |
options.mask = ~0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (optind == argc) {
|
|
Packit Service |
a1973e |
args = argv_all;
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
args = argv + optind;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
if (!options.csv_sep)
|
|
Packit Service |
a1973e |
options.csv_sep = default_sep;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* avoid combinatorial explosion */
|
|
Packit Service |
a1973e |
if (options.combo_lim == 0)
|
|
Packit Service |
a1973e |
options.combo_lim = COMBO_MAX;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (ostr)
|
|
Packit Service |
a1973e |
setup_os(ostr);
|
|
Packit Service |
a1973e |
else
|
|
Packit Service |
a1973e |
options.os = PFM_OS_NONE;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (!options.compact) {
|
|
Packit Service |
a1973e |
int total_supported_events = 0;
|
|
Packit Service |
a1973e |
int total_available_events = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
printf("Supported PMU models:\n");
|
|
Packit Service |
a1973e |
pfm_for_all_pmus(i) {
|
|
Packit Service |
a1973e |
ret = pfm_get_pmu_info(i, &pinfo);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
printf("\t[%d, %s, \"%s\"]\n", i, pinfo.name, pinfo.desc);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
printf("Detected PMU models:\n");
|
|
Packit Service |
a1973e |
pfm_for_all_pmus(i) {
|
|
Packit Service |
a1973e |
ret = pfm_get_pmu_info(i, &pinfo);
|
|
Packit Service |
a1973e |
if (ret != PFM_SUCCESS)
|
|
Packit Service |
a1973e |
continue;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (pinfo.is_present) {
|
|
Packit Service |
a1973e |
if (pinfo.type >= PFM_PMU_TYPE_MAX)
|
|
Packit Service |
a1973e |
pinfo.type = PFM_PMU_TYPE_UNKNOWN;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
printf("\t[%d, %s, \"%s\", %d events, %d max encoding, %d counters, %s PMU]\n",
|
|
Packit Service |
a1973e |
i,
|
|
Packit Service |
a1973e |
pinfo.name,
|
|
Packit Service |
a1973e |
pinfo.desc,
|
|
Packit Service |
a1973e |
pinfo.nevents,
|
|
Packit Service |
a1973e |
pinfo.max_encoding,
|
|
Packit Service |
a1973e |
pinfo.num_cntrs + pinfo.num_fixed_cntrs,
|
|
Packit Service |
a1973e |
pmu_types[pinfo.type]);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
total_supported_events += pinfo.nevents;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
total_available_events += pinfo.nevents;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
printf("Total events: %d available, %d supported\n", total_available_events, total_supported_events);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
while(*args) {
|
|
Packit Service |
a1973e |
/* drop umasks and modifiers */
|
|
Packit Service |
a1973e |
drop_event_attributes(*args);
|
|
Packit Service |
a1973e |
if (regcomp(&preg, *args, REG_ICASE))
|
|
Packit Service |
a1973e |
errx(1, "error in regular expression for event \"%s\"", *argv);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (options.sort)
|
|
Packit Service |
a1973e |
match = show_info_sorted(*args, &preg;;
|
|
Packit Service |
a1973e |
else
|
|
Packit Service |
a1973e |
match = show_info(*args, &preg;;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (match == 0)
|
|
Packit Service |
a1973e |
errx(1, "event %s not found", *args);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
args++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
regfree(&preg;;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
pfm_terminate();
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
}
|