#!/usr/bin/perl
# This script reads the output from the irqs monitor and reports how many
# unique stack traces there were and what the latencies each time were.
# One would typically expect that the latencies were always roughly the
# same and if not, it's worth investigating
#
# Copyright Mel Gorman 2011
use strict;

my $line;
my %unique_event_counts;
my %unique_event_trace;
my %unique_event_latency;
my %unique_event_latency_details;
my $total_irqsoff_latency;

my ($timestamp, $latency, $latency_details, $started, $ended, $trace, $reading_trace);
while ($line = <>) {
	# Watch for the beginning of a new event
	if ($line =~ /^time: ([0-9]*)/) {
		if ($ended ne "") {
			my $event;
			$event = sprintf "%-50s %4d", "$started..$ended", $latency;
			$unique_event_counts{$event}++;
			$unique_event_trace{$event} = $trace;
			$unique_event_latency{$event} = $latency;
			$unique_event_latency_details{$event} .= $latency_details;
			$total_irqsoff_latency += $latency;
		}

		$timestamp = $1;
		$started = $ended = "";
		$reading_trace = 0;
		$trace = "";
	}

	# If we have reached a trace, blindly read it
	if ($reading_trace) {
		$trace .= $line;
		next;
	}

	if ($line =~ /^# latency: ([0-9]*) us.*/) {
		$latency = $1;
		$latency_details = "$timestamp $line";
	}

	if ($line =~ /.*=> started at: ([_a-zA-Z0-9]*)/) {
		$started = $1;
		next;
	}

	if ($line =~ /.*=> ended at:\s+([_a-zA-Z0-9]*)/) {
		$ended = $1;
		$reading_trace = 1;
		next;
	}
}

print "Summary\n=======\n";
print "Total sampled time IRQs off (not real total time): $total_irqsoff_latency\n";
foreach my $event (sort {$unique_event_latency{$b} <=> $unique_event_latency{$a}} keys %unique_event_latency) {
	printf "Event $event us count %4d\n", $unique_event_counts{$event};
}

print "\nDetails\n=======\n";
foreach my $event (sort {$unique_event_latency{$b} <=> $unique_event_latency{$a}} keys %unique_event_latency) {
	print "Event $event us count $unique_event_counts{$event}\n";
	print $unique_event_latency_details{$event};
	print $unique_event_trace{$event};
	print "\n";
}
