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

proc do_time {module n buf} {  
  global Failures Filesize

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

  # get the timings while kprobes running
  if {[catch {exec ./itest $n} res2]} {
    puts "itest failed: $res2"
    exit -1
  }

  exec sleep 4
  # terminate kprobes
  if {[catch {exec kill -s SIGINT $pid} res]} {
    puts "Kill failed: $res"
  }

  exec sleep 4

  # 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

  set Filesize [file size xxx]
  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 "TRANS 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
}

# warmup
exec ./itest 20 > /dev/null

set res1 [do_time bench 1 1]
set call_overhead [lindex $res1 0]

puts "Function call plus kprobe overhead = $call_overhead ns per call"
puts "--------------------------------------"


set max 5
set n 1
set buf 1
while {$buf <= 64 && $n < $max} {
  set Failures 0
  while {!$Failures && $n < $max} {
    set res2 [do_time bench_io1 $n $buf]
    set t_printf [expr [lindex $res2 0] - $call_overhead]
    set total_print [lindex $res2 1]
    puts "PROCFS with ${buf}MB buffers"
    puts "_stp_printf on 100 chars = $t_printf ns / call system + user time."
    if {$t_printf < 0} {
      puts "res2=$res2"
      exit
    }
    puts "_stp_printf of [expr $n * 100]MB in $total_print secs real time."
    puts "Transfer rate = [format "%6.2f" [expr ($n * 100)/$total_print]] MB/sec"
    puts "Transport failures: $Failures"
    if {$Filesize != [expr $n * 100000000]} {
      puts "WARNING: file size was $Filesize (expected [expr $n * 100000000])."
    }
    puts "--------------------------------------"
    if {$Failures == 0} {incr n}
  }
  set buf [expr $buf + $buf]
}

set max 5
set n 1
set buf 1
while {$buf <= 64 && $n < $max} {
  set Failures 0
  while {!$Failures && $n < $max} {
    set res2 [do_time bench_io2 $n $buf]
    set t_printf [expr [lindex $res2 0] - $call_overhead]
    set total_print [lindex $res2 1]
    puts "RELAYFS with ${buf}MB buffers"
    puts "_stp_printf on 100 chars = $t_printf ns / call system + user time."
    if {$t_printf < 0} {
      puts "res2=$res2"
      exit
    }
    puts "_stp_printf of [expr $n * 100]MB in $total_print secs real time."
    puts "Transfer rate = [format "%6.2f" [expr ($n * 100)/$total_print]] MB/sec"
    puts "Transport failures: $Failures"
    if {$Filesize != [expr $n * 100000000]} {
      puts "WARNING: file size was $Filesize (expected [expr $n * 100000000])."
    }
    puts "--------------------------------------"
    if {$Failures == 0} {incr n}
  }
  set buf [expr $buf + $buf]
}

set Failures 0
set buf 1
set res2 [do_time bench_io3 1 $buf]
set t_printf [expr [lindex $res2 0] - $call_overhead]
set total_print [lindex $res2 1]
puts "PROCFS with ${buf}MB buffers"
puts "_stp_printf on 1000 chars = $t_printf ns / call system + user time."
if {$t_printf < 0} {
    puts "res2=$res2"
    exit
}
puts "_stp_printf of 1GB in $total_print secs real time."
puts "Transfer rate = [format "%6.2f" [expr 1000/$total_print]] MB/sec"
puts "Transport failures: $Failures"
if {$Filesize != 1000000000} {
  puts "WARNING: file size was $Filesize (expected 1000000000)."
}
puts "--------------------------------------"

set Failures 0
set buf 1
set res2 [do_time bench_io4 1 $buf]
set t_printf [expr [lindex $res2 0] - $call_overhead]
set total_print [lindex $res2 1]
puts "RELAYFS with ${buf}MB buffers"
puts "_stp_printf on 1000 chars = $t_printf ns / call system + user time."
if {$t_printf < 0} {
    puts "res2=$res2"
    exit
}
puts "_stp_printf of 1GB in $total_print secs real time."
puts "Transfer rate = [format "%6.2f" [expr 1000/$total_print]] MB/sec"
puts "Transport failures: $Failures"
if {$Filesize != 1000000000} {
  puts "WARNING: file size was $Filesize (expected 1000000000)."
}
puts "--------------------------------------"

exec /bin/rm -f stpd_cpu*
