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