主调度器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, ...
随机推荐
- .net 微信Token验证
首次接受这个项目,看了微信的API,云里雾里,经过几经测试,理清思路 开发者自个申请,微信API给出四个参数: 下面我解释下 signature 是微信加密签名 即:微信服务器将 timetamp n ...
- 页面获取不到spring实例化services解决方法
WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext(); DaoSupport dao= (Da ...
- java框架篇---Struts入门
首先理解Struts与MVC的关系 在传统的MVC模式中所有的请求都要先交给Servlet处理,之后由Servlet调用JavaBean,并将结果交给JSP中进行显示.结构图如下 Struts是Apa ...
- ViewController之间的转场和数据传递
ViewController之间的转场和数据传递 可以正向传递值, 反向传递值. 注意反向传值的时候,方法的位置: https://github.com/urmyfaith/GRDBUsage/blo ...
- 【WPF】屏幕右下角消息提示框
WPF做一个仿QQ的右下角消息提示窗,网上找到几个Demo后,选了一个比较好用的. 博客 http://blog.csdn.net/huangli321456/article/details/5052 ...
- js 控制输入文字的字数
直接上代码. <html> <head> </head> <body> <textarea id='txtArea' cols='50' rows ...
- 【Java集合源码剖析】Hashtable源码剖析
转载出处:http://blog.csdn.net/ns_code/article/details/36191279 Hashtable简介 Hashtable同样是基于哈希表实现的,同样每个元素是一 ...
- node学习笔记2——搭建服务器
搭建服务器关键词: require('http') —— 请求 node 里面的 http 模块 createServer —— 创建一个服务器 request —— 请求 response—— 响应 ...
- CSS非ASCII字符最佳实践
问题场景 在写样式时经常需要用到非ASCII字符的属性值,如下: ? 1 2 3 4 5 6 7 8 9 10 11 .hot_list .sign_discount:before { cont ...
- 【转】如果有人让你推荐Python技术书,请让他看这个列表
入门级 <Head First Python>+ 入门级 + 微信49票 + 豆瓣评分 9.5 推荐语: 66:浅显易懂,编排的顺序特别,有大量插图.对话,不感觉枯燥 古心:通熟易懂,配有 ...