#
# timer_top.pl
#
# Timer Top: gets timers info exported by kernel in /proc/top_info and
# organizes and shows useful info in the screen. Its main purpose is to
# test the dynamic tick patch by Tony Lindgren and Tuukka Tikkanen.
# Idea is to evolve this in order to get more useful info
# It needs the System.map file to be in the same directory
#
# Copyright (C) 2005 Insituto Nokia de Tecnologia - INdT - Manaus
# Written by Daniel Petrini <daniel.petrini@indt.org.br> and
#            Ilias Biris <ilias.biris@indt.org.br>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
# 
#!/usr/bin/perl

open (INFILE, "System.map") || die ("cannot open file\n");

my ($interval) = $ARGV[0];
my ($diff) = $ARGV[1];

if ($interval eq "") {
    printf("Usage: %s interval_in_seconds print_diff\n", $0);	
    exit(1);
}

if ($diff eq "") {
    $diff = 1;    
} 

%sys_map_lines=();
%top_lines=();
%numb_func=();
%diff_time=();

while(<INFILE>) {
    chomp $_;
    if( $_ ne "" ) {
	$sys_map_line = substr($_, 0, 8);	
	$sys_map_lines{$sys_map_line}=substr($_, 10, length($_));
    }
}
close(INFILE);


sub read_top_info {

    open (INFILE2, "/proc/top_info") || die ("cannot open file\n");

    while(<INFILE2>){
	if( $_ !~ m/^Function\scounter/ ){
	    $func_top = substr( $_, 0, 8);
	    $numb_top = substr( $_, 9, 8);
	    if( $sys_map_lines{$func_top} ne "" ){
		# Check if there is variation for that timer function
		if ( ($numb_top) != ($numb_func{$func_top})  ) {
		    $top_lines{$func_top} = $sys_map_lines{$func_top};
		    $diff_time{$func_top} = $numb_top - $numb_func{$func_top};	#Get the difference
		    $numb_func{$func_top} = $numb_top;
	    	} else {
		    $top_lines{$func_top} = "";
		} 
		    

	    }
	}
    }
    close(INFILE2);
}

while (1) {

    read_top_info();

    system("clear");

    print "Timer Top v0.9.1 \n";
    print "Address      Count   Freq(Hz)   Function\n";

    while(($item, $value) = each(%top_lines)) {
	if ( $top_lines{$item} ne "" ) {
	    chomp ($numb_func{$item});
	    printf "%s|%10s|%9.2f|%s\n", $item, $numb_func{$item}, $diff_time{$item}/$interval, $value;
	}
    }
    sleep $interval;
}
