1*c29d5175Schristos#!/usr/bin/sh 2*c29d5175Schristos# 3*c29d5175Schristos# cputimes - print CPU time consumed by Kernel/Idle/Processes. 4*c29d5175Schristos# Written using DTrace (Solaris 10 3/05). 5*c29d5175Schristos# 6*c29d5175Schristos# $Id: cputimes,v 1.1.1.1 2015/09/30 22:01:09 christos Exp $ 7*c29d5175Schristos# 8*c29d5175Schristos# This program accurately measures time consumed by the kernel, but in 9*c29d5175Schristos# doing so creates extra kernel load of it's own. The extra kernel 10*c29d5175Schristos# activity can be measured by running one cputimes and then another, and 11*c29d5175Schristos# comparing the difference in kernel consumed time. This method can be 12*c29d5175Schristos# used to estimate the load created by other DTrace scripts. 13*c29d5175Schristos# 14*c29d5175Schristos# USAGE: cputimes [-ahTV] [-t top] [interval [count]] 15*c29d5175Schristos# 16*c29d5175Schristos# -a # print all processes 17*c29d5175Schristos# -T # print totals 18*c29d5175Schristos# -V # don't print timestamps 19*c29d5175Schristos# -t num # print top num lines only 20*c29d5175Schristos# eg, 21*c29d5175Schristos# cputimes 1 # print every 1 second 22*c29d5175Schristos# cputimes -a 10 # print all processes every 10 secs 23*c29d5175Schristos# cputimes -at 8 5 # print top 8 lines every 5 secs 24*c29d5175Schristos# 25*c29d5175Schristos# 26*c29d5175Schristos# FIELDS: 27*c29d5175Schristos# THREADS The following or the process name, 28*c29d5175Schristos# IDLE Idle time - CPU running idle thread 29*c29d5175Schristos# KERNEL Kernel time - Kernel servicing interrupts, ... 30*c29d5175Schristos# PROCESS Process time - PIDs running on the system 31*c29d5175Schristos# TIME (ns) Sum of the CPU time, ns (nanoseconds) 32*c29d5175Schristos# 33*c29d5175Schristos# NOTES: 34*c29d5175Schristos# * This takes into account multiple CPU servers, the total 35*c29d5175Schristos# seconds consumed will be a multiple of the CPU count and interval. 36*c29d5175Schristos# 37*c29d5175Schristos# SEE ALSO: cpudists 38*c29d5175Schristos# Heisenberg's uncertainty principle. 39*c29d5175Schristos# 40*c29d5175Schristos# COPYRIGHT: Copyright (c) 2005 Brendan Gregg. 41*c29d5175Schristos# 42*c29d5175Schristos# CDDL HEADER START 43*c29d5175Schristos# 44*c29d5175Schristos# The contents of this file are subject to the terms of the 45*c29d5175Schristos# Common Development and Distribution License, Version 1.0 only 46*c29d5175Schristos# (the "License"). You may not use this file except in compliance 47*c29d5175Schristos# with the License. 48*c29d5175Schristos# 49*c29d5175Schristos# You can obtain a copy of the license at Docs/cddl1.txt 50*c29d5175Schristos# or http://www.opensolaris.org/os/licensing. 51*c29d5175Schristos# See the License for the specific language governing permissions 52*c29d5175Schristos# and limitations under the License. 53*c29d5175Schristos# 54*c29d5175Schristos# CDDL HEADER END 55*c29d5175Schristos# 56*c29d5175Schristos# Author: Brendan Gregg [Sydney, Australia] 57*c29d5175Schristos# 58*c29d5175Schristos# 27-Apr-2005 Brendan Gregg Created this. 59*c29d5175Schristos# 22-Sep-2005 " " Fixed a key corruption bug. 60*c29d5175Schristos# 22-Sep-2005 " " Last update. 61*c29d5175Schristos# 62*c29d5175Schristos 63*c29d5175Schristos 64*c29d5175Schristos############################## 65*c29d5175Schristos# --- Process Arguments --- 66*c29d5175Schristos# 67*c29d5175Schristosopt_all=0; opt_time=1; opt_top=0; opt_totals=0 68*c29d5175Schristostop=0; interval=1; count=1 69*c29d5175Schristos 70*c29d5175Schristoswhile getopts aht:TV name 71*c29d5175Schristosdo 72*c29d5175Schristos case $name in 73*c29d5175Schristos a) opt_all=1 ;; 74*c29d5175Schristos T) opt_totals=1 ;; 75*c29d5175Schristos V) opt_time=0 ;; 76*c29d5175Schristos t) opt_top=1; top=$OPTARG ;; 77*c29d5175Schristos h|?) cat <<-END >&2 78*c29d5175Schristos USAGE: cputimes [-ahTV] [-t top] [interval [count]] 79*c29d5175Schristos cputimes # default output 80*c29d5175Schristos -a # print all processes 81*c29d5175Schristos -T # print totals 82*c29d5175Schristos -V # don't print times 83*c29d5175Schristos -t num # print top num lines only 84*c29d5175Schristos eg, 85*c29d5175Schristos cputimes 1 # print every 1 second 86*c29d5175Schristos cputimes -a 10 # all processes per 10 sec 87*c29d5175Schristos cputimes -at 8 5 # top 8 lines every 5 secs 88*c29d5175Schristos END 89*c29d5175Schristos exit 1 90*c29d5175Schristos esac 91*c29d5175Schristosdone 92*c29d5175Schristosshift `expr $OPTIND - 1` 93*c29d5175Schristos 94*c29d5175Schristosif [ "$1" -gt 0 ]; then 95*c29d5175Schristos interval=$1; count=-1; shift 96*c29d5175Schristosfi 97*c29d5175Schristosif [ "$1" -gt 0 ]; then 98*c29d5175Schristos count=$1; shift 99*c29d5175Schristosfi 100*c29d5175Schristos 101*c29d5175Schristos 102*c29d5175Schristos################################# 103*c29d5175Schristos# --- Main Program, DTrace --- 104*c29d5175Schristos# 105*c29d5175Schristos/usr/sbin/dtrace -n ' 106*c29d5175Schristos #pragma D option quiet 107*c29d5175Schristos 108*c29d5175Schristos /* 109*c29d5175Schristos * Command line arguments 110*c29d5175Schristos */ 111*c29d5175Schristos inline int OPT_all = '$opt_all'; 112*c29d5175Schristos inline int OPT_time = '$opt_time'; 113*c29d5175Schristos inline int OPT_totals = '$opt_totals'; 114*c29d5175Schristos inline int OPT_top = '$opt_top'; 115*c29d5175Schristos inline int TOP = '$top'; 116*c29d5175Schristos inline int INTERVAL = '$interval'; 117*c29d5175Schristos inline int COUNTER = '$count'; 118*c29d5175Schristos 119*c29d5175Schristos /* Initialise variables */ 120*c29d5175Schristos dtrace:::BEGIN 121*c29d5175Schristos { 122*c29d5175Schristos cpustart[cpu] = 0; 123*c29d5175Schristos counts = COUNTER; 124*c29d5175Schristos secs = INTERVAL; 125*c29d5175Schristos } 126*c29d5175Schristos 127*c29d5175Schristos /* Flag this thread as idle */ 128*c29d5175Schristos sysinfo:unix:idle_enter:idlethread 129*c29d5175Schristos { 130*c29d5175Schristos idle[cpu] = 1; 131*c29d5175Schristos } 132*c29d5175Schristos 133*c29d5175Schristos /* Save kernel time between running threads */ 134*c29d5175Schristos sched:::on-cpu 135*c29d5175Schristos /cpustart[cpu]/ 136*c29d5175Schristos { 137*c29d5175Schristos this->elapsed = timestamp - cpustart[cpu]; 138*c29d5175Schristos @Procs["KERNEL"] = sum(this->elapsed); 139*c29d5175Schristos } 140*c29d5175Schristos 141*c29d5175Schristos /* Save the elapsed time of a thread */ 142*c29d5175Schristos sched:::off-cpu, 143*c29d5175Schristos sched:::remain-cpu, 144*c29d5175Schristos profile:::profile-1sec 145*c29d5175Schristos /cpustart[cpu]/ 146*c29d5175Schristos { 147*c29d5175Schristos /* determine the name for this thread */ 148*c29d5175Schristos program[cpu] = pid == 0 ? idle[cpu] ? "IDLE" : "KERNEL" : 149*c29d5175Schristos OPT_all ? execname : "PROCESS"; 150*c29d5175Schristos 151*c29d5175Schristos /* save elapsed */ 152*c29d5175Schristos this->elapsed = timestamp - cpustart[cpu]; 153*c29d5175Schristos @Procs[program[cpu]] = sum(this->elapsed); 154*c29d5175Schristos cpustart[cpu] = timestamp; 155*c29d5175Schristos } 156*c29d5175Schristos 157*c29d5175Schristos /* Record the start time of a thread */ 158*c29d5175Schristos sched:::on-cpu, 159*c29d5175Schristos sched:::remain-cpu 160*c29d5175Schristos { 161*c29d5175Schristos idle[cpu] = 0; 162*c29d5175Schristos cpustart[cpu] = timestamp; 163*c29d5175Schristos } 164*c29d5175Schristos 165*c29d5175Schristos 166*c29d5175Schristos profile:::tick-1sec 167*c29d5175Schristos { 168*c29d5175Schristos secs--; 169*c29d5175Schristos } 170*c29d5175Schristos 171*c29d5175Schristos /* Print time */ 172*c29d5175Schristos profile:::tick-1sec 173*c29d5175Schristos /secs == 0/ 174*c29d5175Schristos { 175*c29d5175Schristos OPT_time ? printf("%Y,\n", walltimestamp) : 1; 176*c29d5175Schristos printf("%16s %16s\n", "THREADS", "TIME (ns)"); 177*c29d5175Schristos } 178*c29d5175Schristos 179*c29d5175Schristos /* Print report */ 180*c29d5175Schristos profile:::tick-1sec 181*c29d5175Schristos /secs == 0/ 182*c29d5175Schristos { 183*c29d5175Schristos OPT_top ? trunc(@Procs, TOP) : 1; 184*c29d5175Schristos printa("%16s %@16d\n", @Procs); 185*c29d5175Schristos trunc(@Procs); 186*c29d5175Schristos secs = INTERVAL; 187*c29d5175Schristos counts--; 188*c29d5175Schristos } 189*c29d5175Schristos 190*c29d5175Schristos /* End of program */ 191*c29d5175Schristos profile:::tick-1sec 192*c29d5175Schristos /counts == 0/ 193*c29d5175Schristos { 194*c29d5175Schristos exit(0); 195*c29d5175Schristos } 196*c29d5175Schristos 197*c29d5175Schristos /* cleanup for Ctrl-C */ 198*c29d5175Schristos dtrace:::END 199*c29d5175Schristos { 200*c29d5175Schristos trunc(@Procs); 201*c29d5175Schristos } 202*c29d5175Schristos' 203*c29d5175Schristos 204