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