| #! /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++; |
| } |