#!/usr/sbin/dtrace -Cs /* #pragma D option aggsize=10000000000 #pragma D option aggrate=10000000000 */ #pragma D option dynvarsize=100000000 #define CALLS 1 long long runtime; BEGIN { start = timestamp; } /* trace CPU time in each function */ #ifdef CALLS #define DoCalls @calls[probefunc] = sum(1); #else #define DoCalls ; #endif #define myprobes(funcs, keyid) \ self int probe_/**/keyid; \ self int stamp_/**/keyid; \ \ pid$1::funcs:entry \ /self->probe_/**/keyid++ == 0/ \ { \ self->stamp_/**/keyid = vtimestamp; \ DoCalls ; \ } \ \ pid$1::funcs:return \ /self->probe_/**/keyid > 0 && self->probe_/**/keyid-- == 1/ \ { \ @runtime[$funcs] = sum(vtimestamp - self->stamp_/**/keyid); \ self->stamp_/**/keyid = 0; \ } myprobes($2,2) myprobes($3,3) myprobes($4,4) myprobes($5,5) myprobes($6,6) sched:::on-cpu /pid == $1/ { self->on = vtimestamp; } sched:::off-cpu /pid == $1 && self->on != 0/ { this->mytime = vtimestamp; @runtime["Total process"] = sum(this->mytime - self->on); runtime += (this->mytime - self->on); self->on = 0; } END { end = timestamp; seconds = (end - start) / 1000000000; @["Time elapsed (s)"] = sum(seconds); printf("\nTotal stats\n"); printa(@); #ifdef CALLS printf("\nTotal function calls :\n"); printa(@calls); #endif printf("\nCPU time (us):\n"); normalize(@runtime, 1000); printa(@runtime); printf("\nStats - per second\n"); normalize(@, seconds); printa(@); #ifdef CALLS printf("\nFunction calls - per second\n"); normalize(@calls, seconds); printa(@calls); #endif printf("\nCPU time (us) - per second :\n"); normalize(@runtime, seconds*1000); printa(@runtime); printf("\nCPU time (us) - per CPU second :\n"); normalize(@runtime, (runtime/1000000)); printa(@runtime); }