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