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# 22-Sep-2005, ver 0.73 (check for newer versions) 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# 52 53 54############################## 55# --- Process Arguments --- 56# 57opt_all=0; opt_time=1; opt_top=0; top=0; interval=1; count=1 58 59while getopts aht:V name 60do 61 case $name in 62 a) opt_all=1 ;; 63 V) opt_time=0 ;; 64 t) opt_top=1; top=$OPTARG ;; 65 h|?) cat <<-END >&2 66 USAGE: cpudists [-ahV] [-t top] [interval [count]] 67 cpudists # default output 68 -a # print all processes 69 -V # don't print times 70 -t num # print top num only 71 END 72 exit 1 73 esac 74done 75shift `expr $OPTIND - 1` 76 77if [ "$1" -gt 0 ]; then 78 interval=$1; count=-1; shift 79fi 80if [ "$1" -gt 0 ]; then 81 count=$1; shift 82fi 83 84 85################################# 86# --- Main Program, DTrace --- 87# 88/usr/sbin/dtrace -n ' 89 #pragma D option quiet 90 91 /* 92 * Command line arguments 93 */ 94 inline int OPT_all = '$opt_all'; 95 inline int OPT_time = '$opt_time'; 96 inline int OPT_top = '$opt_top'; 97 inline int TOP = '$top'; 98 inline int INTERVAL = '$interval'; 99 inline int COUNTER = '$count'; 100 101 /* Initialise variables */ 102 dtrace:::BEGIN 103 { 104 cpustart[cpu] = 0; 105 counts = COUNTER; 106 secs = INTERVAL; 107 } 108 109 /* Flag this thread as idle */ 110 sysinfo:unix:idle_enter:idlethread 111 { 112 idle[cpu] = 1; 113 } 114 115 /* Save kernel time between running threads */ 116 sched:::on-cpu 117 /cpustart[cpu]/ 118 { 119 this->elapsed = timestamp - cpustart[cpu]; 120 @Procs["KERNEL"] = quantize(this->elapsed); 121 } 122 123 /* Save the elapsed time of a thread */ 124 sched:::off-cpu, 125 sched:::remain-cpu, 126 profile:::profile-1sec 127 /cpustart[cpu]/ 128 { 129 /* determine the name for this thread */ 130 program[cpu] = pid == 0 ? idle[cpu] ? "IDLE" : "KERNEL" : 131 OPT_all ? execname : "PROCESS"; 132 133 /* save elapsed */ 134 this->elapsed = timestamp - cpustart[cpu]; 135 @Procs[program[cpu]] = quantize(this->elapsed); 136 cpustart[cpu] = timestamp; 137 } 138 139 /* Record the start time of a thread */ 140 sched:::on-cpu, 141 sched:::remain-cpu 142 { 143 idle[cpu] = 0; 144 cpustart[cpu] = timestamp; 145 } 146 147 profile:::tick-1sec 148 { 149 secs--; 150 } 151 152 /* Print time */ 153 profile:::tick-1sec 154 /secs == 0 && OPT_time/ 155 { 156 printf("%Y,\n", walltimestamp); 157 } 158 159 /* Print report */ 160 profile:::tick-1sec 161 /secs == 0/ 162 { 163 OPT_top ? trunc(@Procs, TOP) : 1; 164 printa("%16s %@16d\n", @Procs); 165 trunc(@Procs); 166 secs = INTERVAL; 167 counts--; 168 } 169 170 /* End of program */ 171 profile:::tick-1sec 172 /counts == 0/ 173 { 174 exit(0); 175 } 176 177 /* cleanup for Ctrl-C */ 178 dtrace:::END 179 { 180 trunc(@Procs); 181 } 182' 183 184