cputimes revision 1.1.1.1 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:06 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