schedule()函数的调用时机(周期性调度)
今天纠正了一个由来已久的认识错误:一个进程的时间片用完之后,当再次发生时钟中断时内核会调用schedule()来进行调度,把当前的进程上下文切出CPU,并把选定的下一个进程切换进来运行。我一直以为schedule()函数是在时钟中断处理函数中被调用的。其实不是,如果真是这样的话,那么在第一次这样的调度完成之后,时钟中断可能就要被mute掉了,系统从此失去“心跳”。
我之前那样理解是基于这样两点考虑:
- 在时钟中断发生时会更新进程的时间片(对于CFS调度器来说,就是更新进程的虚拟运行时间virtual run-time)。 更新完这个时间信息之后,立刻运行schedule()顺理成章,调度就应该在这个时机发生;
- 中断发生之后,(以arm架构为例)系统会从IRQ模式迅速切换成SVC模式,并且在此后的中断处理过程中,中断是关闭的,只有在切换回USR模式(其中还经过IRQ模式)时,才回再把中断打开。如果在中断处理函数中调用schedule()并不会带来中断无法再次打开的问题,因为最后总是要切换到USR模式的,那时时钟中断也总是有机会能重新打开的。
但是我没有注意到一个问题,就是ARM中断控制器(VIC)的mask/unmask操作。在进入中断响应函数之前,需要先对相应的中断设计掩码,即把正在处理的这个中断mask掉,在响应完后再把它unmask回来,好让中断能够继续发生。这段代码在kernel/irq/chip.c中(以下是经简化的示例代码):
void handle_level_irq(unsigned int irq, struct irq_desc *desc)
{
......
mask_ack_irq(desc, irq);
......
action_ret = handle_IRQ_event(irq, action);
......
unmask_irq(desc, irq);
......
}
注:中断的mask/unmask与enable/disable是两个层次的概念:enable/disable是对所有中断而言,如果disable的话任何中断都不会发生;而mask/unmask是对一个特定的中断而言的,mask之后,指定的中断不会再发生了,但并不影响其它的中断。
所以,基于这种设计,在中断响应过程中,只能更新进程的时间片,却不可以进行调度。如果一旦在上述的handle_IRQ_event()里面调用了schedule()函数,就会立刻切换到其它进程(SVC模式,内核态),接下来的unmask_irq()执行不到,时钟中断就再也没有机会打开。切换到下一个进程之后,因为没有时钟中断,系统也就失去了心跳。
正确的方法是在中断处理快要结束时调用schedule():
在中断处理的汇编代码中(arm架构下主要看__irq_usr),主要的中断处理过程都完成之后,会跑到ret_to_user处准备返回用户模式。这时就会检查进程的thread_info结构中是否置有“_TIF_NEED_RESCHED”标志,如果是的话,说明需要进行进程调度,这时再调用函数schedule()。在这个时间点上,中断控制器中相应的位已经被unmask过,接下来只要开中断即可。
上面提到的汇编代码比较零散,这里就不贴了,都在文件arch/arm/kernel/entry-armv.S和entry-common.S中。
schedule()函数的调用时机(周期性调度)的更多相关文章
- MFC浅析(7) CWnd类虚函数的调用时机、缺省实现
CWnd类虚函数的调用时机.缺省实现 FMD(http://www.fmdstudio.net) 1. Create 2. PreCreateWindow 3. PreSubclassWindow 4 ...
- CWnd类虚函数的调用时机、缺省实现
MFC(VC6.0)的CWnd及其子类中,有如下三个函数: class CWnd : public CCmdTarget{ public: virtual BOOL PreCrea ...
- Linux CFS调度器之task_tick_fair处理周期性调度器--Linux进程的管理与调度(二十九)
1. CFS如何处理周期性调度器 周期性调度器的工作由scheduler_tick函数完成(定义在kernel/sched/core.c, line 2910), 在scheduler_tick中周期 ...
- Linux核心调度器之周期性调度器scheduler_tick--Linux进程的管理与调度(十八)
我们前面提到linux有两种方法激活调度器:核心调度器和 周期调度器 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测是否有必要 因 ...
- Direct3D Draw函数 异步调用原理解析
概述 在D3D10中,一个基本的渲染流程可分为以下步骤: 清理帧缓存: 执行若干次的绘制: 通过Device API创建所需Buffer: 通过Map/Unmap填充数据到Buffer中: 将Buff ...
- Spring AOP在函数接口调用性能分析及其日志处理方面的应用
面向切面编程可以实现在不修改原来代码的情况下,增加我们所需的业务处理逻辑,比如:添加日志.本文AOP实例是基于Aspect Around注解实现的,我们需要在调用API函数的时候,统计函数调用的具体信 ...
- 驱动:中断【2】中断处理程序、中断上下文中处理延时及一些函数的调用规则(调IIC中断驱动有感)
中断处理程序.中断上下文中处理延时及一些函数的调用规则(调IIC中断驱动有感)http://blog.csdn.net/samantha_sun/article/details/6790492 1,中 ...
- (copy)赋值构造函数的4种调用时机or方法
第一种调用方法: demo #include <iostream> using namespace std; class Text { public: Text() // 无参数构造函数 ...
- 周期性调度器scheduler_tick
周期性调度器由中断实现,系统定时产生一个中断,然后启动周期性调度器,周期性调度器执行过程中要关闭中断, 周期性调度器执行完毕后再打开中断(handle_IRQ_event, IRQF_DISABLE ...
随机推荐
- 圣魔大战3(Castle Fantisia)艾伦希亚战记完美攻略
作为城堡幻想曲系列续作,艾伦希亚战记继承了前作的战棋+养成模式进行游戏. (城堡幻想曲3,纠正大家个错误哦,不是圣魔大战3,圣魔大战是城堡幻想曲2,圣魔大战不是个系列,艾伦西亚战记==艾伦希亚战记,一 ...
- Android TextView自己主动换行文字排版參差不齐的原因
今天项目没什么进展,公司后台出问题了.看了下刚刚学习Android时的笔记,发现TextView会自己主动换行,并且排版文字參差不齐.查了下资料,总结原因例如以下: 1.半角字符与全角字符混乱所致:这 ...
- 微信jssdk已无力吐槽
微信强大的整合能力让企业公众号的开发迅速窜红.尤其是企业须要个性化定制的一些功能.公司在同一时候上线的app和触屏版的应用中,微信分享自然是不可或缺的重要一环. 纵观如今大多数的微信公众号.分享大都是 ...
- Expert for SQL Server 诊断系列
Expert for SQL Server 诊断系列 Expert 诊断优化系列------------------锁是个大角色 前面几篇已经陆续从服务器的几个大块讲述了SQL SERVER数据库 ...
- Jenkins快速搭建持续集成
基于Jenkins快速搭建持续集成环境 Jenkins+tortoisesvn+MSBuild做到持续集成 附Jenkins的使用:http://www.infoq.com/cn/articles/M ...
- FireMonkey Style Designer
http://docwiki.embarcadero.com/RADStudio/Berlin/en/FireMonkey_Style_Designer http://docwiki.embarcad ...
- RAD路线规划2016版
http://community.embarcadero.com/article/news/16211-embarcadero-rad-studio-2016-product-approach-and ...
- Android开发系列(二十八):使用SubMenu创建选项菜单
大部分手机上边都会有一个"MENU"键,在一个应用安装到手机上之后,能够通过"MENU"显示该应用关联的菜单. 可是,从Android 3.0開始,Androi ...
- JSP自定义标签——简单标签(1)
前面一篇博客介绍了自定义标签的传统标签使用方式,但是我们会发现,使用传统标签非常的麻烦,而且接口还多,现在传统标签基本都没用了,除了一些比较久的框架.Sun公司之后推出了一个新的标签使用方式,称之为简 ...
- 【ASP.NET Web API教程】3.2 通过.NET客户端调用Web API(C#)
原文:[ASP.NET Web API教程]3.2 通过.NET客户端调用Web API(C#) 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的 ...