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