This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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);
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]