# test for checking monotonic timer (PR3916) set test "gtod" if {![installtest_p]} { untested $test; continue } set wd [pwd] set filename "$srcdir/$subdir/gtod.c" target_compile $filename $wd/gtod executable "" # Return the absolute difference between num1 and num2 proc abs_diff { num1 num2 } { if {$num1 > $num2} { return [expr $num1 - $num2] } return [expr $num2 - $num1] } # We're looking for lines in the following format: # # :00 1336494634008794 appl # :00 1336494634008971 kern # :00 1336494634009194 prog # :01 1336494634009196 appl # :01 1336494634009199 kern # :01 1336494634009203 prog # ... # # The lines should be in the order 'appl', 'kern', and 'prog', but we # don't insist on it. If systemtap's time is a bit ahead of the # kernel's real time, the 'kern' line can appear first. The first # number, the count, must match on each of the 3 lines. for {set i 0} { $i < 3 } {incr i } { if {$i == 0} { # non interval (check timer drift in short range) set test "gtod (short range)" spawn $srcdir/$subdir/gtod.sh $srcdir/$subdir/gtod.stp $wd/gtod } elseif {$i == 1} { # 10ms interval (check timer drift in middle range) set test "gtod (10ms interval)" spawn $srcdir/$subdir/gtod.sh $srcdir/$subdir/gtod.stp $wd/gtod 10000 } else { # 100ms interval (calm down processors and CPU freq might be # changed) set test "gtod (100ms interval)" spawn $srcdir/$subdir/gtod.sh $srcdir/$subdir/gtod.stp $wd/gtod 100000 } # 'ok' is the number of passes set ok 0 # 'iteration_num' contains the current iteration number for each # of the 3 sets of lines set iteration_num(appl) -1 set iteration_num(kern) -1 set iteration_num(prog) -1 # 'us_time' contains the reported time for each of the 3 sets of lines set us_time(appl) 0 set us_time(kern) 0 set us_time(prog) 0 # 'max_diff' is used to remember the maximum difference between # systemtap's time and the kernel's time set max_diff 0 # 'variance' is the maximum number of microseconds difference # between systemtap's time and the kernel's time that we'll accept set variance 500 expect { -timeout 120 # We found a 'appl|kern|prog' line -re {^\:([0-9]+) ([0-9]+) (appl|kern|prog)\r\n} { set type $expect_out(3,string) set iteration_num($type) $expect_out(1,string) set us_time($type) $expect_out(2,string) # If we've seen all the lines for this iteration, check # the times. if {$iteration_num(appl) == $iteration_num(kern) \ && $iteration_num(kern) == $iteration_num(prog)} { set appl_diff [abs_diff $us_time(appl) $us_time(kern)] set prog_diff [abs_diff $us_time(prog) $us_time(kern)] if {$appl_diff < $variance && $prog_diff < $variance} { incr ok } else { verbose -log "difference of ($appl_diff, $prog_diff) for iteration $iteration_num(kern) is too large" } if {$appl_diff > $max_diff} { set max_diff $appl_diff } if {$prog_diff > $max_diff} { set max_diff $prog_diff } } exp_continue } timeout { fail "$test (timeout)" } eof { } } catch {close}; catch {wait} if {$max_diff > 0} { verbose -log "maximum time difference was $max_diff us" } if {$ok == 100} { pass "$test ($ok)" } { fail "$test ($ok)" } } exec rm -f $wd/gtod