|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /usr/share/doc/systemtap-client-1.8/examples/process/ |
Upload File : |
#!/usr/bin/stap
############################################################
# Schedtimes.stp
#
# Copyright (C) 2009 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
# Author: Jason Baron <jbaron@redhat.com>
# profiles threads and displays their run times, queued times,
# wait times, including i/o wait times.
# Has two modes. When no arguments are given it profiles all
# threads. Alternatively, you can pass -c "program name"
############################################################
//constants
global RUNNING=0, QUEUED=1, SLEEPING=2
global traced_pid
global run_time, queued_time, sleep_time, io_wait_time
global pid_state, pid_names
global previous_timestamp
global io_wait_count
global io_wait_incremented
function get_iowait:long(queue:long)
{
return @cast(queue,"rq","kernel")->nr_iowait->counter;
}
probe kernel.trace("sched_switch") {
previous_pid = $prev->pid;
next_pid = $next->pid;
if (traced_pid) {
if (previous_pid != traced_pid) {
previous_pid = 0;
}
if (next_pid != traced_pid) {
next_pid = 0;
}
}
if (previous_pid) {
if (!([previous_pid] in pid_state)) {
//use this state as entry into state machine
previous_timestamp[previous_pid] = gettimeofday_us();
pid_names[previous_pid] = kernel_string($prev->comm);
if ($prev->state > 0) {
pid_state[previous_pid] = SLEEPING;
} else if ($prev->state == 0) {
pid_state[previous_pid] = QUEUED;
} else {
printf("unknown transition:\n");
printf("pid state: %d our state: %d\n",
$prev->state, pid_state[previous_pid]);
}
} else if (pid_state[previous_pid] == RUNNING) {
pid_names[previous_pid] = kernel_string($prev->comm);
t = gettimeofday_us();
run_time[previous_pid] += (t - previous_timestamp[previous_pid]);
previous_timestamp[previous_pid] = t;
if ($prev->state > 0) {
if (@defined($rq) && (get_iowait($rq) - io_wait_count[previous_pid]) > 0)
io_wait_incremented[previous_pid] = 1;
pid_state[previous_pid] = SLEEPING;
} else if ($prev->state == 0) {
pid_state[previous_pid] = QUEUED;
} else {
printf("unknown transition:\n");
printf("pid state: %d our state: %d\n",
$prev->state, pid_state[previous_pid]);
}
} else {
printf("unknown transition:\n");
printf("%s pid state: %d our state: %d\n",
pid_names[previous_pid],
$prev->state, pid_state[previous_pid]);
}
}
if (next_pid) {
if (@defined($rq))
io_wait_count[next_pid] = get_iowait($rq);
if (!([next_pid] in pid_state)) {
//use this state as entry into state machine
previous_timestamp[next_pid] = gettimeofday_us();
pid_state[next_pid] = RUNNING;
pid_names[next_pid] = kernel_string($next->comm);
} else if (pid_state[next_pid] == QUEUED) {
t = gettimeofday_us();
queued_time[next_pid] += (t - previous_timestamp[next_pid]);
previous_timestamp[next_pid] = t;
pid_state[next_pid] = RUNNING;
pid_names[next_pid] = kernel_string($next->comm);
} else {
printf("unknown transition:\n");
printf("%s pid state: %d our state: %d\n",
pid_names[next_pid],
$next->state, pid_state[next_pid]);
}
}
}
probe kernel.trace("sched_wakeup") {
wakeup_pid = $p->pid;
if (traced_pid && (wakeup_pid != traced_pid)) next
if ((!$success) && (pid_state[wakeup_pid] != SLEEPING)) next
if (!wakeup_pid) next
if (!([wakeup_pid] in pid_state)) {
//use this state as entry into state machine
previous_timestamp[wakeup_pid] = gettimeofday_us();
pid_state[wakeup_pid] = QUEUED;
pid_names[wakeup_pid] = kernel_string($p->comm);
} else if (pid_state[wakeup_pid] == SLEEPING) {
t = gettimeofday_us();
sleep_time[wakeup_pid] += (t - previous_timestamp[wakeup_pid]);
if (io_wait_incremented[wakeup_pid] == 1) {
io_wait_time[wakeup_pid] += (t - previous_timestamp[wakeup_pid]);
io_wait_incremented[wakeup_pid] = 0;
}
previous_timestamp[wakeup_pid] = t;
pid_state[wakeup_pid] = QUEUED;
pid_names[wakeup_pid] = kernel_string($p->comm);
} else {
printf("unknown transition:\n");
printf("pid state: %d our state: %d\n",
$p->state, pid_state[wakeup_pid]);
}
}
probe begin {
traced_pid = target();
if (traced_pid == 0) {
printf("all mode\n");
} else {
printf("target mode\n");
printf("traced pid: %d\n", traced_pid);
}
}
probe end {
t = gettimeofday_us();
foreach (pid in pid_state) {
if (pid_state[pid] == SLEEPING)
sleep_time[pid] += (t - previous_timestamp[pid]);
if (pid_state[pid] == QUEUED)
queued_time[pid] += (t - previous_timestamp[pid]);
if (pid_state[pid] == RUNNING)
run_time[pid] += (t - previous_timestamp[pid]);
}
printf ("%16s: %6s %10s %10s %10s %10s %10s\n\n",
"execname", "pid", "run(us)", "sleep(us)", "io_wait(us)",
"queued(us)", "total(us)")
foreach (pid+ in run_time) {
printf("%16s: %6d %10d %10d %10d %10d %10d\n",
pid_names[pid], pid, run_time[pid], sleep_time[pid],
io_wait_time[pid], queued_time[pid],
(run_time[pid] + sleep_time[pid] + queued_time[pid]));
}
}