#!/usr/bin/tclsh
# -*- tcl -*-

proc do_time {module n} {  
  global Failures

  # start kprobes
  if {[catch {exec ../../stpd/stpd -mq $module.ko > xxx &} pid]} {
    puts $pid
    exit -1
  }
  
  exec sleep 2

  # get the timings while kprobes running
  if {[catch {exec ./ttest $n} res2]} {
    puts $res2
    exit -1
  }
  
  # terminate kprobes
  if {[catch {exec kill -s SIGINT $pid} res]} {
    puts $res
  }

  exec sleep 2

  # look for warnings 
  exec tail xxx >xxx.tail
  if {[catch {open xxx.tail r} fd]} {
    puts "Cannot open test output\n"
    exit -1
  }

  set Failures 0
  while {[gets $fd line] >= 0} {
    if {[regexp {^\033\[33mWARNING: \033\[0mThere were ([0-9]*) transport failures.} $line match var]} {
      set Failures $var
      break
    }
  }
  close $fd
  exec /bin/rm -f xxx xxx.out
  return $res2
}

######## START HERE ###########


set nproc [exec grep ^processor /proc/cpuinfo | wc -l]
if {![catch {exec grep "physical id" /proc/cpuinfo} phyid]} {
    foreach phy [split $phyid \n] {
	set cpu($phy) 1
    }
}
set model [exec grep "model name" /proc/cpuinfo]
set model [lindex [split $model \n] 0]
set model [string range $model [expr [string first : $model]+1] end]
set model [string trimleft $model]

puts "STP BENCH for [exec uname -r] on [exec uname -m]"
if {[file exists /etc/redhat-release]} {
  puts [exec cat /etc/redhat-release]
}
puts "[exec uname -n]: [exec uptime]"
if {$nproc > 1} { 
    puts "processors: $nproc ([array size cpu] physical) $model"
} else {
    puts "processors: $nproc $model"
}
set mem [split [exec cat /proc/meminfo] \n]
puts "[lindex $mem 0]    [lindex $mem 1]"
puts "--------------------------------------"

# load the modules
if {[catch {exec stp_check} res]} {
    puts $res
    exit -1
}

# get the timings without kprobes
if {[catch {exec ./ttest 4} res1]} {
  puts $res1
  exit -1
}

set r_overhead [lindex $res1 0]
set w_overhead [lindex $res1 1]

puts "function call overhead = $r_overhead ns"
puts "--------------------------------------"

set res2 [do_time bench 4]
set t_kprobe [expr [lindex $res2 0] - $r_overhead]
set t_jprobe [expr [lindex $res2 1] - $w_overhead]

puts "Jprobes overhead = $t_jprobe ns"
puts "Kprobes overhead = $t_kprobe ns"
puts "--------------------------------------"

if {[file exists bench_ret.ko]} {
  set res2 [do_time bench_ret 4]
  set t_ret [expr [lindex $res2 0] - $r_overhead]
  set t_entret [expr [lindex $res2 1] - $w_overhead]
  
  puts "Return probe overhead       = $t_ret ns"
  puts "Entry+Return probe overhead = $t_entret ns"
  puts "--------------------------------------"
}

set res2 [do_time bench_multi 4]
set t_k2 [expr [lindex $res2 0] - $r_overhead]
set t_k4 [expr [lindex $res2 1] - $w_overhead]

puts "2 kprobes on same func       = $t_k2 ns"
puts "4 kprobes on same func       = $t_k4 ns"
puts "--------------------------------------"

set res2 [do_time bench_io1 1]
# subtract function call overhead and kprobe overhead
set t_printf [expr [lindex $res2 0] - $r_overhead - $t_kprobe]
set t_print [expr [lindex $res2 1] - $w_overhead - $t_kprobe]

puts "PROCFS"
puts "_stp_printf on 100 chars = $t_printf ns."
puts "_stp_print  on 100 chars = $t_print ns."
puts "Transport failures: $Failures"
puts "--------------------------------------"
exec sleep 4

set res2 [do_time bench_io2 1]
# subtract function call overhead and kprobe overhead
set t_printf [expr [lindex $res2 0] - $r_overhead - $t_kprobe]
set t_print [expr [lindex $res2 1] - $w_overhead - $t_kprobe]

puts "RELAYFS"
puts "_stp_printf on 100 chars = $t_printf ns."
puts "_stp_print  on 100 chars = $t_print ns."
puts "Transport failures: $Failures"
puts "--------------------------------------"

exec /bin/rm -f stpd_cpu*
