perf tools: Introduce event selectors

Out of ad-hoc code and global arrays with hard coded sizes.

This is the first step on having a library that will be first
used on regression tests in the 'perf test' tool.

[acme@felicio linux]$ size /tmp/perf.before
   text	   data	    bss	    dec	    hex	filename
1273776	  97384	5104416	6475576	 62cf38	/tmp/perf.before
[acme@felicio linux]$ size /tmp/perf.new
   text	   data	    bss	    dec	    hex	filename
1275422	  97416	1392416	2765254	 2a31c6	/tmp/perf.new

Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo
2011-01-03 16:39:04 -02:00
parent 56f4c40034
commit 69aad6f1ee
14 changed files with 432 additions and 244 deletions

View File

@ -1,6 +1,7 @@
#include "../../../include/linux/hw_breakpoint.h"
#include "util.h"
#include "../perf.h"
#include "evsel.h"
#include "parse-options.h"
#include "parse-events.h"
#include "exec_cmd.h"
@ -12,8 +13,7 @@
int nr_counters;
struct perf_event_attr attrs[MAX_COUNTERS];
char *filters[MAX_COUNTERS];
LIST_HEAD(evsel_list);
struct event_symbol {
u8 type;
@ -266,10 +266,10 @@ static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result)
return name;
}
const char *event_name(int counter)
const char *event_name(struct perf_evsel *evsel)
{
u64 config = attrs[counter].config;
int type = attrs[counter].type;
u64 config = evsel->attr.config;
int type = evsel->attr.type;
return __event_name(type, config);
}
@ -814,9 +814,6 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u
return -1;
for (;;) {
if (nr_counters == MAX_COUNTERS)
return -1;
memset(&attr, 0, sizeof(attr));
ret = parse_event_symbols(&str, &attr);
if (ret == EVT_FAILED)
@ -826,8 +823,13 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u
return -1;
if (ret != EVT_HANDLED_ALL) {
attrs[nr_counters] = attr;
nr_counters++;
struct perf_evsel *evsel;
evsel = perf_evsel__new(attr.type, attr.config,
nr_counters);
if (evsel == NULL)
return -1;
list_add_tail(&evsel->node, &evsel_list);
++nr_counters;
}
if (*str == 0)
@ -844,21 +846,22 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u
int parse_filter(const struct option *opt __used, const char *str,
int unset __used)
{
int i = nr_counters - 1;
int len = strlen(str);
struct perf_evsel *last = NULL;
if (i < 0 || attrs[i].type != PERF_TYPE_TRACEPOINT) {
if (!list_empty(&evsel_list))
last = list_entry(evsel_list.prev, struct perf_evsel, node);
if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) {
fprintf(stderr,
"-F option should follow a -e tracepoint option\n");
return -1;
}
filters[i] = malloc(len + 1);
if (!filters[i]) {
last->filter = strdup(str);
if (last->filter == NULL) {
fprintf(stderr, "not enough memory to hold filter string\n");
return -1;
}
strcpy(filters[i], str);
return 0;
}
@ -967,3 +970,15 @@ void print_events(void)
exit(129);
}
int perf_evsel_list__create_default(void)
{
struct perf_evsel *evsel = perf_evsel__new(PERF_TYPE_HARDWARE,
PERF_COUNT_HW_CPU_CYCLES, 0);
if (evsel == NULL)
return -ENOMEM;
list_add(&evsel->node, &evsel_list);
++nr_counters;
return 0;
}