1N/A#!/usr/sbin/dtrace -qs
1N/A/*
1N/A * shortlived.d - determine time spent by short lived processes.
1N/A * Written in DTrace (Solaris 10 3/05).
1N/A *
1N/A * $Id: shortlived.d 3 2007-08-01 10:50:08Z brendan $
1N/A *
1N/A * USAGE: shortlived.d # wait, then hit Ctrl-C
1N/A *
1N/A * Applications that run many short lived processes can cause load
1N/A * on the system that is difficult to identify - the processes
1N/A * aren't sampled in time by programs such as prstat. This program
1N/A * illustrates how much time was spent processing those extra
1N/A * processes, and a table of process name by total times for each.
1N/A *
1N/A * SEE ALSO: execsnoop
1N/A *
1N/A * Notes:
1N/A * - The measurements are minimum values, not all of the overheads
1N/A * caused by process generation and destruction are measured (DTrace
1N/A * can do so, but the script would become seriously complex).
1N/A * - The summary values are accurate, the by program and by PPID values
1N/A * are usually slightly smaller due to rounding errors.
1N/A *
1N/A * COPYRIGHT: Copyright (c) 2005, 2006 Brendan Gregg.
1N/A *
1N/A * CDDL HEADER START
1N/A *
1N/A * The contents of this file are subject to the terms of the
1N/A * Common Development and Distribution License, Version 1.0 only
1N/A * (the "License"). You may not use this file except in compliance
1N/A * with the License.
1N/A *
1N/A * You can obtain a copy of the license at Docs/cddl1.txt
1N/A * or http://www.opensolaris.org/os/licensing.
1N/A * See the License for the specific language governing permissions
1N/A * and limitations under the License.
1N/A *
1N/A * CDDL HEADER END
1N/A *
1N/A * 22-Apr-2005 Brendan Gregg Created this.
1N/A * 20-Apr-2006 " " Last update.
1N/A */
1N/A
1N/A/*
1N/A * Start
1N/A */
1N/Adtrace:::BEGIN
1N/A{
1N/A /* save start time */
1N/A start = timestamp;
1N/A
1N/A /* this is time spent on shortlived processes */
1N/A procs = 0;
1N/A
1N/A /* print header */
1N/A printf("Tracing... Hit Ctrl-C to stop.\n");
1N/A}
1N/A
1N/A/*
1N/A * Measure parent fork time
1N/A */
1N/Asyscall::*fork*:entry
1N/A{
1N/A /* save start of fork */
1N/A self->fork = vtimestamp;
1N/A}
1N/Asyscall::*fork*:return
1N/A/arg0 != 0 && self->fork/
1N/A{
1N/A /* record elapsed time for the fork syscall */
1N/A this->elapsed = vtimestamp - self->fork;
1N/A procs += this->elapsed;
1N/A self->fork = 0;
1N/A}
1N/A
1N/A/*
1N/A * Measure child processes time
1N/A */
1N/Asyscall::*fork*:return
1N/A/arg0 == 0/
1N/A{
1N/A /* save start of child process */
1N/A self->start = vtimestamp;
1N/A
1N/A /* memory cleanup */
1N/A self->fork = 0;
1N/A}
1N/Aproc:::exit
1N/A/self->start/
1N/A{
1N/A /* record elapsed time for process execution */
1N/A this->elapsed = vtimestamp - self->start;
1N/A procs += this->elapsed;
1N/A
1N/A /* sum elapsed by process name and ppid */
1N/A @Times_exec[execname] = sum(this->elapsed/1000000);
1N/A @Times_ppid[ppid] = sum(this->elapsed/1000000);
1N/A
1N/A /* memory cleanup */
1N/A self->start = 0;
1N/A}
1N/A
1N/A/*
1N/A * Print report
1N/A */
1N/Adtrace:::END
1N/A{
1N/A this->total = timestamp - start;
1N/A printf("short lived processes: %6d.%03d secs\n",
1N/A procs/1000000000, (procs%1000000000)/1000000);
1N/A printf("total sample duration: %6d.%03d secs\n",
1N/A this->total/1000000000, (this->total%1000000000)/1000000);
1N/A printf("\nTotal time by process name,\n");
1N/A printa("%18s %@12d ms\n", @Times_exec);
1N/A printf("\nTotal time by PPID,\n");
1N/A printa("%18d %@12d ms\n", @Times_ppid);
1N/A}