我们知道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); });