schedule函数主要流程Word格式.docx
- 文档编号:16390875
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:10
- 大小:18.93KB
schedule函数主要流程Word格式.docx
《schedule函数主要流程Word格式.docx》由会员分享,可在线阅读,更多相关《schedule函数主要流程Word格式.docx(10页珍藏版)》请在冰豆网上搜索。
structtask_struct*prev,*next;
10.
unsignedlong*switch_count;
11.
structrq*rq;
12.
intcpu;
13.
14.
need_resched:
15.
preempt_disable();
16.
cpu=smp_processor_id();
17.
rq=cpu_rq(cpu);
/*得到特定cpu的rq*/
18.
rcu_sched_qs(cpu);
19.
prev=rq->
curr;
/*当前的运行进程*/
20.
switch_count=&
prev->
nivcsw;
/*进程切换计数*/
21.
22.
release_kernel_lock(prev);
23.
need_resched_nonpreemptible:
24.
25.
schedule_debug(prev);
26.
27.
if(sched_feat(HRTICK))
28.
hrtick_clear(rq);
29.
30.
spin_lock_irq(&
rq->
lock);
31.
update_rq_clock(rq);
/*更新rq的clock属性*/
32.
clear_tsk_need_resched(prev);
/*清楚prev进程的调度位*/
33.
34.
if(prev->
state&
&
!
(preempt_count()&
PREEMPT_ACTIVE)){
35.
if(unlikely(signal_pending_state(prev->
state,prev)))
36.
prev->
state=TASK_RUNNING;
37.
else/*从运行队列中删除prev进程,根据调度类的
38.
不同,实现不同*/
39.
deactivate_task(rq,prev,1);
40.
nvcsw;
41.
}
42.
/*现只对实时进程有用*/
43.
pre_schedule(rq,prev);
44.
45.
if(unlikely(!
nr_running))
46.
idle_balance(cpu,rq);
47.
/*将当前进程,也就是被切换出去的进程重新
48.
插入到各自的运行队列中,对于CFS算法插入
49.
到合适的位置上,对于实时调度插入到同一个
50.
优先级队列的链表尾部*/
51.
put_prev_task(rq,prev);
52.
/*从各自的运行队列中选择下一个进程来运行*/
53.
next=pick_next_task(rq);
54.
55.
if(likely(prev!
=next)){
56.
/*更新切换出去和进来进程以及对应rq的相关变量*/
57.
sched_info_switch(prev,next);
58.
perf_event_task_sched_out(prev,next,cpu);
59.
60.
rq->
nr_switches++;
/*切换记录*/
61.
curr=next;
62.
++*switch_count;
63.
/*上下文切换,在进程切换已经介绍*/
64.
context_switch(rq,prev,next);
/*unlockstherq*/
65.
/*
66.
*thecontextswitchmighthaveflippedthestackfromunder
67.
*us,hencerefreshthelocalvariables.
68.
*/
69.
70.
71.
}else
72.
spin_unlock_irq(&
73.
/*对于实时进程有用到*/
74.
post_schedule(rq);
75.
76.
if(unlikely(reacquire_kernel_lock(current)<
0))
77.
gotoneed_resched_nonpreemptible;
78.
79.
preempt_enable_no_resched();
80.
if(need_resched())
81.
gotoneed_resched;
82.
对于cpu_rq函数
/*通过向上加偏移的方式得到rq,这里可以看出
runqueues为一个rq结构的数组,cpu为数组下标*/
#definecpu_rq(cpu)
(&
per_cpu(runqueues,(cpu)))
deactivate_task函数实现
*deactivate_task-removeataskfromtherunqueue.
staticvoiddeactivate_task(structrq*rq,structtask_struct*p,intsleep)
if(task_contributes_to_load(p))
nr_uninterruptible++;
/*具体操作*/
dequeue_task(rq,p,sleep);
dec_nr_running(rq);
/*rq中当前进程的运行数减一*/
我们看具体的操作
staticvoiddequeue_task(structrq*rq,structtask_struct*p,intsleep)
if(sleep){/*如果sleep不为0,更新se中相关变量*/
if(p->
se.last_wakeup){
update_avg(&
p->
se.avg_overlap,
p->
se.sum_exec_runtime-p->
se.last_wakeup);
se.last_wakeup=0;
}else{
se.avg_wakeup,
sysctl_sched_wakeup_granularity);
13.
/*更新进程的sched_info数据结构中相关属性*/
sched_info_dequeued(p);
/*调用具体调度类的函数从他的运行队列中删除*/
sched_class->
dequeue_task(rq,p,sleep);
se.on_rq=0;
可见,调用了具体运行队列的删除函数,我们看最关键的选择下一个进程的方式。
[cpp]viewplaincopyprint?
*Pickupthehighest-priotask:
/*以优先级为序,从高到低,一次检查每个调度类
并且从高优先级的调度类中,选择最高优先级的进程
staticinlinestructtask_struct*
pick_next_task(structrq*rq)
conststructsched_class*class;
structtask_struct*p;
12.
*Optimization:
weknowthatifalltasksarein
*thefairclasswecancallthatfunctiondirectly:
if(likely(rq->
nr_running==rq->
cfs.nr_running)){
p=fair_sched_class.pick_next_task(rq);
if(likely(p))
returnp;
21.
22.
class=sched_class_highest;
24.
for(;
;
){/*对每一个调度类*/
p=class->
pick_next_task(rq);
/*调用该调度类中的函数,找出下一个task*/
26.
if(p)
29.
*WillneverbeNULLastheidleclassalways
*returnsanon-NULLp:
/*访问下一个调度类*/
33.
class=class->
next;
可见,对于调度类的选择,同样以优先级进行。
对于进程调度信息的切换最终会调用__sched_info_switch
*Calledwhentasksareswitchedinvoluntarilydue,typically,toexpiring
*theirtimeslice.
(Thismayalsobecalledwhenswitchingtoorfrom
*theidletask.)
Weareonlycalledwhenprev!
=next.
staticinlinevoid
__sched_info_switch(structtask_struct*prev,structtask_struct*next)
structrq*rq=task_rq(prev);
10.
*prevnowdepartsthecpu.
It'
snotinterestingtorecord
*statsabouthowefficientwewereatschedulingtheidle
*process,however.
if(prev!
=rq->
idle)/*如果被切换出去的进程不是idle进程*/
sched_info_depart(prev);
/*更新prev进程和他对应rq的相关变量*/
18.
if(next!
idle)/*如果切换进来的进程不是idle进程*/
sched_info_arrive(next);
/*更新next进程和对应队列的相关变量*/
*Calledwhenaprocessceasesbeingtheactive-runningprocess,either
*voluntarilyorinvoluntarily.
Nowwecancalculatehowlongweran.
*Also,iftheprocessisstillintheTASK_RUNNINGstate,call
*sched_info_queued()tomarkthatithasnowagainstartedwaitingon
*therunqueue.
staticinlinevoidsched_info_depart(structtask_struct*t)
/*计算在进程在rq中运行的时间长度*/
unsignedlonglongdelta=task_rq(t)->
clock-
t->
sched_info.last_arrival;
/*更新RunQueue中的Task所得到CPU执行
时间的累加值。
*/
rq_sched_info_depart(task_rq(t),delta);
16.
/*如果被切换出去进程的状态是运行状态
那么将进程sched_info.last_queued设置为rq的clock
last_queued为最后一次排队等待运行的时间*/
if(t->
stat
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- schedule 函数 主要 流程