主调度器schedule
中断处理完毕后,系统有三种执行流向:
1)直接返回中断前的状态;
2)系统重新进行调度;
3)进行信号处理;
我们此处重点关注:在用户态下发生scheduler_tick,且已判定当前进程可被抢占的情形(此处以ARM为例)。
__irq_usr:
#......
b ret_to_user_from_irq ENTRY(ret_to_user_from_irq)
ldr r1, [tsk, #TI_FLAGS]
#define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
tst r1, #_TIF_WORK_MASK ;判定是否有信号需要处理,或者被抢占
bne work_pending
#......
ENDPROC(ret_to_user_from_irq) work_pending:
mov r0, sp @ 'regs'
mov r2, why @ 'syscall'
bl do_work_pending
#......
当do_work_pending中检查thread_info的flags知道当前进程可被抢占时,则启动主调度器schedule
schedule()----prev = rq->curr 但前运行进程
|----next = pick_next_task(rq) 选择下一运行进程
|---->context_switch(rq, prev, next)
context_switch()---->prepare_task_switch(rq, prev, next)
| 更新prev,next的进程信息统计量
|----mm = next->mm; 取得即将被调度进入的进程的内存描述符
|----oldmm = prev->active_mm;
| 取得即将被调度出去的进程的运行时内存描述符。
| 此时需要区分即将被调入的进程是普通进程还是内核线程;
| 被调出的进程是普通进程还是内核线程;
| 引入active_mm的目的在于实现 lazy TLB
| (当我们把运行的进程个数限于2个,一个是普通进程
| 另一个是内核线程时就容易明白了)。
|
| 我们讨论普通情形:即将被调入调出的进程都为普通进程,
| 且oldmm与mm不同,需要切换内存页表。
|----switch_mm(oldmm, mm, next);
| 切换页表,刷TLB (注意假设oldmm与mm不同)
| 对于vivt型cache需要注意对cache的操作
|----switch_to(prev, next, prev);
| cpu_context_save切换(运行到next进程)
| 对于unicore保存r4-r15,r16-r26,
| r27(fp),r29(sp),r30(lr)
| 不需保存r0-r3,r31(pc),r28(ip)
|----finish_task_switch(this_rq(), prev);
| 对被调度出的进程进行相关处理
|---->mmdrop(mm);
更新prev,next的进程信息统计量(注意exec_start,prev_sum_exec_runtime)
prepare_task_switch(rq, prev, next)
|---->sched_info_switch(prev, next)
#ifdef CONFIG_SCHEDSTATS
|----__sched_info_switch(prev, next)
|---->sched_info_depart(prev)
|----prev->sched_info.last_queued = task_rq(t)->clock;
|---->sched_info_arrive(next)
|----t->sched_info.run_delay +=
now - t->sched_info.last_queued;
|----t->sched_info.last_queued = ;
|----t->sched_info.last_arrival = now;
#endif
pick_next_task()---->p = fair_sched_class.pick_next_task(rq);
| 即pick_next_task_fair()
|---->se = pick_next_entity(cfs_rq);
|---- set_next_entity(cfs_rq, se);
|---->update_stats_curr_start(cfs_rq, se);
| 即se->exec_start =
rq_of(cfs_rq)->clock_task;
|---- cfs_rq->curr = se;
|---- se->prev_sum_exec_runtime =
se->sum_exec_runtime;
关于switch_to(prev, next, prev)
《深入Linux架构》p_83-84,83页上的图看懂了,但是84页第三段“因此……”没看明白,和同学讨论了一下:
A->B->C->A,第二次调度进A运行时,确实需要知道上次运行的是C,以便调用finish_task_switch(),其实自己理解错误的原因很低级(只顾着看汇编,自己想多了):
函数UP中有变量a、b,函数UP调用LOW(a,b),很明显UP中的a值没有被改变,如果要改变,则需要a = LOW(a,b);
当然我们也可以用传地址的方式来完成啊,当我尝试用传地址的方式来修改UP中的变量a时,发现我们需要保存即将恢复的进程中a的地址才能在下次运行时通过地址来修改a的值,这并不明智,因此对于unicore或ARM来说通过r0来返回值进而赋值是很好的选择。
主调度器schedule的更多相关文章
- Linux进程核心调度器之主调度器schedule--Linux进程的管理与调度(十九)
主调度器 在内核中的许多地方, 如果要将CPU分配给与当前活动进程不同的另一个进程, 都会直接调用主调度器函数schedule, 从系统调用返回后, 内核也会检查当前进程是否设置了重调度标志TLF_N ...
- 一个简单的Python调度器Schedule
关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...
- 调度器的实现、schedule、switch_context、switch_to
根据<深入Linux内核架构>和Linux-3.10.1内核源码,记一些调度过程的主体工作. 调度器任务:CPU数目比要运行的进程数目少,需要程序之间共享CPU时间,创造并行执行的错觉.分 ...
- linux cfs调度器_理论模型
参考资料:<调度器笔记>Kevin.Liu <Linux kernel development> <深入Linux内核架构> version: 2.6.32.9 下 ...
- Linux核心调度器之周期性调度器scheduler_tick--Linux进程的管理与调度(十八)
我们前面提到linux有两种方法激活调度器:核心调度器和 周期调度器 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测是否有必要 因 ...
- cocos2d调度器(定时执行某函数)
调度器(scheduler) 继承关系 原理介绍 Cocos2d-x调度器为游戏提供定时事件和定时调用服务.所有Node对象都知道如何调度和取消调度事件,使用调度器有几个好处: 每当Node不再可见或 ...
- (5)调度器(scheduler)
继承关系 原理介绍 Cocos2d-x调度器为游戏提供定时事件和定时调用服务.所有Node对象都知道如何调度和取消调度事件,使用调度器有几个好处: 每当Node不再可见或已从场景中移除时,调度器会停止 ...
- Erlang/OTP 17.0-rc1 新引入的"脏调度器"浅析
最近在做一些和 NIF 有关的事情,看到 OTP 团队发布的 17 rc1 引入了一个新的特性“脏调度器”,为的是解决 NIF 运行时间过长耗死调度器的问题.本文首先简单介绍脏调度器机制的用法,然后简 ...
- 【Cocos2d-x 3.x】 调度器Scheduler类源码分析
非个人的全部理解,部分摘自cocos官网教程,感谢cocos官网. 在<CCScheduler.h>头文件中,定义了关于调度器的五个类:Timer,TimerTargetSelector, ...
随机推荐
- spring batch中MyBatisPagingItemReader分页使用介绍
假如是mysql的话,SQL语句 <![CDATA[select * from ( SELECT so.* FROM t_tm_sales_order so where so.last_modi ...
- postgresql相关命令
1,打开命令窗口: 2,查看数据库用户:\du 3,列出所有数据库名:\l或者SELECT datname FROM pg_database; 4,切换某个数据库下面的某个用户下面:\c 数据库名 用 ...
- iOS开发中的火星坐标系及各种坐标系转换算法
原文地址:http://m.oschina.net/blog/619183?ref=myread 其原理是这样的:保密局开发了一个系统,能将实际的坐标转换成虚拟的坐标.所有在中国销售的数字地图必须使用 ...
- order by name 注入
order by name id id是一个注入点 可以利用if语句进行注入 order by name ,if(1=1,1,select 1 from information_schema.tabl ...
- 解决Eclipse异常关闭后重启报 org.eclipse.swt.SWTException: Invalid thread access 的问题
. . . . . 很久没有写博客了,最近实在是太忙,一直想写点干货,但是一直没静下心来学习. 今天又在加班忙碌之中,结果谁知道越忙碌越出问题.先是 weblogic 没有正常启动,凭经验第一反应就是 ...
- junit import org.junit.Test 报错
由于用的是父-子项目 在自项目中各种改都不行,还是报错,而且子项目中明明已经导入了还在报错,后面发现是父项目中的scope是test 注释掉就好了
- 火狐FireFox57不支持Tab Mix Plus插件的问题
火狐的Tab Mix Plus插件管理标签页很好用,但是在这次升级到57版本后不能用了,也没找到合适的替代品. 该插件一个很常用的功能是在新建的标签页打开网页(而不是在当前页上跳转),该功能直接修改C ...
- zookeeper学习:知识点收集
其实学习zookeeper挺简单的,找一本书或者网上的资源,按照其中的例子做一遍就大致了解了.之前是自己学习的方法有问题. 1. 会启动单机版的服务器,并使用客户端连接,然后进行节点的各种操作 2. ...
- <悟道一位IT高管20年的职场心经>笔记
1. 你一定会在某个时候惊讶地发现,原来当初你曾经硬着头皮挨过来的日子对你是那么的珍贵.2. "'老板就是老板'.这一点,你可能会忘,他一定不会忘.'老板不会总是老板'.这一点,他可能会忘, ...
- [ADC]TI am4378 ADC采样设置问题(am335x类似)
这段时间在调试AM4378的ADC问题,发现采样到的数据和真实输入波形有所出入,比如输入是1ms的周期,50%占空比的信号,但是采样的数据描点总是偏差较大,数据如下 iio device number ...