Raw-OS源代码分析之同优先级任务切换
分析的内核版本号截止到2014-04-15,基于1.05正式版,blogs会及时跟进最新版本号的内核开发进度,若源代码凝视出现”???”字样,则是未深究理解部分。
Raw-OS官方站点:http://www.raw-os.org/
Raw-OS托管地址:https://github.com/jorya/raw-os/
1.同优先级任务轮转
比如,系统中创建有两个同样优先级任务Task A和Task B,而且已经增加到就绪队列。
当Task A时间片用完时,由于同优先级,会被系统调度至就绪队列的末尾,那么Task B就開始执行,当Task B时间片耗尽时,相同也会被系统调度至就绪队列末尾,由此,系统调度时实现相同优先级的轮转。
2.系统计数的内核实现
一般对于OS来说,都会有一个系统时钟节拍,来提供系统计数用途,并且,这个系统计数是专门用一个中断来实现,所以在非常多芯片架构都会专门分开tick和timer的外设,至于系统计数,是移植相关的部分,在Raw-OS官网提供的移植都包含这个部分,所以不须要阁下去做
硬件移植依据Raw-OS的宏配置文件设置tick间隔,初始化芯片外设,这里关心的是内核实现。
在系统时钟中断服务函数中,重点关注的是raw_time_tick()函数,至于由task 0推送事件,临时还没研究过,所以在内核宏配置我是先不去实现,一般的固定写法是:
void tick_isr(){
/* 中断ISR进入,进入中断时必须先调用 */
raw_enter_interrupt();
/* 宏配置中先不要实现task 0,还没研究过源代码,不懂怎么去解释??? */
#ifdef (CONFIG_RAW_TASK_0 == 1)
/* task 0 转发??? */
task_0_tick_post();
#else
/* 调用系统时间tick处理函数 */
raw_time_tick();
#endif
/* 中断ISR退出,退出中断时必须配套raw_enter_interrupt()使用,这里可能发生中断任务切换 */
raw_finish_int();
}
那么raw_time_tick()函数就干以下的事
看着源代码凝视消化一下吧~码字确实是非常累的事情,但尼玛抠图是更累的事情~
RAW_VOID raw_time_tick(void)
{
/* 开启task0宏后,不能在中断调用该函数???要使用task_0_post??? */
#if (CONFIG_RAW_TASK_0 > 0)
if (raw_int_nesting) {
RAW_ASSERT(0);
}
#endif /* 移植相关,调用tick的hook函数 */
#if (CONFIG_RAW_USER_HOOK > 0)
raw_tick_hook();
#endif #if (CONFIG_RAW_TICK_TASK > 0)
/*
* 在raw_os_init(),依据宏配置会选择是否把tick封装成任务,若封装成任务则会建
* 立一个优先级别为1的任务,而且在任务函数中堵塞在tick_task_obj的信号量上
*
* 假设tick计数为单独一个任务时,在这里释放tick任务信号量,在调度后立即执行tick task
* 终于调用tick_list_update()更新tick list
*/
raw_task_semaphore_put(&tick_task_obj);
#else
/* 假设tick计数不作为一个单独任务,直接更新tick list */
tick_list_update();
#endif /* 计算更新任务轮转时间片 */
#if (CONFIG_SCHED_FIFO_RR > 0)
calculate_time_slice(raw_task_active->priority);
#endif /* 通知软件定时器任务更新信息,用于处理系统创建的软件定时器部分 */
#if (CONFIG_RAW_TIMER > 0)
call_timer_task();
#endif
}
那么,终于发生计算任务超时事件实现同优先级轮转会发生在calculate_time_slice()函数中,直接看凝视的源代码:
void calculate_time_slice(RAW_U8 task_prio)
{
RAW_TASK_OBJ *task_ptr;
LIST *head; RAW_SR_ALLOC();
/* 获取就绪hash表中最高优先级的就绪链表头 */
head = &raw_ready_queue.task_ready_list[task_prio]; RAW_CRITICAL_ENTER(); /* 就绪链表中没有就绪任务时,返回,这样的情况怎么发生??? */
if (is_list_empty(head)) { RAW_CRITICAL_EXIT();
return;
} /*
* 当前就绪链表头的下一个元素就是第一个就绪任务,这个任务同一时候也是最高优先级任务
* 通过list_entry获取任务控制块地址
*/
task_ptr = list_entry(head->next, RAW_TASK_OBJ, task_list); /* 假设任务是FIFO调度,则不须要计算时间 */
if (task_ptr->sched_way == SCHED_FIFO) { RAW_CRITICAL_EXIT();
return;
} /*
这里推断获取最高优先级就绪链表中是否仅仅有一个任务,假设是,返回,
说明仅仅有一个最高优先级任务时,永远执行这个任务,由于没有同样优先级作为轮转操作
注:IDLE任务必须满足这个条件
*/
if (head->next->next == head) { RAW_CRITICAL_EXIT();
return; } /* 当前任务时间片减1 */
if (task_ptr->time_slice) {
task_ptr->time_slice--;
} /* 当前任务时间片不为0,返回,即任务时间片未消耗完,返回 */
if (task_ptr->time_slice) {
RAW_CRITICAL_EXIT();
return;
} /*
* 任务时间片为0后,将当前执行的任务转移到同优先级别的就绪链表的表尾
* 原来在这里实现同优先级任务的轮转
*/
move_to_ready_list_end(&raw_ready_queue, task_ptr); /* 加入到表尾时重置该任务的时间片,等待下次调度时有原来设置的时间片 */
task_ptr->time_slice = task_ptr->time_total; RAW_CRITICAL_EXIT();
}
最后能够总结了,每一次系统tick都会产生一个中断,然后在tick isr中更新系统时钟,和做一些其它有关须要用到系统时间的操作,对于本节讨论的同优先级任务轮转,会终于在tick isr中更新就绪队列来实现,至于完整地实现更新就绪队列,系统调度,在下节连同系统中断架构一起解说
Raw-OS源代码分析之同优先级任务切换的更多相关文章
- Android HandlerThread 源代码分析
HandlerThread 简单介绍: 我们知道Thread线程是一次性消费品,当Thread线程运行完一个耗时的任务之后.线程就会被自己主动销毁了.假设此时我又有一 个耗时任务须要运行,我们不得不又 ...
- 转:SDL2源代码分析
1:初始化(SDL_Init()) SDL简介 有关SDL的简介在<最简单的视音频播放示例7:SDL2播放RGB/YUV>以及<最简单的视音频播放示例9:SDL2播放PCM>中 ...
- 转:RTMPDump源代码分析
0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...
- 【转载】linux环境下tcpdump源代码分析
linux环境下tcpdump源代码分析 原文时间 2013-10-11 13:13:02 CSDN博客 原文链接 http://blog.csdn.net/han_dawei/article/d ...
- Hadoop源代码分析
http://wenku.baidu.com/link?url=R-QoZXhc918qoO0BX6eXI9_uPU75whF62vFFUBIR-7c5XAYUVxDRX5Rs6QZR9hrBnUdM ...
- linux环境下tcpdump源代码分析
Linux 环境下tcpdump 源代码分析 韩大卫@吉林师范大学 tcpdump.c 是tcpdump 工具的main.c, 本文旨对tcpdump的框架有简单了解,只展示linux平台使用的一部分 ...
- Android系统进程Zygote启动过程的源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6768304 在Android系统中,所有的应用 ...
- Android应用程序进程启动过程的源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址: http://blog.csdn.net/luoshengyang/article/details/6747696 Android 应用程序框架层创 ...
- Android应用程序绑定服务(bindService)的过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6745181 Android应用程序组件Serv ...
随机推荐
- 【hdoj_1133】Buy the Ticket(卡特兰数+大数)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1133 题目的意思是,m个人只有50元钱,n个人只有100元整钱,票价50元/人.现在售票厅没钱,只有50元 ...
- Spring 中Bean的装配方式
最近又买了一本介绍SSM框架的书,是由黑马程序员编写的,书上讲的很好理解,边看边总结一下.主要总结一下bean的装配方式. Bean的装配可以理解为依赖系统注入,Bean的装配方式即Bean依赖注入的 ...
- [VBA]批量替换PPT里的字体颜色
不知道为什么计组老师的大量课件字体是伤害视力的亮蓝色……看久了眼睛疼,想把颜色替换成保护视力一点的灰色,但是找了N久也没找到在图形界面上直接操作的方法,于是在MSDN上晃了晃,Google了一下,写了 ...
- yii2 GirdView使用全教程
开始GridView GridView主要是为了实现表格复用,尤其我们做后台的时候,你发现表单和表格占据了大部分页面,而表格的样式又是高度的统一,那么如果有这样一个挂件,传入数据集自动渲染表格该多好. ...
- 移动端禁止图片长按和vivo手机点击img标签放大图片,禁止长按识别二维码或保存图片【转载】
移动端禁止图片长按和vivo手机点击img标签放大图片,禁止长按识别二维码或保存图片 img{ pointer-events: none; } 源文地址:https://www.cnblogs.com ...
- Robot Framework自动化测试的应用
Robot Framework自动化测试的应用(一) 最近尝试用Robot Framework代替之前全部采用python实现测试case,开始对Robot Framework进行些了解学习. 1. ...
- 【Spark亚太研究院系列丛书】Spark实战高手之路-第2章动手实战Scala第3小节:动手实战Scala函数式编程(2)
3,动手实战Scala中的泛型 泛型泛型类和泛型方法,也就是我们实例化类或者调用方法的时候可以指定其类型,由于Scala的泛型和Java的泛型是一致的,这里不再赘述. 4,动手实战Scala中的隐式转 ...
- 几道坑人的PHP面试题 试试看看你会不会也中招
这篇文章主要介绍了几道坑人的PHP面试题,试试看看你会不会也中招,这些题目都用了一些障眼法,需要你有一双火眼金睛哦,需要的朋友可以参考下 这几道题是在德问上看到的,感觉挺有意思,拿来给大家分享其中的陷 ...
- 转:Linux创建进程
转:http://www.cnblogs.com/GT_Andy/archive/2011/06/21/2086129.html 我们都知道,进程就是正在执行的程序.而在Linux中,可以使用一个进程 ...
- LibreOJ#143 质数判定 [Miller_Rabin]
题目传送门 质数判定 题目描述 判定输入的数是不是质数. 输入格式 若干行,一行一个数 x. 行数不超过 $1.5\times 10^4$ 输出格式 对于输入的每一行,如果 x是质数输出一行 Y,否则 ...