Home | History | Annotate | Download | only in perl
      1 #!/usr/bin/perl -w
      2 # (c) 2009, Tom Zanussi <tzanussi (at] gmail.com>
      3 # Licensed under the terms of the GNU GPL License version 2
      4 
      5 # Display avg/min/max wakeup latency
      6 
      7 # The common_* event handler fields are the most useful fields common to
      8 # all events.  They don't necessarily correspond to the 'common_*' fields
      9 # in the status files.  Those fields not available as handler params can
     10 # be retrieved via script functions of the form get_common_*().
     11 
     12 use 5.010000;
     13 use strict;
     14 use warnings;
     15 
     16 use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
     17 use lib "./Perf-Trace-Util/lib";
     18 use Perf::Trace::Core;
     19 use Perf::Trace::Util;
     20 
     21 my %last_wakeup;
     22 
     23 my $max_wakeup_latency;
     24 my $min_wakeup_latency;
     25 my $total_wakeup_latency = 0;
     26 my $total_wakeups = 0;
     27 
     28 sub sched::sched_switch
     29 {
     30     my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
     31 	$common_pid, $common_comm,
     32 	$prev_comm, $prev_pid, $prev_prio, $prev_state, $next_comm, $next_pid,
     33 	$next_prio) = @_;
     34 
     35     my $wakeup_ts = $last_wakeup{$common_cpu}{ts};
     36     if ($wakeup_ts) {
     37 	my $switch_ts = nsecs($common_secs, $common_nsecs);
     38 	my $wakeup_latency = $switch_ts - $wakeup_ts;
     39 	if ($wakeup_latency > $max_wakeup_latency) {
     40 	    $max_wakeup_latency = $wakeup_latency;
     41 	}
     42 	if ($wakeup_latency < $min_wakeup_latency) {
     43 	    $min_wakeup_latency = $wakeup_latency;
     44 	}
     45 	$total_wakeup_latency += $wakeup_latency;
     46 	$total_wakeups++;
     47     }
     48     $last_wakeup{$common_cpu}{ts} = 0;
     49 }
     50 
     51 sub sched::sched_wakeup
     52 {
     53     my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
     54 	$common_pid, $common_comm,
     55 	$comm, $pid, $prio, $success, $target_cpu) = @_;
     56 
     57     $last_wakeup{$target_cpu}{ts} = nsecs($common_secs, $common_nsecs);
     58 }
     59 
     60 sub trace_begin
     61 {
     62     $min_wakeup_latency = 1000000000;
     63     $max_wakeup_latency = 0;
     64 }
     65 
     66 sub trace_end
     67 {
     68     printf("wakeup_latency stats:\n\n");
     69     print "total_wakeups: $total_wakeups\n";
     70     if ($total_wakeups) {
     71 	printf("avg_wakeup_latency (ns): %u\n",
     72 	       avg($total_wakeup_latency, $total_wakeups));
     73     } else {
     74 	printf("avg_wakeup_latency (ns): N/A\n");
     75     }
     76     printf("min_wakeup_latency (ns): %u\n", $min_wakeup_latency);
     77     printf("max_wakeup_latency (ns): %u\n", $max_wakeup_latency);
     78 
     79     print_unhandled();
     80 }
     81 
     82 my %unhandled;
     83 
     84 sub print_unhandled
     85 {
     86     if ((scalar keys %unhandled) == 0) {
     87 	return;
     88     }
     89 
     90     print "\nunhandled events:\n\n";
     91 
     92     printf("%-40s  %10s\n", "event", "count");
     93     printf("%-40s  %10s\n", "----------------------------------------",
     94 	   "-----------");
     95 
     96     foreach my $event_name (keys %unhandled) {
     97 	printf("%-40s  %10d\n", $event_name, $unhandled{$event_name});
     98     }
     99 }
    100 
    101 sub trace_unhandled
    102 {
    103     my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
    104 	$common_pid, $common_comm) = @_;
    105 
    106     $unhandled{$event_name}++;
    107 }
    108