perf evlist: Add can_select_event() method
authorAdrian Hunter <adrian.hunter@intel.com>
Wed, 11 Dec 2013 12:36:29 +0000 (14:36 +0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 13 Dec 2013 13:30:20 +0000 (10:30 -0300)
Add a function to determine whether an event can be selected.

This function is needed to allow a tool to automatically select
additional events, but only if they are available.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1386765443-26966-18-git-send-email-alexander.shishkin@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/evlist.h
tools/perf/util/record.c

index 649d6ea98a84a0dfb91b5dbfb55a96292ca9703a..8a04aae95a18f77639af65e85952a3e03329281c 100644 (file)
@@ -193,4 +193,6 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md,
        pc->data_tail = tail;
 }
 
+bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str);
+
 #endif /* __PERF_EVLIST_H */
index c8845b107f6085cfacb907fce862c2e76dc6db5b..e5104538c3543883765f1bf57a32489788b90431 100644 (file)
@@ -177,3 +177,40 @@ int perf_record_opts__config(struct perf_record_opts *opts)
 {
        return perf_record_opts__config_freq(opts);
 }
+
+bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
+{
+       struct perf_evlist *temp_evlist;
+       struct perf_evsel *evsel;
+       int err, fd, cpu;
+       bool ret = false;
+
+       temp_evlist = perf_evlist__new();
+       if (!temp_evlist)
+               return false;
+
+       err = parse_events(temp_evlist, str);
+       if (err)
+               goto out_delete;
+
+       evsel = perf_evlist__last(temp_evlist);
+
+       if (!evlist || cpu_map__empty(evlist->cpus)) {
+               struct cpu_map *cpus = cpu_map__new(NULL);
+
+               cpu =  cpus ? cpus->map[0] : 0;
+               cpu_map__delete(cpus);
+       } else {
+               cpu = evlist->cpus->map[0];
+       }
+
+       fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, 0);
+       if (fd >= 0) {
+               close(fd);
+               ret = true;
+       }
+
+out_delete:
+       perf_evlist__delete(temp_evlist);
+       return ret;
+}