#!/usr/bin/perl
#!/usr/bin/perl
##############################################################################
# Time-stamp: <Wed Nov 22 2000 03:05:52 Stardate: [-30]5765.64 hwloidl>
#
# Usage: gr2RTS [options] <gr-file>
#
# Extract the runtimes of all threads out of a gr-file, sort them, and write 
# them into an intermediate file. 
# 
# Options:
#  -o <file> ... write output to <file>
#  -I <char> ... extract <char> out of gr-file (default: runtime):
#                  'r' ... runtime (default)
#                  'b' ... blocktime 
#                  'f' ... fetchtime
#                  'a' ... heap allocations
#                  's' ... sparks
#  -h        ... help; print this text.
#  -v        ... verbose mode.
#
##############################################################################

# @menu
# * Init::			
# * Main prg::			
# * Subroutines::		
# @end menu

# @node Top, Init, (dir), (dir)
# @top

# ----------------------------------------------------------------------------
# @node Init, Main prg, Top, Top
# @section Command line processing and initialization
# ----------------------------------------------------------------------------

# Constants
$runtime = 10;
$blocktime = 11; 
$fetchtime = 12;
$heap_alloc = 13;
$sparks = 14;

%str = ( $runtime,    "runtime",
	 $blocktime,  "blocktime",
	 $fetchtime,  "fetchtime",
	 $heap_alloc, "heap_allocations",
	 $sparks,     "sparks" );

require "getopts.pl";

&Getopts('hvo:I:');  

do process_options();

if ( $opt_v ) { do print_verbose_message (); }

# ----------------------------------------------------------------------------
# @node Main prg, Subroutines, Init, Top
# @section Main prg ---The real thing
# ----------------------------------------------------------------------------

open(INPUT,"<$input") || die "Couldn't open input file $input";
open(OUTPUT,"| sort -n > $output") || die "Couldn't open output pipe: sort -n > $output";

#do skip_header();

$it = $max = $sum = 0;
$line_no = 0;
while (<INPUT>) {
    next                     if /^--/;     # Comment lines start with --
    next		     if /^\s*$/;   # Skip empty lines
    $line_no++;
    @fields = split(/[:,]/,$_);
    $has_end = 0;

    foreach $elem (@fields) {
      foo : {
        $pe = $1, $end = $2 , last foo   if $elem =~ /^\s*PE\s+(\d+)\s+\[(\d+)\].*$/;
        $tn = $1, $has_end = 1  , last foo   if $elem =~ /^\s*END\s+(\w+).*$/;
	# $tn = $1	, last foo   if $elem =~ /^\s*TN\s+(\w+).*$/;
	$sn = $1	, last foo   if $elem =~ /^\s*SN\s+(\d+).*$/;
        $start = $1     , last foo   if $elem =~ /^\s*ST\s+(\d+).*$/;
        $is_global = $1 , last foo   if $elem =~ /^\s*EXP\s+(T|F).*$/;
        $bbs = $1       , last foo   if $elem =~ /^\s*BB\s+(\d+).*$/;
        $ha = $1        , last foo   if $elem =~ /^\s*HA\s+(\d+).*$/;
        $rt = $1        , last foo   if $elem =~ /^\s*RT\s+(\d+).*$/;
        $bt = $1, $bc = $2 , last foo if $elem =~ /^\s*BT\s+(\d+)\s+\((\d+)\).*$/;
        $ft = $1, $fc = $2 , last foo if $elem =~ /^\s*FT\s+(\d+)\s+\((\d+)\).*$/;
        $lsp = $1        , last foo   if $elem =~ /^\s*LS\s+(\d+).*$/;
        $gsp = $1        , last foo   if $elem =~ /^\s*GS\s+(\d+).*$/;
        $my = $1        , last foo   if $elem =~ /^\s*MY\s+(T|F).*$/;
      }
    }

    next unless $has_end == 1;

    $ha = 4*$ha;   # allocations recorded in words; translated into bytes
    bar: {
         $it = $rt, $max = (($rt>$max) ? $rt : $max), $sum += $rt, 
	   last bar  if $what == $runtime;
         $it = $bt, $max = (($bt>$max) ? $bt : $max), $sum += $bt, 
	   last bar  if $what == $blocktime;
	 $it = $ft, $max = (($ft>$max) ? $ft : $max), $sum += $ft, 
	   last bar  if $what == $fetchtime;
	 $it = $ha, $max = (($ha>$max) ? $ha : $max), $sum += $ha, 
	   last bar  if $what == $heap_alloc;
	 $it = $gsp, $max = (($gsp>$max) ? $gsp : $max), $sum += $gsp, 
	   last bar  if $what == $sparks;
	 # die "Unknown field to extract: $what\n"; # dbg
    }

#     $total_rt = $end - $start;
#     $tot_total_rt += $total_rt;
#     $tot_rt += $rt;

    print OUTPUT "$it\n";
}
close INPUT;
close OUTPUT;

# Hack to  fake a filter
if ( $output eq $filter_output ) {
    system "cat $output";
    system "rm $output";
}

exit 0;

# ---------------------------------------------------------------------------

# @node Subroutines,  , Main prg, Top
# @section Subroutines

sub process_options {
    if ( $opt_h ) {                      
	open(ME,$0) || die "Can't open myself ($0)";
	$n = 0;
	while (<ME>) {
	    last if $_ =~ /^$/;
	    print $_;
	    $n++;
	}
	close(ME);
	
	# system "cat $0 | awk 'BEGIN { n = 0; } \
	#                             /^$/ { print n; \
	#                                    exit; } \
	#                                  { n++; }'"
	exit ;
    }

    $input = $#ARGV == -1 ? "-" : $ARGV[0] ;
    
    if ( $#ARGV != 0 ) {
	#print "Usage: gran-extr [options] <sim-file>\n";
	#print "Use -h option to get details\n";
	#exit 1;
	
    }

    $filter_output = $ENV{'TMPDIR'} . "./,gr2RTS-out";
    if ( $opt_o ) {
	$output = $opt_o;
    } else {
	if ( $input eq "-" ) {
	    $output = $filter_output;
	} else {
	    $output = $input; # "RTS";
	    $output =~ s/\.gr$/.rts/g;
        }			# 
    }
    $what = $runtime;
    $what = $blocktime  if $opt_I eq "b";
    $what = $fetchtime  if $opt_I eq "f";
    $what = $heap_alloc if $opt_I eq "a";
    $what = $sparks     if $opt_I eq "s";
}

# ----------------------------------------------------------------------------

sub print_verbose_message {
    print STDERR "Input file: $input\t Output file: $output\n";
    print STDERR  "Extracting: " . $str{$what} . " ($what)\n";
}

# ----------------------------------------------------------------------------
