diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-06-25 10:16:44 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-06-25 10:16:44 -0400 |
| commit | 9a15a07fe2175dc25cd928a354b3839f562ac8cc (patch) | |
| tree | 09b470f3cf153c1d4f621cafc475ca1d22f7f6d3 | |
| parent | ffabd99e051e73344efe4e53d58f11643f180512 (diff) | |
| parent | 830f4c803196eec181e209110885c4ac130f3805 (diff) | |
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
| -rw-r--r-- | tools/perf/Makefile | 2 | ||||
| -rw-r--r-- | tools/perf/builtin-record.c | 9 | ||||
| -rw-r--r-- | tools/perf/util/newt.c | 185 |
3 files changed, 109 insertions, 87 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 6aa2fe323db1..17a3692397c5 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
| @@ -577,7 +577,7 @@ ifdef NO_LIBPERL | |||
| 577 | else | 577 | else |
| 578 | PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null` | 578 | PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null` |
| 579 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` | 579 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` |
| 580 | PERL_EMBED_FLAGS=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) | 580 | FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) |
| 581 | 581 | ||
| 582 | ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED)),y) | 582 | ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED)),y) |
| 583 | BASIC_CFLAGS += -DNO_LIBPERL | 583 | BASIC_CFLAGS += -DNO_LIBPERL |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 86b1c3b6264e..0df64088135f 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -445,8 +445,6 @@ static void atexit_header(void) | |||
| 445 | static void event__synthesize_guest_os(struct machine *machine, void *data) | 445 | static void event__synthesize_guest_os(struct machine *machine, void *data) |
| 446 | { | 446 | { |
| 447 | int err; | 447 | int err; |
| 448 | char *guest_kallsyms; | ||
| 449 | char path[PATH_MAX]; | ||
| 450 | struct perf_session *psession = data; | 448 | struct perf_session *psession = data; |
| 451 | 449 | ||
| 452 | if (machine__is_host(machine)) | 450 | if (machine__is_host(machine)) |
| @@ -466,13 +464,6 @@ static void event__synthesize_guest_os(struct machine *machine, void *data) | |||
| 466 | pr_err("Couldn't record guest kernel [%d]'s reference" | 464 | pr_err("Couldn't record guest kernel [%d]'s reference" |
| 467 | " relocation symbol.\n", machine->pid); | 465 | " relocation symbol.\n", machine->pid); |
| 468 | 466 | ||
| 469 | if (machine__is_default_guest(machine)) | ||
| 470 | guest_kallsyms = (char *) symbol_conf.default_guest_kallsyms; | ||
| 471 | else { | ||
| 472 | sprintf(path, "%s/proc/kallsyms", machine->root_dir); | ||
| 473 | guest_kallsyms = path; | ||
| 474 | } | ||
| 475 | |||
| 476 | /* | 467 | /* |
| 477 | * We use _stext for guest kernel because guest kernel's /proc/kallsyms | 468 | * We use _stext for guest kernel because guest kernel's /proc/kallsyms |
| 478 | * have no _text sometimes. | 469 | * have no _text sometimes. |
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index cf182ca132fe..7bdbfd3e24d2 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c | |||
| @@ -267,9 +267,48 @@ struct ui_browser { | |||
| 267 | void *first_visible_entry, *entries; | 267 | void *first_visible_entry, *entries; |
| 268 | u16 top, left, width, height; | 268 | u16 top, left, width, height; |
| 269 | void *priv; | 269 | void *priv; |
| 270 | unsigned int (*refresh_entries)(struct ui_browser *self); | ||
| 271 | void (*seek)(struct ui_browser *self, | ||
| 272 | off_t offset, int whence); | ||
| 270 | u32 nr_entries; | 273 | u32 nr_entries; |
| 271 | }; | 274 | }; |
| 272 | 275 | ||
| 276 | static void ui_browser__list_head_seek(struct ui_browser *self, | ||
| 277 | off_t offset, int whence) | ||
| 278 | { | ||
| 279 | struct list_head *head = self->entries; | ||
| 280 | struct list_head *pos; | ||
| 281 | |||
| 282 | switch (whence) { | ||
| 283 | case SEEK_SET: | ||
| 284 | pos = head->next; | ||
| 285 | break; | ||
| 286 | case SEEK_CUR: | ||
| 287 | pos = self->first_visible_entry; | ||
| 288 | break; | ||
| 289 | case SEEK_END: | ||
| 290 | pos = head->prev; | ||
| 291 | break; | ||
| 292 | default: | ||
| 293 | return; | ||
| 294 | } | ||
| 295 | |||
| 296 | if (offset > 0) { | ||
| 297 | while (offset-- != 0) | ||
| 298 | pos = pos->next; | ||
| 299 | } else { | ||
| 300 | while (offset++ != 0) | ||
| 301 | pos = pos->prev; | ||
| 302 | } | ||
| 303 | |||
| 304 | self->first_visible_entry = pos; | ||
| 305 | } | ||
| 306 | |||
| 307 | static bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row) | ||
| 308 | { | ||
| 309 | return (self->first_visible_entry_idx + row) == self->index; | ||
| 310 | } | ||
| 311 | |||
| 273 | static void ui_browser__refresh_dimensions(struct ui_browser *self) | 312 | static void ui_browser__refresh_dimensions(struct ui_browser *self) |
| 274 | { | 313 | { |
| 275 | int cols, rows; | 314 | int cols, rows; |
| @@ -286,8 +325,34 @@ static void ui_browser__refresh_dimensions(struct ui_browser *self) | |||
| 286 | 325 | ||
| 287 | static void ui_browser__reset_index(struct ui_browser *self) | 326 | static void ui_browser__reset_index(struct ui_browser *self) |
| 288 | { | 327 | { |
| 289 | self->index = self->first_visible_entry_idx = 0; | 328 | self->index = self->first_visible_entry_idx = 0; |
| 290 | self->first_visible_entry = NULL; | 329 | self->seek(self, 0, SEEK_SET); |
| 330 | } | ||
| 331 | |||
| 332 | static int ui_browser__show(struct ui_browser *self, const char *title) | ||
| 333 | { | ||
| 334 | if (self->form != NULL) | ||
| 335 | return 0; | ||
| 336 | ui_browser__refresh_dimensions(self); | ||
| 337 | newtCenteredWindow(self->width + 2, self->height, title); | ||
| 338 | self->form = newt_form__new(); | ||
| 339 | if (self->form == NULL) | ||
| 340 | return -1; | ||
| 341 | |||
| 342 | self->sb = newtVerticalScrollbar(self->width + 1, 0, self->height, | ||
| 343 | HE_COLORSET_NORMAL, | ||
| 344 | HE_COLORSET_SELECTED); | ||
| 345 | if (self->sb == NULL) | ||
| 346 | return -1; | ||
| 347 | |||
| 348 | newtFormAddHotKey(self->form, NEWT_KEY_UP); | ||
| 349 | newtFormAddHotKey(self->form, NEWT_KEY_DOWN); | ||
| 350 | newtFormAddHotKey(self->form, NEWT_KEY_PGUP); | ||
| 351 | newtFormAddHotKey(self->form, NEWT_KEY_PGDN); | ||
| 352 | newtFormAddHotKey(self->form, NEWT_KEY_HOME); | ||
| 353 | newtFormAddHotKey(self->form, NEWT_KEY_END); | ||
| 354 | newtFormAddComponent(self->form, self->sb); | ||
| 355 | return 0; | ||
| 291 | } | 356 | } |
| 292 | 357 | ||
| 293 | static int objdump_line__show(struct objdump_line *self, struct list_head *head, | 358 | static int objdump_line__show(struct objdump_line *self, struct list_head *head, |
| @@ -341,26 +406,10 @@ static int objdump_line__show(struct objdump_line *self, struct list_head *head, | |||
| 341 | 406 | ||
| 342 | static int ui_browser__refresh_entries(struct ui_browser *self) | 407 | static int ui_browser__refresh_entries(struct ui_browser *self) |
| 343 | { | 408 | { |
| 344 | struct objdump_line *pos; | 409 | int row; |
| 345 | struct list_head *head = self->entries; | ||
| 346 | struct hist_entry *he = self->priv; | ||
| 347 | int row = 0; | ||
| 348 | int len = he->ms.sym->end - he->ms.sym->start; | ||
| 349 | |||
| 350 | if (self->first_visible_entry == NULL || self->first_visible_entry == self->entries) | ||
| 351 | self->first_visible_entry = head->next; | ||
| 352 | |||
| 353 | pos = list_entry(self->first_visible_entry, struct objdump_line, node); | ||
| 354 | |||
| 355 | list_for_each_entry_from(pos, head, node) { | ||
| 356 | bool current_entry = (self->first_visible_entry_idx + row) == self->index; | ||
| 357 | SLsmg_gotorc(self->top + row, self->left); | ||
| 358 | objdump_line__show(pos, head, self->width, | ||
| 359 | he, len, current_entry); | ||
| 360 | if (++row == self->height) | ||
| 361 | break; | ||
| 362 | } | ||
| 363 | 410 | ||
| 411 | newtScrollbarSet(self->sb, self->index, self->nr_entries - 1); | ||
| 412 | row = self->refresh_entries(self); | ||
| 364 | SLsmg_set_color(HE_COLORSET_NORMAL); | 413 | SLsmg_set_color(HE_COLORSET_NORMAL); |
| 365 | SLsmg_fill_region(self->top + row, self->left, | 414 | SLsmg_fill_region(self->top + row, self->left, |
| 366 | self->height - row, self->width, ' '); | 415 | self->height - row, self->width, ' '); |
| @@ -368,42 +417,13 @@ static int ui_browser__refresh_entries(struct ui_browser *self) | |||
| 368 | return 0; | 417 | return 0; |
| 369 | } | 418 | } |
| 370 | 419 | ||
| 371 | static int ui_browser__run(struct ui_browser *self, const char *title, | 420 | static int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es) |
| 372 | struct newtExitStruct *es) | ||
| 373 | { | 421 | { |
| 374 | if (self->form) { | ||
| 375 | newtFormDestroy(self->form); | ||
| 376 | newtPopWindow(); | ||
| 377 | } | ||
| 378 | |||
| 379 | ui_browser__refresh_dimensions(self); | ||
| 380 | newtCenteredWindow(self->width + 2, self->height, title); | ||
| 381 | self->form = newt_form__new(); | ||
| 382 | if (self->form == NULL) | ||
| 383 | return -1; | ||
| 384 | |||
| 385 | self->sb = newtVerticalScrollbar(self->width + 1, 0, self->height, | ||
| 386 | HE_COLORSET_NORMAL, | ||
| 387 | HE_COLORSET_SELECTED); | ||
| 388 | if (self->sb == NULL) | ||
| 389 | return -1; | ||
| 390 | |||
| 391 | newtFormAddHotKey(self->form, NEWT_KEY_UP); | ||
| 392 | newtFormAddHotKey(self->form, NEWT_KEY_DOWN); | ||
| 393 | newtFormAddHotKey(self->form, NEWT_KEY_PGUP); | ||
| 394 | newtFormAddHotKey(self->form, NEWT_KEY_PGDN); | ||
| 395 | newtFormAddHotKey(self->form, ' '); | ||
| 396 | newtFormAddHotKey(self->form, NEWT_KEY_HOME); | ||
| 397 | newtFormAddHotKey(self->form, NEWT_KEY_END); | ||
| 398 | newtFormAddHotKey(self->form, NEWT_KEY_TAB); | ||
| 399 | newtFormAddHotKey(self->form, NEWT_KEY_RIGHT); | ||
| 400 | |||
| 401 | if (ui_browser__refresh_entries(self) < 0) | 422 | if (ui_browser__refresh_entries(self) < 0) |
| 402 | return -1; | 423 | return -1; |
| 403 | newtFormAddComponent(self->form, self->sb); | ||
| 404 | 424 | ||
| 405 | while (1) { | 425 | while (1) { |
| 406 | unsigned int offset; | 426 | off_t offset; |
| 407 | 427 | ||
| 408 | newtFormRun(self->form, es); | 428 | newtFormRun(self->form, es); |
| 409 | 429 | ||
| @@ -417,9 +437,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title, | |||
| 417 | break; | 437 | break; |
| 418 | ++self->index; | 438 | ++self->index; |
| 419 | if (self->index == self->first_visible_entry_idx + self->height) { | 439 | if (self->index == self->first_visible_entry_idx + self->height) { |
| 420 | struct list_head *pos = self->first_visible_entry; | ||
| 421 | ++self->first_visible_entry_idx; | 440 | ++self->first_visible_entry_idx; |
| 422 | self->first_visible_entry = pos->next; | 441 | self->seek(self, +1, SEEK_CUR); |
| 423 | } | 442 | } |
| 424 | break; | 443 | break; |
| 425 | case NEWT_KEY_UP: | 444 | case NEWT_KEY_UP: |
| @@ -427,9 +446,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title, | |||
| 427 | break; | 446 | break; |
| 428 | --self->index; | 447 | --self->index; |
| 429 | if (self->index < self->first_visible_entry_idx) { | 448 | if (self->index < self->first_visible_entry_idx) { |
| 430 | struct list_head *pos = self->first_visible_entry; | ||
| 431 | --self->first_visible_entry_idx; | 449 | --self->first_visible_entry_idx; |
| 432 | self->first_visible_entry = pos->prev; | 450 | self->seek(self, -1, SEEK_CUR); |
| 433 | } | 451 | } |
| 434 | break; | 452 | break; |
| 435 | case NEWT_KEY_PGDN: | 453 | case NEWT_KEY_PGDN: |
| @@ -442,12 +460,7 @@ static int ui_browser__run(struct ui_browser *self, const char *title, | |||
| 442 | offset = self->nr_entries - 1 - self->index; | 460 | offset = self->nr_entries - 1 - self->index; |
| 443 | self->index += offset; | 461 | self->index += offset; |
| 444 | self->first_visible_entry_idx += offset; | 462 | self->first_visible_entry_idx += offset; |
| 445 | 463 | self->seek(self, +offset, SEEK_CUR); | |
| 446 | while (offset--) { | ||
| 447 | struct list_head *pos = self->first_visible_entry; | ||
| 448 | self->first_visible_entry = pos->next; | ||
| 449 | } | ||
| 450 | |||
| 451 | break; | 464 | break; |
| 452 | case NEWT_KEY_PGUP: | 465 | case NEWT_KEY_PGUP: |
| 453 | if (self->first_visible_entry_idx == 0) | 466 | if (self->first_visible_entry_idx == 0) |
| @@ -460,29 +473,19 @@ static int ui_browser__run(struct ui_browser *self, const char *title, | |||
| 460 | 473 | ||
| 461 | self->index -= offset; | 474 | self->index -= offset; |
| 462 | self->first_visible_entry_idx -= offset; | 475 | self->first_visible_entry_idx -= offset; |
| 463 | 476 | self->seek(self, -offset, SEEK_CUR); | |
| 464 | while (offset--) { | ||
| 465 | struct list_head *pos = self->first_visible_entry; | ||
| 466 | self->first_visible_entry = pos->prev; | ||
| 467 | } | ||
| 468 | break; | 477 | break; |
| 469 | case NEWT_KEY_HOME: | 478 | case NEWT_KEY_HOME: |
| 470 | ui_browser__reset_index(self); | 479 | ui_browser__reset_index(self); |
| 471 | break; | 480 | break; |
| 472 | case NEWT_KEY_END: { | 481 | case NEWT_KEY_END: |
| 473 | struct list_head *head = self->entries; | ||
| 474 | offset = self->height - 1; | 482 | offset = self->height - 1; |
| 475 | 483 | ||
| 476 | if (offset > self->nr_entries) | 484 | if (offset > self->nr_entries) |
| 477 | offset = self->nr_entries; | 485 | offset = self->nr_entries; |
| 478 | 486 | ||
| 479 | self->index = self->first_visible_entry_idx = self->nr_entries - 1 - offset; | 487 | self->index = self->first_visible_entry_idx = self->nr_entries - 1 - offset; |
| 480 | self->first_visible_entry = head->prev; | 488 | self->seek(self, -offset, SEEK_END); |
| 481 | while (offset-- != 0) { | ||
| 482 | struct list_head *pos = self->first_visible_entry; | ||
| 483 | self->first_visible_entry = pos->prev; | ||
| 484 | } | ||
| 485 | } | ||
| 486 | break; | 489 | break; |
| 487 | case NEWT_KEY_RIGHT: | 490 | case NEWT_KEY_RIGHT: |
| 488 | case NEWT_KEY_LEFT: | 491 | case NEWT_KEY_LEFT: |
| @@ -539,6 +542,31 @@ static char *callchain_list__sym_name(struct callchain_list *self, | |||
| 539 | return bf; | 542 | return bf; |
| 540 | } | 543 | } |
| 541 | 544 | ||
| 545 | static unsigned int hist_entry__annotate_browser_refresh(struct ui_browser *self) | ||
| 546 | { | ||
| 547 | struct objdump_line *pos; | ||
| 548 | struct list_head *head = self->entries; | ||
| 549 | struct hist_entry *he = self->priv; | ||
| 550 | int row = 0; | ||
| 551 | int len = he->ms.sym->end - he->ms.sym->start; | ||
| 552 | |||
| 553 | if (self->first_visible_entry == NULL || self->first_visible_entry == self->entries) | ||
| 554 | self->first_visible_entry = head->next; | ||
| 555 | |||
| 556 | pos = list_entry(self->first_visible_entry, struct objdump_line, node); | ||
| 557 | |||
| 558 | list_for_each_entry_from(pos, head, node) { | ||
| 559 | bool current_entry = ui_browser__is_current_entry(self, row); | ||
| 560 | SLsmg_gotorc(self->top + row, self->left); | ||
| 561 | objdump_line__show(pos, head, self->width, | ||
| 562 | he, len, current_entry); | ||
| 563 | if (++row == self->height) | ||
| 564 | break; | ||
| 565 | } | ||
| 566 | |||
| 567 | return row; | ||
| 568 | } | ||
| 569 | |||
| 542 | static void __callchain__append_graph_browser(struct callchain_node *self, | 570 | static void __callchain__append_graph_browser(struct callchain_node *self, |
| 543 | newtComponent tree, u64 total, | 571 | newtComponent tree, u64 total, |
| 544 | int *indexes, int depth) | 572 | int *indexes, int depth) |
| @@ -701,7 +729,9 @@ int hist_entry__tui_annotate(struct hist_entry *self) | |||
| 701 | ui_helpline__push("Press <- or ESC to exit"); | 729 | ui_helpline__push("Press <- or ESC to exit"); |
| 702 | 730 | ||
| 703 | memset(&browser, 0, sizeof(browser)); | 731 | memset(&browser, 0, sizeof(browser)); |
| 704 | browser.entries = &head; | 732 | browser.entries = &head; |
| 733 | browser.refresh_entries = hist_entry__annotate_browser_refresh; | ||
| 734 | browser.seek = ui_browser__list_head_seek; | ||
| 705 | browser.priv = self; | 735 | browser.priv = self; |
| 706 | list_for_each_entry(pos, &head, node) { | 736 | list_for_each_entry(pos, &head, node) { |
| 707 | size_t line_len = strlen(pos->line); | 737 | size_t line_len = strlen(pos->line); |
| @@ -711,7 +741,8 @@ int hist_entry__tui_annotate(struct hist_entry *self) | |||
| 711 | } | 741 | } |
| 712 | 742 | ||
| 713 | browser.width += 18; /* Percentage */ | 743 | browser.width += 18; /* Percentage */ |
| 714 | ret = ui_browser__run(&browser, self->ms.sym->name, &es); | 744 | ui_browser__show(&browser, self->ms.sym->name); |
| 745 | ui_browser__run(&browser, &es); | ||
| 715 | newtFormDestroy(browser.form); | 746 | newtFormDestroy(browser.form); |
| 716 | newtPopWindow(); | 747 | newtPopWindow(); |
| 717 | list_for_each_entry_safe(pos, n, &head, node) { | 748 | list_for_each_entry_safe(pos, n, &head, node) { |
