cpudists revision 1.1 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 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