1 #!/usr/bin/sh 2 # 3 # cputimes - print CPU time consumed by Kernel/Idle/Processes. 4 # Written using DTrace (Solaris 10 3/05). 5 # 6 # $Id: cputimes,v 1.1.1.1 2015/09/30 22:01:09 christos Exp $ 7 # 8 # This program accurately measures time consumed by the kernel, but in 9 # doing so creates extra kernel load of it's own. The extra kernel 10 # activity can be measured by running one cputimes and then another, and 11 # comparing the difference in kernel consumed time. This method can be 12 # used to estimate the load created by other DTrace scripts. 13 # 14 # USAGE: cputimes [-ahTV] [-t top] [interval [count]] 15 # 16 # -a # print all processes 17 # -T # print totals 18 # -V # don't print timestamps 19 # -t num # print top num lines only 20 # eg, 21 # cputimes 1 # print every 1 second 22 # cputimes -a 10 # print all processes every 10 secs 23 # cputimes -at 8 5 # print top 8 lines every 5 secs 24 # 25 # 26 # FIELDS: 27 # THREADS The following or the process name, 28 # IDLE Idle time - CPU running idle thread 29 # KERNEL Kernel time - Kernel servicing interrupts, ... 30 # PROCESS Process time - PIDs running on the system 31 # TIME (ns) Sum of the CPU time, ns (nanoseconds) 32 # 33 # NOTES: 34 # * This takes into account multiple CPU servers, the total 35 # seconds consumed will be a multiple of the CPU count and interval. 36 # 37 # SEE ALSO: cpudists 38 # Heisenberg's uncertainty principle. 39 # 40 # COPYRIGHT: Copyright (c) 2005 Brendan Gregg. 41 # 42 # CDDL HEADER START 43 # 44 # The contents of this file are subject to the terms of the 45 # Common Development and Distribution License, Version 1.0 only 46 # (the "License"). You may not use this file except in compliance 47 # with the License. 48 # 49 # You can obtain a copy of the license at Docs/cddl1.txt 50 # or http://www.opensolaris.org/os/licensing. 51 # See the License for the specific language governing permissions 52 # and limitations under the License. 53 # 54 # CDDL HEADER END 55 # 56 # Author: Brendan Gregg [Sydney, Australia] 57 # 58 # 27-Apr-2005 Brendan Gregg Created this. 59 # 22-Sep-2005 " " Fixed a key corruption bug. 60 # 22-Sep-2005 " " Last update. 61 # 62 63 64 ############################## 65 # --- Process Arguments --- 66 # 67 opt_all=0; opt_time=1; opt_top=0; opt_totals=0 68 top=0; interval=1; count=1 69 70 while getopts aht:TV name 71 do 72 case $name in 73 a) opt_all=1 ;; 74 T) opt_totals=1 ;; 75 V) opt_time=0 ;; 76 t) opt_top=1; top=$OPTARG ;; 77 h|?) cat <<-END >&2 78 USAGE: cputimes [-ahTV] [-t top] [interval [count]] 79 cputimes # default output 80 -a # print all processes 81 -T # print totals 82 -V # don't print times 83 -t num # print top num lines only 84 eg, 85 cputimes 1 # print every 1 second 86 cputimes -a 10 # all processes per 10 sec 87 cputimes -at 8 5 # top 8 lines every 5 secs 88 END 89 exit 1 90 esac 91 done 92 shift `expr $OPTIND - 1` 93 94 if [ "$1" -gt 0 ]; then 95 interval=$1; count=-1; shift 96 fi 97 if [ "$1" -gt 0 ]; then 98 count=$1; shift 99 fi 100 101 102 ################################# 103 # --- Main Program, DTrace --- 104 # 105 /usr/sbin/dtrace -n ' 106 #pragma D option quiet 107 108 /* 109 * Command line arguments 110 */ 111 inline int OPT_all = '$opt_all'; 112 inline int OPT_time = '$opt_time'; 113 inline int OPT_totals = '$opt_totals'; 114 inline int OPT_top = '$opt_top'; 115 inline int TOP = '$top'; 116 inline int INTERVAL = '$interval'; 117 inline int COUNTER = '$count'; 118 119 /* Initialise variables */ 120 dtrace:::BEGIN 121 { 122 cpustart[cpu] = 0; 123 counts = COUNTER; 124 secs = INTERVAL; 125 } 126 127 /* Flag this thread as idle */ 128 sysinfo:unix:idle_enter:idlethread 129 { 130 idle[cpu] = 1; 131 } 132 133 /* Save kernel time between running threads */ 134 sched:::on-cpu 135 /cpustart[cpu]/ 136 { 137 this->elapsed = timestamp - cpustart[cpu]; 138 @Procs["KERNEL"] = sum(this->elapsed); 139 } 140 141 /* Save the elapsed time of a thread */ 142 sched:::off-cpu, 143 sched:::remain-cpu, 144 profile:::profile-1sec 145 /cpustart[cpu]/ 146 { 147 /* determine the name for this thread */ 148 program[cpu] = pid == 0 ? idle[cpu] ? "IDLE" : "KERNEL" : 149 OPT_all ? execname : "PROCESS"; 150 151 /* save elapsed */ 152 this->elapsed = timestamp - cpustart[cpu]; 153 @Procs[program[cpu]] = sum(this->elapsed); 154 cpustart[cpu] = timestamp; 155 } 156 157 /* Record the start time of a thread */ 158 sched:::on-cpu, 159 sched:::remain-cpu 160 { 161 idle[cpu] = 0; 162 cpustart[cpu] = timestamp; 163 } 164 165 166 profile:::tick-1sec 167 { 168 secs--; 169 } 170 171 /* Print time */ 172 profile:::tick-1sec 173 /secs == 0/ 174 { 175 OPT_time ? printf("%Y,\n", walltimestamp) : 1; 176 printf("%16s %16s\n", "THREADS", "TIME (ns)"); 177 } 178 179 /* Print report */ 180 profile:::tick-1sec 181 /secs == 0/ 182 { 183 OPT_top ? trunc(@Procs, TOP) : 1; 184 printa("%16s %@16d\n", @Procs); 185 trunc(@Procs); 186 secs = INTERVAL; 187 counts--; 188 } 189 190 /* End of program */ 191 profile:::tick-1sec 192 /counts == 0/ 193 { 194 exit(0); 195 } 196 197 /* cleanup for Ctrl-C */ 198 dtrace:::END 199 { 200 trunc(@Procs); 201 } 202 ' 203 204