]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - cddl/contrib/dtracetoolkit/Kernel/cputimes
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / cddl / contrib / dtracetoolkit / Kernel / cputimes
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 3 2007-08-01 10:50:08Z brendan $
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