Home | History | Annotate | Download | only in tests
      1 #!/bin/sh
      2 
      3 debug=false;args=;time=true
      4 
      5 # temporary files used by this script
      6 my_awk=/tmp/.uptime.$$.awk
      7 my_log=/tmp/.uptime.$$.log
      8 
      9 # check for arguments - to override temporary file names
     10 yes=true
     11 while $yes && [ $# -gt 1 ]
     12 do
     13   case $1 in
     14     -v)
     15       # verbose mode: print collected info
     16       debug=true
     17       shift
     18       ;;
     19     -vv)
     20       # super verbose mode: print collected info and debug awk script
     21       debug=true
     22       args="$args debug=1"
     23       shift
     24       ;;
     25     -notime)
     26       # do not use time
     27       time=false
     28       shift
     29       ;;
     30     -CPU=*)
     31       # CPU speed
     32       args="$args `echo "$1" | cut -c2-`"
     33       shift
     34       ;;
     35     *)
     36       yes=false
     37       ;;
     38   esac
     39 done
     40 
     41 cat >$my_awk <<"AWKSCRIPT"
     42 
     43 BEGIN {
     44    FS=" "
     45    factor=0;           # we are measuring after-before as (-before) + (after),
     46                        # so the factor before the test is -1, after the test is
     47                        # +1.
     48    uptime_total = 0;   # total system uptime (before/after)
     49    uptime_idle  = 0;   # total idle uptime (before/after)
     50    proctime_total = 0; # total time the test was running
     51    proctime_work  = 0; # total CPU time that the test was using
     52    cpu_time = 0;       # total time the CPU stats were measured on
     53    cpu_MHz = 0;        # total kHz work for the CPU
     54    cpu_eMHz = 0;       # effective CPU operating point
     55    delete MHZtime;     # total time spent in various power states
     56    kernel = 0;         # don't print separate kernel time statistics
     57 
     58    # get variable assignments from ARGV
     59    for (i=1; i<ARGC; i++)
     60    {
     61       arg = ARGV[i];
     62       if      (gsub("^CPU=",     "",arg)) { cpu_eMHz = arg; }
     63       else if (gsub("^debug=",   "",arg)) { debug    = arg; }
     64       else if (arg == "kernel")           { kernel   = 1; }
     65       else continue;
     66       delete ARGV[i]; # we can do this is AWK, and we don't need to decrement i
     67    }
     68 }
     69 
     70 /^[0-9]+\./ {  # /proc/uptime lines
     71    # the first time an uptime line is encountered factor should be -1, the
     72    # second time it should be 1.  We set it to 0 at the beginning, so we use
     73    # that to decide if it is the 1st uptime line
     74    factor = factor ? 1 : -1
     75    # get uptime stats (for beginning or end)
     76    uptime_total += factor * $1
     77    uptime_idle  += factor * $2
     78    if (debug)
     79    {
     80       print "got(/proc/uptime):", $0, "=>", factor, uptime_total, uptime_idle
     81    }
     82 }
     83 
     84 /^[0-9]+ / {   # /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state lines
     85    # get time spent in various power states (in 10ms)
     86    MHZtime[$1] += factor * $2 * 0.01
     87    cpu_time += factor * $2 * 0.01
     88    cpu_MHz += factor * $1 * $2 / 100000 # (CPU freq is in kHz)
     89    if (debug)
     90    {
     91       print "got(/sys/..time_in_state):", $0, "=>", factor, cpu_time, cpu_MHz, MHZtime[$1]
     92    }
     93 }
     94 
     95 /^(real|user|sys)/ {
     96    # test has run
     97    factor=1
     98    # get time (from h m s notation to seconds)
     99    time=0
    100    for (i = 2; i <= NF; i++)
    101    {
    102       if ($i ~ /h/)
    103       {
    104          time += 3600 * $i
    105       }
    106       else if ($i ~ /m/)
    107       {
    108          time += 60 * $i
    109       }
    110       else
    111       {  # this works for both POSIX and normal output
    112          time += 1 * $i
    113       }
    114       if (debug)
    115       {
    116          print "got (" $i ") =>", time
    117       }
    118    }
    119 
    120    if ($1 ~ /real/)
    121    {
    122       proctime_total = time
    123    }
    124    else
    125    {
    126       proctime_work += time;
    127       if (kernel && ($1 ~ /sys/))
    128       {
    129          proctime_kernel += time;
    130       }
    131    }
    132 
    133    if (debug)
    134    {
    135       print "got(time)", $0, "=>", proctime_total, proctime_work
    136    }
    137 }
    138 
    139 END {
    140    print "ARMtime Results"
    141 
    142    if (proctime_total)
    143    {
    144       dur_time = ", " proctime_total " (time)"
    145    }
    146    if (cpu_time)
    147    {
    148       dur_cpu = ", " cpu_time " (cpu-stats)"
    149    }
    150    
    151    print " Test duration:", uptime_total, "(uptime)" dur_time dur_cpu
    152 
    153    # calculate CPU MHz for test
    154    cpu_states = 0
    155    for (i in MHZtime)
    156    {
    157       if (MHZtime[i] > 0)
    158       {
    159          print " ARM-CPU time at", i/1000, "MHz: ", MHZtime[i], "s"
    160          cpu_states ++;
    161       }
    162    }
    163 
    164    if (cpu_time)
    165    {
    166       cpu_eMHz = cpu_MHz/cpu_time
    167    }
    168    else if (cpu_states)
    169    {
    170       cpu_eMHz /= cpu_states
    171    }
    172    else if (cpu_eMHz == 0)
    173    {
    174       "grep mpu /proc/omap_clocks /proc/ckomap24xx" | getline clock_speed
    175       split(clock_speed, clock_speeds)
    176       if (debug) {
    177          print "got", clock_speed
    178          print "got", clock_speeds[1], clock_speeds[2], clock_speeds[3]
    179       }
    180       cpu_eMHz = clock_speeds[3] / 1000000
    181    }
    182 
    183    # mark ~ if we are not sure about the CPU-speed (e.g. if we had more than one
    184    # power states during the test run)
    185    cpu_sureness = (cpu_states == 1) ? "" : "~"
    186 
    187    cpu_eMHz /= 100  # so we can multiply with the %-s
    188    if (uptime_total > 0)
    189    {
    190       # WE always will use uptime total
    191       uptime_idle -= uptime_total
    192       util = int(0.5 - 1000 * uptime_idle/uptime_total) / 10
    193 
    194       # don't let utilization be negative (because it is infact 0)
    195       if (util < 0)
    196       {
    197          util = 0
    198       }
    199 
    200       print " Total ARM-CPU utilization:", util "% =", cpu_sureness (util * cpu_eMHz), "eMHz"
    201       if (proctime_total)
    202       {
    203          util = int(0.5 + 1000 * proctime_work/uptime_total) / 10
    204          print " Test  ARM-CPU utilization:", util "% =", cpu_sureness (util * cpu_eMHz), "eMHz"
    205 
    206          if (kernel)
    207          {
    208             util = int(0.5 + 1000 * proctime_kernel/uptime_total) / 10
    209             proc_util = int(0.5 + 1000 * proctime_kernel/proctime_work) / 10
    210             print " Test's kernel space util.:", util "% =", cpu_sureness (util * cpu_eMHz), "eMHz (" proc_util "% of test thread)"
    211          }
    212       }
    213    }
    214 }
    215 AWKSCRIPT
    216 
    217 # run measurement
    218 cat /proc/uptime /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state >$my_log
    219 if $time
    220 then
    221   time -p $* 2>>$my_log
    222 else
    223   $*
    224 fi
    225 cat /proc/uptime /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state >>$my_log
    226 
    227 # evaluate and debug
    228 $debug && cat $my_log
    229 awk -f $my_awk $args $my_log
    230 
    231 # remove temporary files
    232 rm $my_log $my_awk
    233 
    234