aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-annotate.c
diff options
context:
space:
mode:
authorJohn Kacur <jkacur@redhat.com>2009-09-24 12:02:49 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-24 15:27:52 -0400
commitdd68ada2d417e57b848822a1407b5317a54136c5 (patch)
tree8d7cc54e3bcf063038532d88ac1f94a54b6650a5 /tools/perf/builtin-annotate.c
parent8b40f521cf1c9750eab0c04da9075e7484675e9c (diff)
perf tools: Create util/sort.and use it
Create util/sort.[ch] and move common functionality for builtin-report.c and builtin-annotate.c there, and make use of it. Signed-off-by: John Kacur <jkacur@redhat.com> LKML-Reference: <alpine.LFD.2.00.0909241758390.11383@localhost.localdomain> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-annotate.c')
-rw-r--r--tools/perf/builtin-annotate.c211
1 files changed, 7 insertions, 204 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index a33087328bd4..059c565b31ea 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -22,12 +22,10 @@
22#include "util/parse-options.h" 22#include "util/parse-options.h"
23#include "util/parse-events.h" 23#include "util/parse-events.h"
24#include "util/thread.h" 24#include "util/thread.h"
25#include "util/sort.h"
25 26
26static char const *input_name = "perf.data"; 27static char const *input_name = "perf.data";
27 28
28static char default_sort_order[] = "comm,symbol";
29static char *sort_order = default_sort_order;
30
31static int force; 29static int force;
32static int input; 30static int input;
33static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV; 31static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
@@ -55,207 +53,6 @@ struct sym_ext {
55 53
56static struct rb_root hist; 54static struct rb_root hist;
57 55
58struct hist_entry {
59 struct rb_node rb_node;
60
61 struct thread *thread;
62 struct map *map;
63 struct dso *dso;
64 struct symbol *sym;
65 u64 ip;
66 char level;
67
68 uint32_t count;
69};
70
71/*
72 * configurable sorting bits
73 */
74
75struct sort_entry {
76 struct list_head list;
77
78 const char *header;
79
80 int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
81 int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
82 size_t (*print)(FILE *fp, struct hist_entry *);
83};
84
85static int64_t cmp_null(void *l, void *r)
86{
87 if (!l && !r)
88 return 0;
89 else if (!l)
90 return -1;
91 else
92 return 1;
93}
94
95/* --sort pid */
96
97static int64_t
98sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
99{
100 return right->thread->pid - left->thread->pid;
101}
102
103static size_t
104sort__thread_print(FILE *fp, struct hist_entry *self)
105{
106 return fprintf(fp, "%16s:%5d", self->thread->comm ?: "", self->thread->pid);
107}
108
109static struct sort_entry sort_thread = {
110 .header = " Command: Pid",
111 .cmp = sort__thread_cmp,
112 .print = sort__thread_print,
113};
114
115/* --sort comm */
116
117static int64_t
118sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
119{
120 return right->thread->pid - left->thread->pid;
121}
122
123static int64_t
124sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
125{
126 char *comm_l = left->thread->comm;
127 char *comm_r = right->thread->comm;
128
129 if (!comm_l || !comm_r)
130 return cmp_null(comm_l, comm_r);
131
132 return strcmp(comm_l, comm_r);
133}
134
135static size_t
136sort__comm_print(FILE *fp, struct hist_entry *self)
137{
138 return fprintf(fp, "%16s", self->thread->comm);
139}
140
141static struct sort_entry sort_comm = {
142 .header = " Command",
143 .cmp = sort__comm_cmp,
144 .collapse = sort__comm_collapse,
145 .print = sort__comm_print,
146};
147
148/* --sort dso */
149
150static int64_t
151sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
152{
153 struct dso *dso_l = left->dso;
154 struct dso *dso_r = right->dso;
155
156 if (!dso_l || !dso_r)
157 return cmp_null(dso_l, dso_r);
158
159 return strcmp(dso_l->name, dso_r->name);
160}
161
162static size_t
163sort__dso_print(FILE *fp, struct hist_entry *self)
164{
165 if (self->dso)
166 return fprintf(fp, "%-25s", self->dso->name);
167
168 return fprintf(fp, "%016llx ", (u64)self->ip);
169}
170
171static struct sort_entry sort_dso = {
172 .header = "Shared Object ",
173 .cmp = sort__dso_cmp,
174 .print = sort__dso_print,
175};
176
177/* --sort symbol */
178
179static int64_t
180sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
181{
182 u64 ip_l, ip_r;
183
184 if (left->sym == right->sym)
185 return 0;
186
187 ip_l = left->sym ? left->sym->start : left->ip;
188 ip_r = right->sym ? right->sym->start : right->ip;
189
190 return (int64_t)(ip_r - ip_l);
191}
192
193static size_t
194sort__sym_print(FILE *fp, struct hist_entry *self)
195{
196 size_t ret = 0;
197
198 if (verbose)
199 ret += fprintf(fp, "%#018llx ", (u64)self->ip);
200
201 if (self->sym) {
202 ret += fprintf(fp, "[%c] %s",
203 self->dso == kernel_dso ? 'k' : '.', self->sym->name);
204 } else {
205 ret += fprintf(fp, "%#016llx", (u64)self->ip);
206 }
207
208 return ret;
209}
210
211static struct sort_entry sort_sym = {
212 .header = "Symbol",
213 .cmp = sort__sym_cmp,
214 .print = sort__sym_print,
215};
216
217static int sort__need_collapse = 0;
218
219struct sort_dimension {
220 const char *name;
221 struct sort_entry *entry;
222 int taken;
223};
224
225static struct sort_dimension sort_dimensions[] = {
226 { .name = "pid", .entry = &sort_thread, },
227 { .name = "comm", .entry = &sort_comm, },
228 { .name = "dso", .entry = &sort_dso, },
229 { .name = "symbol", .entry = &sort_sym, },
230};
231
232static LIST_HEAD(hist_entry__sort_list);
233
234static int sort_dimension__add(char *tok)
235{
236 unsigned int i;
237
238 for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
239 struct sort_dimension *sd = &sort_dimensions[i];
240
241 if (sd->taken)
242 continue;
243
244 if (strncasecmp(tok, sd->name, strlen(tok)))
245 continue;
246
247 if (sd->entry->collapse)
248 sort__need_collapse = 1;
249
250 list_add_tail(&sd->entry->list, &hist_entry__sort_list);
251 sd->taken = 1;
252
253 return 0;
254 }
255
256 return -ESRCH;
257}
258
259static int64_t 56static int64_t
260hist_entry__cmp(struct hist_entry *left, struct hist_entry *right) 57hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
261{ 58{
@@ -1137,5 +934,11 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
1137 934
1138 setup_pager(); 935 setup_pager();
1139 936
937 if (field_sep && *field_sep == '.') {
938 fputs("'.' is the only non valid --field-separator argument\n",
939 stderr);
940 exit(129);
941 }
942
1140 return __cmd_annotate(); 943 return __cmd_annotate();
1141} 944}