diff options
-rw-r--r-- | tools/perf/util/sort.c | 211 | ||||
-rw-r--r-- | tools/perf/util/sort.h | 8 |
2 files changed, 99 insertions, 120 deletions
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index f44fa541d56e..f5dba560d918 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -15,95 +15,6 @@ char * field_sep; | |||
15 | 15 | ||
16 | LIST_HEAD(hist_entry__sort_list); | 16 | LIST_HEAD(hist_entry__sort_list); |
17 | 17 | ||
18 | static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf, | ||
19 | size_t size, unsigned int width); | ||
20 | static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf, | ||
21 | size_t size, unsigned int width); | ||
22 | static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf, | ||
23 | size_t size, unsigned int width); | ||
24 | static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf, | ||
25 | size_t size, unsigned int width); | ||
26 | static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf, | ||
27 | size_t size, unsigned int width); | ||
28 | static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf, | ||
29 | size_t size, unsigned int width); | ||
30 | |||
31 | struct sort_entry sort_thread = { | ||
32 | .se_header = "Command: Pid", | ||
33 | .se_cmp = sort__thread_cmp, | ||
34 | .se_snprintf = hist_entry__thread_snprintf, | ||
35 | .se_width_idx = HISTC_THREAD, | ||
36 | }; | ||
37 | |||
38 | struct sort_entry sort_comm = { | ||
39 | .se_header = "Command", | ||
40 | .se_cmp = sort__comm_cmp, | ||
41 | .se_collapse = sort__comm_collapse, | ||
42 | .se_snprintf = hist_entry__comm_snprintf, | ||
43 | .se_width_idx = HISTC_COMM, | ||
44 | }; | ||
45 | |||
46 | struct sort_entry sort_dso = { | ||
47 | .se_header = "Shared Object", | ||
48 | .se_cmp = sort__dso_cmp, | ||
49 | .se_snprintf = hist_entry__dso_snprintf, | ||
50 | .se_width_idx = HISTC_DSO, | ||
51 | }; | ||
52 | |||
53 | struct sort_entry sort_sym = { | ||
54 | .se_header = "Symbol", | ||
55 | .se_cmp = sort__sym_cmp, | ||
56 | .se_snprintf = hist_entry__sym_snprintf, | ||
57 | .se_width_idx = HISTC_SYMBOL, | ||
58 | }; | ||
59 | |||
60 | struct sort_entry sort_parent = { | ||
61 | .se_header = "Parent symbol", | ||
62 | .se_cmp = sort__parent_cmp, | ||
63 | .se_snprintf = hist_entry__parent_snprintf, | ||
64 | .se_width_idx = HISTC_PARENT, | ||
65 | }; | ||
66 | |||
67 | struct sort_entry sort_cpu = { | ||
68 | .se_header = "CPU", | ||
69 | .se_cmp = sort__cpu_cmp, | ||
70 | .se_snprintf = hist_entry__cpu_snprintf, | ||
71 | .se_width_idx = HISTC_CPU, | ||
72 | }; | ||
73 | |||
74 | struct sort_dimension { | ||
75 | const char *name; | ||
76 | struct sort_entry *entry; | ||
77 | int taken; | ||
78 | }; | ||
79 | |||
80 | static struct sort_dimension sort_dimensions[] = { | ||
81 | { .name = "pid", .entry = &sort_thread, }, | ||
82 | { .name = "comm", .entry = &sort_comm, }, | ||
83 | { .name = "dso", .entry = &sort_dso, }, | ||
84 | { .name = "symbol", .entry = &sort_sym, }, | ||
85 | { .name = "parent", .entry = &sort_parent, }, | ||
86 | { .name = "cpu", .entry = &sort_cpu, }, | ||
87 | }; | ||
88 | |||
89 | int64_t cmp_null(void *l, void *r) | ||
90 | { | ||
91 | if (!l && !r) | ||
92 | return 0; | ||
93 | else if (!l) | ||
94 | return -1; | ||
95 | else | ||
96 | return 1; | ||
97 | } | ||
98 | |||
99 | /* --sort pid */ | ||
100 | |||
101 | int64_t | ||
102 | sort__thread_cmp(struct hist_entry *left, struct hist_entry *right) | ||
103 | { | ||
104 | return right->thread->pid - left->thread->pid; | ||
105 | } | ||
106 | |||
107 | static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...) | 18 | static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...) |
108 | { | 19 | { |
109 | int n; | 20 | int n; |
@@ -125,6 +36,24 @@ static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...) | |||
125 | return n; | 36 | return n; |
126 | } | 37 | } |
127 | 38 | ||
39 | static int64_t cmp_null(void *l, void *r) | ||
40 | { | ||
41 | if (!l && !r) | ||
42 | return 0; | ||
43 | else if (!l) | ||
44 | return -1; | ||
45 | else | ||
46 | return 1; | ||
47 | } | ||
48 | |||
49 | /* --sort pid */ | ||
50 | |||
51 | static int64_t | ||
52 | sort__thread_cmp(struct hist_entry *left, struct hist_entry *right) | ||
53 | { | ||
54 | return right->thread->pid - left->thread->pid; | ||
55 | } | ||
56 | |||
128 | static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf, | 57 | static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf, |
129 | size_t size, unsigned int width) | 58 | size_t size, unsigned int width) |
130 | { | 59 | { |
@@ -132,15 +61,50 @@ static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf, | |||
132 | self->thread->comm ?: "", self->thread->pid); | 61 | self->thread->comm ?: "", self->thread->pid); |
133 | } | 62 | } |
134 | 63 | ||
64 | struct sort_entry sort_thread = { | ||
65 | .se_header = "Command: Pid", | ||
66 | .se_cmp = sort__thread_cmp, | ||
67 | .se_snprintf = hist_entry__thread_snprintf, | ||
68 | .se_width_idx = HISTC_THREAD, | ||
69 | }; | ||
70 | |||
71 | /* --sort comm */ | ||
72 | |||
73 | static int64_t | ||
74 | sort__comm_cmp(struct hist_entry *left, struct hist_entry *right) | ||
75 | { | ||
76 | return right->thread->pid - left->thread->pid; | ||
77 | } | ||
78 | |||
79 | static int64_t | ||
80 | sort__comm_collapse(struct hist_entry *left, struct hist_entry *right) | ||
81 | { | ||
82 | char *comm_l = left->thread->comm; | ||
83 | char *comm_r = right->thread->comm; | ||
84 | |||
85 | if (!comm_l || !comm_r) | ||
86 | return cmp_null(comm_l, comm_r); | ||
87 | |||
88 | return strcmp(comm_l, comm_r); | ||
89 | } | ||
90 | |||
135 | static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf, | 91 | static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf, |
136 | size_t size, unsigned int width) | 92 | size_t size, unsigned int width) |
137 | { | 93 | { |
138 | return repsep_snprintf(bf, size, "%*s", width, self->thread->comm); | 94 | return repsep_snprintf(bf, size, "%*s", width, self->thread->comm); |
139 | } | 95 | } |
140 | 96 | ||
97 | struct sort_entry sort_comm = { | ||
98 | .se_header = "Command", | ||
99 | .se_cmp = sort__comm_cmp, | ||
100 | .se_collapse = sort__comm_collapse, | ||
101 | .se_snprintf = hist_entry__comm_snprintf, | ||
102 | .se_width_idx = HISTC_COMM, | ||
103 | }; | ||
104 | |||
141 | /* --sort dso */ | 105 | /* --sort dso */ |
142 | 106 | ||
143 | int64_t | 107 | static int64_t |
144 | sort__dso_cmp(struct hist_entry *left, struct hist_entry *right) | 108 | sort__dso_cmp(struct hist_entry *left, struct hist_entry *right) |
145 | { | 109 | { |
146 | struct dso *dso_l = left->ms.map ? left->ms.map->dso : NULL; | 110 | struct dso *dso_l = left->ms.map ? left->ms.map->dso : NULL; |
@@ -173,9 +137,16 @@ static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf, | |||
173 | return repsep_snprintf(bf, size, "%-*s", width, "[unknown]"); | 137 | return repsep_snprintf(bf, size, "%-*s", width, "[unknown]"); |
174 | } | 138 | } |
175 | 139 | ||
140 | struct sort_entry sort_dso = { | ||
141 | .se_header = "Shared Object", | ||
142 | .se_cmp = sort__dso_cmp, | ||
143 | .se_snprintf = hist_entry__dso_snprintf, | ||
144 | .se_width_idx = HISTC_DSO, | ||
145 | }; | ||
146 | |||
176 | /* --sort symbol */ | 147 | /* --sort symbol */ |
177 | 148 | ||
178 | int64_t | 149 | static int64_t |
179 | sort__sym_cmp(struct hist_entry *left, struct hist_entry *right) | 150 | sort__sym_cmp(struct hist_entry *left, struct hist_entry *right) |
180 | { | 151 | { |
181 | u64 ip_l, ip_r; | 152 | u64 ip_l, ip_r; |
@@ -211,29 +182,16 @@ static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf, | |||
211 | return ret; | 182 | return ret; |
212 | } | 183 | } |
213 | 184 | ||
214 | /* --sort comm */ | 185 | struct sort_entry sort_sym = { |
215 | 186 | .se_header = "Symbol", | |
216 | int64_t | 187 | .se_cmp = sort__sym_cmp, |
217 | sort__comm_cmp(struct hist_entry *left, struct hist_entry *right) | 188 | .se_snprintf = hist_entry__sym_snprintf, |
218 | { | 189 | .se_width_idx = HISTC_SYMBOL, |
219 | return right->thread->pid - left->thread->pid; | 190 | }; |
220 | } | ||
221 | |||
222 | int64_t | ||
223 | sort__comm_collapse(struct hist_entry *left, struct hist_entry *right) | ||
224 | { | ||
225 | char *comm_l = left->thread->comm; | ||
226 | char *comm_r = right->thread->comm; | ||
227 | |||
228 | if (!comm_l || !comm_r) | ||
229 | return cmp_null(comm_l, comm_r); | ||
230 | |||
231 | return strcmp(comm_l, comm_r); | ||
232 | } | ||
233 | 191 | ||
234 | /* --sort parent */ | 192 | /* --sort parent */ |
235 | 193 | ||
236 | int64_t | 194 | static int64_t |
237 | sort__parent_cmp(struct hist_entry *left, struct hist_entry *right) | 195 | sort__parent_cmp(struct hist_entry *left, struct hist_entry *right) |
238 | { | 196 | { |
239 | struct symbol *sym_l = left->parent; | 197 | struct symbol *sym_l = left->parent; |
@@ -252,9 +210,16 @@ static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf, | |||
252 | self->parent ? self->parent->name : "[other]"); | 210 | self->parent ? self->parent->name : "[other]"); |
253 | } | 211 | } |
254 | 212 | ||
213 | struct sort_entry sort_parent = { | ||
214 | .se_header = "Parent symbol", | ||
215 | .se_cmp = sort__parent_cmp, | ||
216 | .se_snprintf = hist_entry__parent_snprintf, | ||
217 | .se_width_idx = HISTC_PARENT, | ||
218 | }; | ||
219 | |||
255 | /* --sort cpu */ | 220 | /* --sort cpu */ |
256 | 221 | ||
257 | int64_t | 222 | static int64_t |
258 | sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right) | 223 | sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right) |
259 | { | 224 | { |
260 | return right->cpu - left->cpu; | 225 | return right->cpu - left->cpu; |
@@ -266,6 +231,28 @@ static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf, | |||
266 | return repsep_snprintf(bf, size, "%-*d", width, self->cpu); | 231 | return repsep_snprintf(bf, size, "%-*d", width, self->cpu); |
267 | } | 232 | } |
268 | 233 | ||
234 | struct sort_entry sort_cpu = { | ||
235 | .se_header = "CPU", | ||
236 | .se_cmp = sort__cpu_cmp, | ||
237 | .se_snprintf = hist_entry__cpu_snprintf, | ||
238 | .se_width_idx = HISTC_CPU, | ||
239 | }; | ||
240 | |||
241 | struct sort_dimension { | ||
242 | const char *name; | ||
243 | struct sort_entry *entry; | ||
244 | int taken; | ||
245 | }; | ||
246 | |||
247 | static struct sort_dimension sort_dimensions[] = { | ||
248 | { .name = "pid", .entry = &sort_thread, }, | ||
249 | { .name = "comm", .entry = &sort_comm, }, | ||
250 | { .name = "dso", .entry = &sort_dso, }, | ||
251 | { .name = "symbol", .entry = &sort_sym, }, | ||
252 | { .name = "parent", .entry = &sort_parent, }, | ||
253 | { .name = "cpu", .entry = &sort_cpu, }, | ||
254 | }; | ||
255 | |||
269 | int sort_dimension__add(const char *tok) | 256 | int sort_dimension__add(const char *tok) |
270 | { | 257 | { |
271 | unsigned int i; | 258 | unsigned int i; |
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 0b91053a7d11..4a6d30908249 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
@@ -108,14 +108,6 @@ extern size_t sort__thread_print(FILE *, struct hist_entry *, unsigned int); | |||
108 | extern size_t sort__comm_print(FILE *, struct hist_entry *, unsigned int); | 108 | extern size_t sort__comm_print(FILE *, struct hist_entry *, unsigned int); |
109 | extern size_t sort__dso_print(FILE *, struct hist_entry *, unsigned int); | 109 | extern size_t sort__dso_print(FILE *, struct hist_entry *, unsigned int); |
110 | extern size_t sort__sym_print(FILE *, struct hist_entry *, unsigned int __used); | 110 | extern size_t sort__sym_print(FILE *, struct hist_entry *, unsigned int __used); |
111 | extern int64_t cmp_null(void *, void *); | ||
112 | extern int64_t sort__thread_cmp(struct hist_entry *, struct hist_entry *); | ||
113 | extern int64_t sort__comm_cmp(struct hist_entry *, struct hist_entry *); | ||
114 | extern int64_t sort__comm_collapse(struct hist_entry *, struct hist_entry *); | ||
115 | extern int64_t sort__dso_cmp(struct hist_entry *, struct hist_entry *); | ||
116 | extern int64_t sort__sym_cmp(struct hist_entry *, struct hist_entry *); | ||
117 | extern int64_t sort__parent_cmp(struct hist_entry *, struct hist_entry *); | ||
118 | int64_t sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right); | ||
119 | extern size_t sort__parent_print(FILE *, struct hist_entry *, unsigned int); | 111 | extern size_t sort__parent_print(FILE *, struct hist_entry *, unsigned int); |
120 | extern int sort_dimension__add(const char *); | 112 | extern int sort_dimension__add(const char *); |
121 | void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, | 113 | void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, |