aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/comm.c
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2013-09-11 10:56:44 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-11-04 10:13:53 -0500
commit1902efe7f626fdebe1520f5ff11f1309ec506708 (patch)
treedbdc3c6f80aece6dfb35e2eaee6eb96a0ead5e4b /tools/perf/util/comm.c
parent162f0befda3becc2cc9f44075fccc030e55baec1 (diff)
perf tools: Add new COMM infrastructure
This new COMM infrastructure provides two features: 1) It keeps track of all comms lifecycle for a given thread. This way we can associate a timeframe to any thread COMM, as long as PERF_SAMPLE_TIME samples are joined to COMM and fork events. As a result we should have more precise COMM sorted hists with seperated entries for pre and post exec time after a fork. 2) It also makes sure that a given COMM string is not duplicated but rather shared among the threads that refer to it. This way the threads COMM can be compared against pointer values from the sort infrastructure. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Tested-by: Jiri Olsa <jolsa@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-hwjf70b2wve9m2kosxiq8bb3@git.kernel.org [ Rename some accessor functions ] Signed-off-by: Namhyung Kim <namhyung@kernel.org> [ Use __ as separator for class__method for private comm_str methods ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/comm.c')
-rw-r--r--tools/perf/util/comm.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
new file mode 100644
index 000000000000..8b3ac9f0207f
--- /dev/null
+++ b/tools/perf/util/comm.c
@@ -0,0 +1,106 @@
1#include "comm.h"
2#include "util.h"
3#include <stdlib.h>
4#include <stdio.h>
5
6struct comm_str {
7 char *str;
8 struct rb_node rb_node;
9 int ref;
10};
11
12/* Should perhaps be moved to struct machine */
13static struct rb_root comm_str_root;
14
15static void comm_str__get(struct comm_str *cs)
16{
17 cs->ref++;
18}
19
20static void comm_str__put(struct comm_str *cs)
21{
22 if (!--cs->ref) {
23 rb_erase(&cs->rb_node, &comm_str_root);
24 free(cs->str);
25 free(cs);
26 }
27}
28
29static struct comm_str *comm_str__alloc(const char *str)
30{
31 struct comm_str *cs;
32
33 cs = zalloc(sizeof(*cs));
34 if (!cs)
35 return NULL;
36
37 cs->str = strdup(str);
38 if (!cs->str) {
39 free(cs);
40 return NULL;
41 }
42
43 return cs;
44}
45
46static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
47{
48 struct rb_node **p = &root->rb_node;
49 struct rb_node *parent = NULL;
50 struct comm_str *iter, *new;
51 int cmp;
52
53 while (*p != NULL) {
54 parent = *p;
55 iter = rb_entry(parent, struct comm_str, rb_node);
56
57 cmp = strcmp(str, iter->str);
58 if (!cmp)
59 return iter;
60
61 if (cmp < 0)
62 p = &(*p)->rb_left;
63 else
64 p = &(*p)->rb_right;
65 }
66
67 new = comm_str__alloc(str);
68 if (!new)
69 return NULL;
70
71 rb_link_node(&new->rb_node, parent, p);
72 rb_insert_color(&new->rb_node, root);
73
74 return new;
75}
76
77struct comm *comm__new(const char *str, u64 timestamp)
78{
79 struct comm *comm = zalloc(sizeof(*comm));
80
81 if (!comm)
82 return NULL;
83
84 comm->start = timestamp;
85
86 comm->comm_str = comm_str__findnew(str, &comm_str_root);
87 if (!comm->comm_str) {
88 free(comm);
89 return NULL;
90 }
91
92 comm_str__get(comm->comm_str);
93
94 return comm;
95}
96
97void comm__free(struct comm *comm)
98{
99 comm_str__put(comm->comm_str);
100 free(comm);
101}
102
103const char *comm__str(const struct comm *comm)
104{
105 return comm->comm_str->str;
106}