我们知道Linux进程分为下面几种状态。

TASK_KILLABLE:The process is sleeping killably.It works like TASK_UNINTERRUPTIBLE with the bonus that it can respond to fatal signals.TASK_UNINTERRUPTIBLE + TASK_WAKEKILL = TASK_KILLABLEThe normal way to put a process to sleep is
to set the process's state to either TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE and call the scheduler's function schedule(). This results in the process getting moved off from
the CPU run queue. If the process is sleeping in interruptible mode (by setting
its state to TASK_INTERRUPTIBLE), it can be awakened either by an explicit wake-up
call (wakeup_process()) or by signals needing processing.
However, if the process is sleeping in
uninterruptible mode (by setting its state to TASK_UNINTERRUPTIBLE), it can only be awakened by an explicit wake-up
call. It is advised to put the processes into interruptible sleep mode rather
than uninterruptible sleep mode unless you really, really need to (such during
device I/O when processing signals is difficult).
在Systrace 中我们常见的状态有R,R+,S ,D ,D|K,R 和R+都是running 或runnable 状态。其他都是sleep 状态。S 是INTERRUPTIBLE的sleep。,D 是UNINTERRUPTIBLE的sleep。D|K 是UNINTERRUPTIBLE的但是可以被killable的sleep。
AudioOut_2-1558 ( 621)
[005] d..3 26071.007774: sched_switch: prev_comm=AudioOut_2 prev_pid=1558
prev_prio=101 prev_state=R
==> next_comm=FastMixer next_pid=1557 next_prio=96
AudioOut_2-1558 ( 621)
[004] d..3 26071.368342: sched_switch: prev_comm=AudioOut_2 prev_pid=1558
prev_prio=101 prev_state=S
==> next_comm=ims_rtp_daemon next_pid=1148 next_prio=120
AudioOut_2-1558 ( 621)
[007] d..3 26071.389107: sched_switch: prev_comm=AudioOut_2 prev_pid=1558
prev_prio=101 prev_state=R+
==> next_comm=cfinteractive next_pid=279 next_prio=0
AudioOut_2-1558 ( 621)
[006] d..3 26071.427973: sched_switch: prev_comm=AudioOut_2 prev_pid=1558
prev_prio=101 prev_state=D
==>
next_comm=logd.writer next_pid=368 next_prio=130
AudioOut_2-1558 ( 621)
[006] d..3 26073.468035: sched_switch: prev_comm=AudioOut_2 prev_pid=1558
prev_prio=101 prev_state=D|K
==> next_comm=qmuxd next_pid=757 next_prio=120
Systrace 状态解析ndroid.launcher-584 [001] d..3 12622.506950: sched_switch: prev_comm=ndroid.launcher prev_pid=584 prev_prio=120 prev_state=R+ ==> next_comm=Binder_1 next_pid=217 next_prio=120
表示即将在cpu1上运行pid 217的binder_1 process。而pid为584的launcher 将sleep。此后PID 为217的process 变为running状态,其runnable的时间为(950-936)ms.
INTERRUPTIBLE Sleep
如果prev_state=R+或S 则其实INTERRUPTIBLE sleep。UNINTERRUPTIBLE Sleep
如果prev_state=D 则其实UNINTERRUPTIBLE sleep。UNINTERRUPTIBLE|KILLABLE Sleep
如果prev_state=D|K则其实UNINTERRUPTIBLE KILLABLE sleep。
Systrace 解析示例
test('importOneSequenceWithSchedWakeUp', function() { var lines = [ 'ndroid.launcher-584 [001] d..3 12622.506890: sched_switch: prev_comm=ndroid.launcher prev_pid=584 prev_prio=120 prev_state=R+ ==> next_comm=Binder_1 next_pid=217 next_prio=120', // @suppress longLineCheck ' Binder_1-217 [001] d..3 12622.506918: sched_switch: prev_comm=Binder_1 prev_pid=217 prev_prio=120 prev_state=D ==> next_comm=ndroid.launcher next_pid=584 next_prio=120', // @suppress longLineCheck 'ndroid.launcher-584 [001] d..4 12622.506936: sched_wakeup: comm=Binder_1 pid=217 prio=120 success=1 target_cpu=001', // @suppress longLineCheck 'ndroid.launcher-584 [001] d..3 12622.506950: sched_switch: prev_comm=ndroid.launcher prev_pid=584 prev_prio=120 prev_state=R+ ==> next_comm=Binder_1 next_pid=217 next_prio=120', // @suppress longLineCheck ' Binder_1-217 [001] ...1 12622.507057: tracing_mark_write: B|128|queueBuffer', // @suppress longLineCheck ' Binder_1-217 [001] ...1 12622.507175: tracing_mark_write: E', ' Binder_1-217 [001] d..3 12622.507253: sched_switch: prev_comm=Binder_1 prev_pid=217 prev_prio=120 prev_state=S ==> next_comm=ndroid.launcher next_pid=584 next_prio=120' // @suppress longLineCheck ];
var m = new tr.Model(lines.join('\n'), false); assert.isFalse(m.hasImportWarnings);
var thread = m.findAllThreadsNamed('Binder_1')[0]; var timeSlices = thread.timeSlices; assert.equal(timeSlices.length, 4);
var runningSlice = timeSlices[0]; assert.equal(runningSlice.title, 'Running'); assert.closeTo(12622506.890, runningSlice.start, 1e-5); assert.closeTo(.918 - .890, runningSlice.duration, 1e-5);
var sleepSlice = timeSlices[1]; assert.equal(sleepSlice.title, 'Uninterruptible Sleep'); assert.closeTo(12622506.918, sleepSlice.start, 1e-5); assert.closeTo(.936 - .918, sleepSlice.duration, 1e-5);
var wakeupSlice = timeSlices[2]; assert.equal(wakeupSlice.title, 'Runnable'); assert.closeTo(12622506.936, wakeupSlice.start, 1e-5); assert.closeTo(.950 - .936, wakeupSlice.duration, 1e-5); assert.equal(wakeupSlice.args['wakeup from tid'], 584);
var runningSlice2 = timeSlices[3]; assert.equal(runningSlice2.title, 'Running'); assert.closeTo(12622506.950, runningSlice2.start, 1e-5); assert.closeTo(7.253 - 6.950, runningSlice2.duration, 1e-5); });