#!/usr/bin/sh # # cpudists - print CPU time distributions by Kernel/Idle/Processes. # Written using DTrace (Solaris 10 3/05). # # 22-Sep-2005, ver 0.73 (check for newer versions) # # USAGE: cpudists [-ahV] [-t top] [interval [count]] # # -a # print all processes # -V # don't print timestamps # -t num # print top num only # eg, # cpudists 1 # print every 1 second # cpudists -a 10 # print all processes every 10 secs # # # FIELDS: # value The following or the process name, # IDLE Idle time - CPU running idle thread # KERNEL Kernel time - Kernel servicing interrupts, ... # PROCESS Process time - PIDs running on the system # count Number of occurances at least this duration (ns) # # NOTES: # * This takes into account multiple CPU servers, the total # seconds consumed will be a multiple of the CPU count and interval. # # SEE ALSO: cputimes # # COPYRIGHT: Copyright (c) 2005 Brendan Gregg. # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # You can obtain a copy of the license at Docs/cddl1.txt # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # CDDL HEADER END # # Author: Brendan Gregg [Sydney, Australia] # # 27-Apr-2005 Brendan Gregg Created this. # 22-Sep-2005 " " Fixed key corruption bug. # ############################## # --- Process Arguments --- # opt_all=0; opt_time=1; opt_top=0; top=0; interval=1; count=1 while getopts aht:V name do case $name in a) opt_all=1 ;; V) opt_time=0 ;; t) opt_top=1; top=$OPTARG ;; h|?) cat <<-END >&2 USAGE: cpudists [-ahV] [-t top] [interval [count]] cpudists # default output -a # print all processes -V # don't print times -t num # print top num only END exit 1 esac done shift `expr $OPTIND - 1` if [ "$1" -gt 0 ]; then interval=$1; count=-1; shift fi if [ "$1" -gt 0 ]; then count=$1; shift fi ################################# # --- Main Program, DTrace --- # /usr/sbin/dtrace -n ' #pragma D option quiet /* * Command line arguments */ inline int OPT_all = '$opt_all'; inline int OPT_time = '$opt_time'; inline int OPT_top = '$opt_top'; inline int TOP = '$top'; inline int INTERVAL = '$interval'; inline int COUNTER = '$count'; /* Initialise variables */ dtrace:::BEGIN { cpustart[cpu] = 0; counts = COUNTER; secs = INTERVAL; } /* Flag this thread as idle */ sysinfo:unix:idle_enter:idlethread { idle[cpu] = 1; } /* Save kernel time between running threads */ sched:::on-cpu /cpustart[cpu]/ { this->elapsed = timestamp - cpustart[cpu]; @Procs["KERNEL"] = quantize(this->elapsed); } /* Save the elapsed time of a thread */ sched:::off-cpu, sched:::remain-cpu, profile:::profile-1sec /cpustart[cpu]/ { /* determine the name for this thread */ program[cpu] = pid == 0 ? idle[cpu] ? "IDLE" : "KERNEL" : OPT_all ? execname : "PROCESS"; /* save elapsed */ this->elapsed = timestamp - cpustart[cpu]; @Procs[program[cpu]] = quantize(this->elapsed); cpustart[cpu] = timestamp; } /* Record the start time of a thread */ sched:::on-cpu, sched:::remain-cpu { idle[cpu] = 0; cpustart[cpu] = timestamp; } profile:::tick-1sec { secs--; } /* Print time */ profile:::tick-1sec /secs == 0 && OPT_time/ { printf("%Y,\n", walltimestamp); } /* Print report */ profile:::tick-1sec /secs == 0/ { OPT_top ? trunc(@Procs, TOP) : 1; printa("%16s %@16d\n", @Procs); trunc(@Procs); secs = INTERVAL; counts--; } /* End of program */ profile:::tick-1sec /counts == 0/ { exit(0); } /* cleanup for Ctrl-C */ dtrace:::END { trunc(@Procs); } '