aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-top.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-11-17 15:38:02 -0500
committerIngo Molnar <mingo@elte.hu>2009-11-19 00:03:41 -0500
commitb269876c8d57fb8c801bea1fc34b461646c5abd0 (patch)
treec9ac282b3a5f2d18a865180eb85c888f9e8cd338 /tools/perf/builtin-top.c
parent5a8e5a3065bf04b7673262fd6c46123e4b888d2b (diff)
perf top: Don't allocate the source parsing members upfront
Defer to parse_source() time allocating it. Now we use about this much memory: 1724 root 20 0 42104 10m 940 S 0.0 0.4 0:00.23 perf Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <1258490282-1821-3-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r--tools/perf/builtin-top.c76
1 files changed, 45 insertions, 31 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 49cf87680fe3..07b92c378ae2 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -108,6 +108,13 @@ static int display_weighted = -1;
108 * Symbols 108 * Symbols
109 */ 109 */
110 110
111struct sym_entry_source {
112 struct source_line *source;
113 struct source_line *lines;
114 struct source_line **lines_tail;
115 pthread_mutex_t lock;
116};
117
111struct sym_entry { 118struct sym_entry {
112 struct rb_node rb_node; 119 struct rb_node rb_node;
113 struct list_head node; 120 struct list_head node;
@@ -117,10 +124,7 @@ struct sym_entry {
117 u16 name_len; 124 u16 name_len;
118 u8 origin; 125 u8 origin;
119 struct map *map; 126 struct map *map;
120 struct source_line *source; 127 struct sym_entry_source *src;
121 struct source_line *lines;
122 struct source_line **lines_tail;
123 pthread_mutex_t source_lock;
124 unsigned long count[0]; 128 unsigned long count[0];
125}; 129};
126 130
@@ -172,6 +176,7 @@ static void sig_winch_handler(int sig __used)
172static void parse_source(struct sym_entry *syme) 176static void parse_source(struct sym_entry *syme)
173{ 177{
174 struct symbol *sym; 178 struct symbol *sym;
179 struct sym_entry_source *source;
175 struct map *map; 180 struct map *map;
176 FILE *file; 181 FILE *file;
177 char command[PATH_MAX*2]; 182 char command[PATH_MAX*2];
@@ -181,8 +186,17 @@ static void parse_source(struct sym_entry *syme)
181 if (!syme) 186 if (!syme)
182 return; 187 return;
183 188
184 if (syme->lines) { 189 if (syme->src == NULL) {
185 pthread_mutex_lock(&syme->source_lock); 190 syme->src = calloc(1, sizeof(*source));
191 if (syme->src == NULL)
192 return;
193 pthread_mutex_init(&syme->src->lock, NULL);
194 }
195
196 source = syme->src;
197
198 if (source->lines) {
199 pthread_mutex_lock(&source->lock);
186 goto out_assign; 200 goto out_assign;
187 } 201 }
188 202
@@ -202,8 +216,8 @@ static void parse_source(struct sym_entry *syme)
202 if (!file) 216 if (!file)
203 return; 217 return;
204 218
205 pthread_mutex_lock(&syme->source_lock); 219 pthread_mutex_lock(&source->lock);
206 syme->lines_tail = &syme->lines; 220 source->lines_tail = &source->lines;
207 while (!feof(file)) { 221 while (!feof(file)) {
208 struct source_line *src; 222 struct source_line *src;
209 size_t dummy = 0; 223 size_t dummy = 0;
@@ -223,8 +237,8 @@ static void parse_source(struct sym_entry *syme)
223 *c = 0; 237 *c = 0;
224 238
225 src->next = NULL; 239 src->next = NULL;
226 *syme->lines_tail = src; 240 *source->lines_tail = src;
227 syme->lines_tail = &src->next; 241 source->lines_tail = &src->next;
228 242
229 if (strlen(src->line)>8 && src->line[8] == ':') { 243 if (strlen(src->line)>8 && src->line[8] == ':') {
230 src->eip = strtoull(src->line, NULL, 16); 244 src->eip = strtoull(src->line, NULL, 16);
@@ -238,7 +252,7 @@ static void parse_source(struct sym_entry *syme)
238 pclose(file); 252 pclose(file);
239out_assign: 253out_assign:
240 sym_filter_entry = syme; 254 sym_filter_entry = syme;
241 pthread_mutex_unlock(&syme->source_lock); 255 pthread_mutex_unlock(&source->lock);
242} 256}
243 257
244static void __zero_source_counters(struct sym_entry *syme) 258static void __zero_source_counters(struct sym_entry *syme)
@@ -246,7 +260,7 @@ static void __zero_source_counters(struct sym_entry *syme)
246 int i; 260 int i;
247 struct source_line *line; 261 struct source_line *line;
248 262
249 line = syme->lines; 263 line = syme->src->lines;
250 while (line) { 264 while (line) {
251 for (i = 0; i < nr_counters; i++) 265 for (i = 0; i < nr_counters; i++)
252 line->count[i] = 0; 266 line->count[i] = 0;
@@ -261,13 +275,13 @@ static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip)
261 if (syme != sym_filter_entry) 275 if (syme != sym_filter_entry)
262 return; 276 return;
263 277
264 if (pthread_mutex_trylock(&syme->source_lock)) 278 if (pthread_mutex_trylock(&syme->src->lock))
265 return; 279 return;
266 280
267 if (!syme->source) 281 if (syme->src == NULL || syme->src->source == NULL)
268 goto out_unlock; 282 goto out_unlock;
269 283
270 for (line = syme->lines; line; line = line->next) { 284 for (line = syme->src->lines; line; line = line->next) {
271 if (line->eip == ip) { 285 if (line->eip == ip) {
272 line->count[counter]++; 286 line->count[counter]++;
273 break; 287 break;
@@ -276,7 +290,7 @@ static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip)
276 break; 290 break;
277 } 291 }
278out_unlock: 292out_unlock:
279 pthread_mutex_unlock(&syme->source_lock); 293 pthread_mutex_unlock(&syme->src->lock);
280} 294}
281 295
282static void lookup_sym_source(struct sym_entry *syme) 296static void lookup_sym_source(struct sym_entry *syme)
@@ -287,14 +301,14 @@ static void lookup_sym_source(struct sym_entry *syme)
287 301
288 sprintf(pattern, "<%s>:", symbol->name); 302 sprintf(pattern, "<%s>:", symbol->name);
289 303
290 pthread_mutex_lock(&syme->source_lock); 304 pthread_mutex_lock(&syme->src->lock);
291 for (line = syme->lines; line; line = line->next) { 305 for (line = syme->src->lines; line; line = line->next) {
292 if (strstr(line->line, pattern)) { 306 if (strstr(line->line, pattern)) {
293 syme->source = line; 307 syme->src->source = line;
294 break; 308 break;
295 } 309 }
296 } 310 }
297 pthread_mutex_unlock(&syme->source_lock); 311 pthread_mutex_unlock(&syme->src->lock);
298} 312}
299 313
300static void show_lines(struct source_line *queue, int count, int total) 314static void show_lines(struct source_line *queue, int count, int total)
@@ -324,24 +338,24 @@ static void show_details(struct sym_entry *syme)
324 if (!syme) 338 if (!syme)
325 return; 339 return;
326 340
327 if (!syme->source) 341 if (!syme->src->source)
328 lookup_sym_source(syme); 342 lookup_sym_source(syme);
329 343
330 if (!syme->source) 344 if (!syme->src->source)
331 return; 345 return;
332 346
333 symbol = sym_entry__symbol(syme); 347 symbol = sym_entry__symbol(syme);
334 printf("Showing %s for %s\n", event_name(sym_counter), symbol->name); 348 printf("Showing %s for %s\n", event_name(sym_counter), symbol->name);
335 printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); 349 printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter);
336 350
337 pthread_mutex_lock(&syme->source_lock); 351 pthread_mutex_lock(&syme->src->lock);
338 line = syme->source; 352 line = syme->src->source;
339 while (line) { 353 while (line) {
340 total += line->count[sym_counter]; 354 total += line->count[sym_counter];
341 line = line->next; 355 line = line->next;
342 } 356 }
343 357
344 line = syme->source; 358 line = syme->src->source;
345 while (line) { 359 while (line) {
346 float pcnt = 0.0; 360 float pcnt = 0.0;
347 361
@@ -366,7 +380,7 @@ static void show_details(struct sym_entry *syme)
366 line->count[sym_counter] = zero ? 0 : line->count[sym_counter] * 7 / 8; 380 line->count[sym_counter] = zero ? 0 : line->count[sym_counter] * 7 / 8;
367 line = line->next; 381 line = line->next;
368 } 382 }
369 pthread_mutex_unlock(&syme->source_lock); 383 pthread_mutex_unlock(&syme->src->lock);
370 if (more) 384 if (more)
371 printf("%d lines not displayed, maybe increase display entries [e]\n", more); 385 printf("%d lines not displayed, maybe increase display entries [e]\n", more);
372} 386}
@@ -647,10 +661,10 @@ static void prompt_symbol(struct sym_entry **target, const char *msg)
647 661
648 /* zero counters of active symbol */ 662 /* zero counters of active symbol */
649 if (syme) { 663 if (syme) {
650 pthread_mutex_lock(&syme->source_lock); 664 pthread_mutex_lock(&syme->src->lock);
651 __zero_source_counters(syme); 665 __zero_source_counters(syme);
652 *target = NULL; 666 *target = NULL;
653 pthread_mutex_unlock(&syme->source_lock); 667 pthread_mutex_unlock(&syme->src->lock);
654 } 668 }
655 669
656 fprintf(stdout, "\n%s: ", msg); 670 fprintf(stdout, "\n%s: ", msg);
@@ -826,10 +840,10 @@ static void handle_keypress(int c)
826 else { 840 else {
827 struct sym_entry *syme = sym_filter_entry; 841 struct sym_entry *syme = sym_filter_entry;
828 842
829 pthread_mutex_lock(&syme->source_lock); 843 pthread_mutex_lock(&syme->src->lock);
830 sym_filter_entry = NULL; 844 sym_filter_entry = NULL;
831 __zero_source_counters(syme); 845 __zero_source_counters(syme);
832 pthread_mutex_unlock(&syme->source_lock); 846 pthread_mutex_unlock(&syme->src->lock);
833 } 847 }
834 break; 848 break;
835 case 'U': 849 case 'U':
@@ -915,7 +929,7 @@ static int symbol_filter(struct map *map, struct symbol *sym)
915 929
916 syme = symbol__priv(sym); 930 syme = symbol__priv(sym);
917 syme->map = map; 931 syme->map = map;
918 pthread_mutex_init(&syme->source_lock, NULL); 932 syme->src = NULL;
919 if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) 933 if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter))
920 sym_filter_entry = syme; 934 sym_filter_entry = syme;
921 935