perf tools: Keep group information
authorNamhyung Kim <namhyung.kim@lge.com>
Tue, 22 Jan 2013 09:09:29 +0000 (18:09 +0900)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 31 Jan 2013 16:07:43 +0000 (13:07 -0300)
Add a few of group-related field in struct perf_{evlist,evsel} so that
the group information in a evlist can be known easily.  It only counts
groups which have more than 1 members since leader-only groups are
treated as non-group events.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.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/1358845787-1350-2-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/evlist.c
tools/perf/util/evlist.h
tools/perf/util/evsel.h
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h
tools/perf/util/parse-events.y

index dc8aee97a488f96c9274ce9bd0645db5e9c1ea02..eddd5ebcd69018811a62ec67a7911a9701533bb8 100644 (file)
@@ -117,6 +117,9 @@ void __perf_evlist__set_leader(struct list_head *list)
        struct perf_evsel *evsel, *leader;
 
        leader = list_entry(list->next, struct perf_evsel, node);
+       evsel = list_entry(list->prev, struct perf_evsel, node);
+
+       leader->nr_members = evsel->idx - leader->idx + 1;
 
        list_for_each_entry(evsel, list, node) {
                if (evsel != leader)
@@ -126,8 +129,10 @@ void __perf_evlist__set_leader(struct list_head *list)
 
 void perf_evlist__set_leader(struct perf_evlist *evlist)
 {
-       if (evlist->nr_entries)
+       if (evlist->nr_entries) {
+               evlist->nr_groups = evlist->nr_entries > 1 ? 1 : 0;
                __perf_evlist__set_leader(&evlist->entries);
+       }
 }
 
 int perf_evlist__add_default(struct perf_evlist *evlist)
index 457e2350d21d563251d67bc4e3423da2d8ba2a4c..73579a25a93ea12d9879f11b2704a63f2c0c45b6 100644 (file)
@@ -21,6 +21,7 @@ struct perf_evlist {
        struct list_head entries;
        struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
        int              nr_entries;
+       int              nr_groups;
        int              nr_fds;
        int              nr_mmaps;
        int              mmap_len;
index cbf42322a27ef10a04387669b60b000a4346d06b..c9031ebf196e82a7744bbf96ef418cd81db157cc 100644 (file)
@@ -74,6 +74,7 @@ struct perf_evsel {
        bool                    needs_swap;
        /* parse modifier helper */
        int                     exclude_GH;
+       int                     nr_members;
        struct perf_evsel       *leader;
        char                    *group_name;
 };
@@ -259,4 +260,9 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
 int perf_evsel__open_strerror(struct perf_evsel *evsel,
                              struct perf_target *target,
                              int err, char *msg, size_t size);
+
+static inline int perf_evsel__group_idx(struct perf_evsel *evsel)
+{
+       return evsel->idx - evsel->leader->idx;
+}
 #endif /* __PERF_EVSEL_H */
index 02f6421f03a05666e849c40b6d5b487505e5adb8..4e0f5c2a9fda4aa99be1ec666d4a10d92e8dd860 100644 (file)
@@ -884,6 +884,7 @@ int parse_events(struct perf_evlist *evlist, const char *str)
        if (!ret) {
                int entries = data.idx - evlist->nr_entries;
                perf_evlist__splice_list_tail(evlist, &data.list, entries);
+               evlist->nr_groups += data.nr_groups;
                return 0;
        }
 
index 2cd2c42a69c54dd2f85d94f08fe2d02ee1794088..8a4859315fd97266fa592ea775d993b9c003a48d 100644 (file)
@@ -64,6 +64,7 @@ struct parse_events_term {
 struct parse_events_evlist {
        struct list_head list;
        int idx;
+       int nr_groups;
 };
 
 struct parse_events_terms {
index 9d43c86176ffc6c9981a3a1a88d5cbba67741ba2..4de2fdca98c8481d6c254151acd5cf5aa2de0600 100644 (file)
@@ -23,6 +23,14 @@ do { \
                YYABORT; \
 } while (0)
 
+static inc_group_count(struct list_head *list,
+                      struct parse_events_evlist *data)
+{
+       /* Count groups only have more than 1 members */
+       if (!list_is_last(list->next, list))
+               data->nr_groups++;
+}
+
 %}
 
 %token PE_START_EVENTS PE_START_TERMS
@@ -123,6 +131,7 @@ PE_NAME '{' events '}'
 {
        struct list_head *list = $3;
 
+       inc_group_count(list, _data);
        parse_events__set_leader($1, list);
        $$ = list;
 }
@@ -131,6 +140,7 @@ PE_NAME '{' events '}'
 {
        struct list_head *list = $2;
 
+       inc_group_count(list, _data);
        parse_events__set_leader(NULL, list);
        $$ = list;
 }