This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
scheduler script
- From: Jason Baron <jbaron at redhat dot com>
- To: systemtap at sourceware dot org
- Date: Wed, 18 Mar 2009 16:46:33 -0400
- Subject: scheduler script
hi,
script below, takes advantage of the new upstream scheduler tracepoints
to figure out the time a process is waiting, running, sleeping. This
info is currently avaiable if CONFIG_SCHEDSTAT is set, but this script
can be used dynamically. example usage:
$ ./schedule.stp -vvv -gx 5290
....
running: 50876 microseconds
sleeping: 122359706 microseconds
on queue: 9142 microseconds
I'm sure the script could be cleaned up a lot, but I just wanted to show
a hopefully interesting example using the new scheduler tracepoints.
thanks,
-Jason
#!/usr/local/bin/stap
//constants
global RUNNING=0
global QUEUED=1
global SLEEPING=2
global UNINITIALIZED=-1
global traced_pid
global run_time
global queued_time
global sleep_time
global pid_state
global previous_timestamp
global tmp_timestamp
probe kernel.trace("sched_switch") {
if ($prev->pid == traced_pid) {
if (pid_state == UNINITIALIZED) {
//use this state as entry into state machine
previous_timestamp = gettimeofday_us();
if ($prev->state > 0) {
pid_state = SLEEPING;
} else if ($prev->state == 0) {
pid_state = RUNNING;
} else {
printf("unkown transition\n");
}
} else if (pid_state == RUNNING) {
tmp_timestamp = gettimeofday_us();
run_time += (tmp_timestamp - previous_timestamp);
previous_timestamp = tmp_timestamp;
if ($prev->state > 0) {
pid_state = SLEEPING;
} else if ($prev->state == 0) {
pid_state = RUNNING;
} else {
printf("unkown transition\n");
}
} else {
printf("unkown transition\n");
}
}
if ($next->pid == traced_pid) {
if (pid_state == UNINITIALIZED) {
//use this state as entry into state machine
previous_timestamp = gettimeofday_us();
pid_state = RUNNING;
} else if (pid_state == QUEUED) {
tmp_timestamp = gettimeofday_us();
queued_time += (tmp_timestamp - previous_timestamp);
previous_timestamp = tmp_timestamp;
pid_state = RUNNING;
} else {
printf("unkown transition\n");
}
}
}
probe kernel.trace("sched_wakeup") {
if (($p->pid == traced_pid) && $success) {
if (pid_state == UNINITIALIZED) {
//use this state as entry into state machine
previous_timestamp = gettimeofday_us();
pid_state = QUEUED;
} else if (pid_state == SLEEPING) {
tmp_timestamp = gettimeofday_us();
sleep_time += (tmp_timestamp - previous_timestamp);
previous_timestamp = tmp_timestamp;
pid_state = QUEUED;
} else {
printf("unkown transition\n");
}
}
}
probe begin {
traced_pid = target();
run_time = 0;
queued_time = 0;
sleep_time = 0;
pid_state = UNINITIALIZED;
printf("traced pid: %d\n", traced_pid);
}
probe end {
tmp_timestamp = gettimeofday_us();
if (pid_state == SLEEPING)
sleep_time += (tmp_timestamp - previous_timestamp);
if (pid_state == QUEUED)
queued_time += (tmp_timestamp - previous_timestamp);
if (pid_state == RUNNING)
run_time += (tmp_timestamp - previous_timestamp);
printf("running: %d microseconds\n", run_time);
printf("sleeping: %d microseconds\n", sleep_time);
printf("on queue: %d microseconds\n", queued_time);
}