4 #Initially inspired by Systemtap schedtimes.stp
5 #and more bugfree compare with Systemtap's version
7 #Note that the time value is associate with pid, not with execname strictly,
8 #sometime you will found there have sleep time for command "ls", the reason
9 #is that sleep time is belong to parent process bash, so clear on this.
26 trace sched:sched_switch {
27 local prev_comm = arg1
29 local prev_state = arg4
30 local next_comm = arg5
32 local t = gettimeofday_us()
34 if (pid_state[prev_pid] == nil) {
36 } elseif (pid_state[prev_pid] == RUNNING) {
37 run_time[prev_pid] += t - prev_timestamp[prev_pid]
38 } elseif (pid_state[prev_pid] == QUEUED) {
40 #sched_wakeup comm=foo
41 #sched_switch prev_comm=foo
42 run_time[prev_pid] += t - prev_timestamp[prev_pid]
45 pid_names[prev_pid] = prev_comm
46 prev_timestamp[prev_pid] = t
48 if (prev_state == DEAD) {
49 pid_state[prev_pid] = DEAD
50 } elseif (prev_state > 0) {
51 if (in_iowait() == 1) {
54 pid_state[prev_pid] = SLEEPING
55 } elseif (prev_state == 0) {
56 pid_state[prev_pid] = QUEUED
59 if (pid_state[next_pid] == nil) {
60 pid_state[next_pid] = RUNNING
61 } elseif (pid_state[next_pid] == QUEUED) {
62 queued_time[next_pid] += t - prev_timestamp[next_pid]
63 pid_state[next_pid] = RUNNING
66 pid_names[next_pid] = next_comm
67 prev_timestamp[next_pid] = t
70 trace sched:sched_wakeup, sched:sched_wakeup_new {
72 local wakeup_pid = arg2
74 local t = gettimeofday_us()
76 if (pid_state[wakeup_pid] == nil) {
78 } elseif (pid_state[wakeup_pid] == SLEEPING) {
79 local durtion = t - prev_timestamp[wakeup_pid]
81 sleep_time[wakeup_pid] += durtion
82 if (io_wait[wakeup_pid] == 1) {
83 io_wait_time[wakeup_pid] += durtion
84 io_wait[wakeup_pid] = 0
86 } elseif (pid_state[wakeup_pid] == RUNNING) {
90 pid_names[wakeup_pid] = comm
91 prev_timestamp[wakeup_pid] = t
92 pid_state[wakeup_pid] = QUEUED
96 local t = gettimeofday_us()
98 for (pid, state in pairs(pid_state)) {
99 local durtion = t - prev_timestamp[pid]
100 if (state == SLEEPING) {
101 sleep_time[pid] += durtion
102 } elseif (state == QUEUED) {
103 queued_time[pid] += durtion
104 } elseif (state == RUNNING) {
105 run_time[pid] += durtion
109 printf ("%16s: %6s %10s %10s %10s %10s %10s\n\n",
110 "execname", "pid", "run(us)", "sleep(us)", "io_wait(us)",
111 "queued(us)", "total(us)")
113 for (pid, time in pairs(run_time)) {
114 if (sleep_time[pid] == nil) {
117 if (queued_time[pid] == nil) {
120 printf("%16s: %6d %10d %10d %10d %10d %10d\n",
121 pid_names[pid], pid, run_time[pid], sleep_time[pid],
122 io_wait_time[pid], queued_time[pid],
123 run_time[pid] + sleep_time[pid] + queued_time[pid]);