blob: f66a1c4d5ab12df9b0644ec0d0e3440774bd3676 [file] [log] [blame]
#! /usr/bin/env stap
# ------------------------------------------------------------------------
# data collection
# disk I/O stats
probe begin { qnames["ioblock"] ++; qsq_start ("ioblock") }
probe ioblock.request { if (pid && pid() == pid) { qs_wait ("ioblock") qs_run("ioblock") }}
probe ioblock.end { if (pid && pid() == pid) { qs_done ("ioblock") }}
# CPU utilization
probe begin { qnames["cpu"] ++; qsq_start ("cpu") }
probe scheduler.cpu_on { if (pid && pid() == pid) { if (!idle) {qs_wait ("cpu") qs_run ("cpu") }}}
probe scheduler.cpu_off { if (pid && pid() == pid) { if (!idle) qs_done ("cpu") }}
# ------------------------------------------------------------------------
# utilization history tracking
global N, pid, threadstacks, threadcounters, reads, writes
global qnames
global counter
probe begin {
N = 50;
pid = 0;
reads = 0;
writes = 0;
}
function qsq_util_reset(q) {
u=qsq_utilization (q, 100)
qsq_start (q)
return u
}
probe process(@1).function("*").call {
if (pid == 0) {
pid = pid();
}
if (! threadcounters[tid()] ) {
threadstacks[tid()] = probefunc();
}
threadcounters[tid()]++;
}
probe vfs.read.return {
if (pid() == pid) {
if ($return>0) {
reads += $return;
}
}
}
probe vfs.write.return {
if (pid() == pid) {
if ($return>0) {
writes += $return;
}
}
}
probe process(@1).function("*").return {
threadcounters[tid()]--;
if (! threadcounters[tid()]) {
delete(threadcounters[tid()]);
delete(threadstacks[tid()]);
}
}
# ------------------------------------------------------------------------
# general gnuplot graphical report generation
probe timer.ms(50) {
printf("--\n");
printf("%d, %d, %d, %d, %d, %d, %d, %d\n", counter, qsq_util_reset("cpu"), qsq_util_reset("ioblock"), proc_mem_size_pid(pid) * mem_page_size(), proc_mem_data_pid(pid) * mem_page_size(), reads + writes, reads, writes);
foreach (tid in threadcounters) {
printf("%d:%s\n", tid, threadstacks[tid]);
}
reads = 0;
writes = 0;
counter++;
}