diff options
Diffstat (limited to 'tools/perf/builtin-lock.c')
-rw-r--r-- | tools/perf/builtin-lock.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index c4eb854ff7eb..1e93179c2d30 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c | |||
@@ -387,7 +387,15 @@ static struct lock_seq_stat *get_seq(struct thread_stat *ts, void *addr) | |||
387 | return seq; | 387 | return seq; |
388 | } | 388 | } |
389 | 389 | ||
390 | static int bad_hist[4]; | 390 | enum broken_state { |
391 | BROKEN_ACQUIRE, | ||
392 | BROKEN_ACQUIRED, | ||
393 | BROKEN_CONTENDED, | ||
394 | BROKEN_RELEASE, | ||
395 | BROKEN_MAX, | ||
396 | }; | ||
397 | |||
398 | static int bad_hist[BROKEN_MAX]; | ||
391 | 399 | ||
392 | static void | 400 | static void |
393 | report_lock_acquire_event(struct trace_acquire_event *acquire_event, | 401 | report_lock_acquire_event(struct trace_acquire_event *acquire_event, |
@@ -437,7 +445,7 @@ report_lock_acquire_event(struct trace_acquire_event *acquire_event, | |||
437 | broken: | 445 | broken: |
438 | /* broken lock sequence, discard it */ | 446 | /* broken lock sequence, discard it */ |
439 | ls->discard = 1; | 447 | ls->discard = 1; |
440 | bad_hist[0]++; | 448 | bad_hist[BROKEN_ACQUIRE]++; |
441 | list_del(&seq->list); | 449 | list_del(&seq->list); |
442 | free(seq); | 450 | free(seq); |
443 | goto end; | 451 | goto end; |
@@ -481,7 +489,6 @@ report_lock_acquired_event(struct trace_acquired_event *acquired_event, | |||
481 | case SEQ_STATE_CONTENDED: | 489 | case SEQ_STATE_CONTENDED: |
482 | contended_term = timestamp - seq->prev_event_time; | 490 | contended_term = timestamp - seq->prev_event_time; |
483 | ls->wait_time_total += contended_term; | 491 | ls->wait_time_total += contended_term; |
484 | |||
485 | if (contended_term < ls->wait_time_min) | 492 | if (contended_term < ls->wait_time_min) |
486 | ls->wait_time_min = contended_term; | 493 | ls->wait_time_min = contended_term; |
487 | else if (ls->wait_time_max < contended_term) | 494 | else if (ls->wait_time_max < contended_term) |
@@ -492,7 +499,7 @@ report_lock_acquired_event(struct trace_acquired_event *acquired_event, | |||
492 | case SEQ_STATE_READ_ACQUIRED: | 499 | case SEQ_STATE_READ_ACQUIRED: |
493 | /* broken lock sequence, discard it */ | 500 | /* broken lock sequence, discard it */ |
494 | ls->discard = 1; | 501 | ls->discard = 1; |
495 | bad_hist[1]++; | 502 | bad_hist[BROKEN_ACQUIRED]++; |
496 | list_del(&seq->list); | 503 | list_del(&seq->list); |
497 | free(seq); | 504 | free(seq); |
498 | goto end; | 505 | goto end; |
@@ -540,7 +547,7 @@ report_lock_contended_event(struct trace_contended_event *contended_event, | |||
540 | case SEQ_STATE_CONTENDED: | 547 | case SEQ_STATE_CONTENDED: |
541 | /* broken lock sequence, discard it */ | 548 | /* broken lock sequence, discard it */ |
542 | ls->discard = 1; | 549 | ls->discard = 1; |
543 | bad_hist[2]++; | 550 | bad_hist[BROKEN_CONTENDED]++; |
544 | list_del(&seq->list); | 551 | list_del(&seq->list); |
545 | free(seq); | 552 | free(seq); |
546 | goto end; | 553 | goto end; |
@@ -594,7 +601,7 @@ report_lock_release_event(struct trace_release_event *release_event, | |||
594 | case SEQ_STATE_RELEASED: | 601 | case SEQ_STATE_RELEASED: |
595 | /* broken lock sequence, discard it */ | 602 | /* broken lock sequence, discard it */ |
596 | ls->discard = 1; | 603 | ls->discard = 1; |
597 | bad_hist[3]++; | 604 | bad_hist[BROKEN_RELEASE]++; |
598 | goto free_seq; | 605 | goto free_seq; |
599 | break; | 606 | break; |
600 | default: | 607 | default: |
@@ -713,6 +720,21 @@ process_raw_event(void *data, int cpu, u64 timestamp, struct thread *thread) | |||
713 | process_lock_release_event(data, event, cpu, timestamp, thread); | 720 | process_lock_release_event(data, event, cpu, timestamp, thread); |
714 | } | 721 | } |
715 | 722 | ||
723 | static void print_bad_events(int bad, int total) | ||
724 | { | ||
725 | /* Output for debug, this have to be removed */ | ||
726 | int i; | ||
727 | const char *name[4] = | ||
728 | { "acquire", "acquired", "contended", "release" }; | ||
729 | |||
730 | pr_info("\n=== output for debug===\n\n"); | ||
731 | pr_info("bad:%d, total:%d\n", bad, total); | ||
732 | pr_info("bad rate:%f\n", (double)(bad / total)); | ||
733 | pr_info("histogram of events caused bad sequence\n"); | ||
734 | for (i = 0; i < BROKEN_MAX; i++) | ||
735 | pr_info(" %10s: %d\n", name[i], bad_hist[i]); | ||
736 | } | ||
737 | |||
716 | /* TODO: various way to print, coloring, nano or milli sec */ | 738 | /* TODO: various way to print, coloring, nano or milli sec */ |
717 | static void print_result(void) | 739 | static void print_result(void) |
718 | { | 740 | { |
@@ -762,20 +784,7 @@ static void print_result(void) | |||
762 | pr_info("\n"); | 784 | pr_info("\n"); |
763 | } | 785 | } |
764 | 786 | ||
765 | { | 787 | print_bad_events(bad, total); |
766 | /* Output for debug, this have to be removed */ | ||
767 | int i; | ||
768 | const char *name[4] = | ||
769 | { "acquire", "acquired", "contended", "release" }; | ||
770 | |||
771 | pr_debug("\n=== output for debug===\n\n"); | ||
772 | pr_debug("bad:%d, total:%d\n", bad, total); | ||
773 | pr_debug("bad rate:%f\n", (double)(bad / total)); | ||
774 | |||
775 | pr_debug("histogram of events caused bad sequence\n"); | ||
776 | for (i = 0; i < 4; i++) | ||
777 | pr_debug(" %10s: %d\n", name[i], bad_hist[i]); | ||
778 | } | ||
779 | } | 788 | } |
780 | 789 | ||
781 | static int info_threads; | 790 | static int info_threads; |