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源代码分析之同优先级任务切换

时间: 2024-08-25 23:56:45

Raw-OS源代码分析之同优先级任务切换的相关文章

Android HandlerThread 源代码分析

HandlerThread 简单介绍: 我们知道Thread线程是一次性消费品,当Thread线程运行完一个耗时的任务之后.线程就会被自己主动销毁了.假设此时我又有一 个耗时任务须要运行,我们不得不又一次创建线程去运行该耗时任务.然而.这样就存在一个性能问题:多次创建和销毁线程是非常耗 系统资源的.为了解这样的问题,我们能够自己构建一个循环线程Looper Thread.当有耗时任务投放到该循环线程中时.线程运行耗 时任务,运行完之后循环线程处于等待状态,直到下一个新的耗时任务被投放进来.这样一

转:RTMPDump源代码分析

0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://.也提供 Android 版本. 最近研究了一下它内部函数调用的关系. 下面列出几个主要的函数的调用关系. RTMPDump用于下载RTMP流媒体的函数Download: 用于建立网络连接(NetConnect)的函数Connect: 用于建立网络流(NetStream)的函数 rtmpdump源代码

【转载】linux环境下tcpdump源代码分析

linux环境下tcpdump源代码分析 原文时间 2013-10-11 13:13:02   原文链接   主题 Tcpdump 作者:韩大卫 @ 吉林师范大学 tcpdump.c 是tcpdump 工具的main.c, 本文旨对tcpdump的框架有简单了解,只展示linux平台使用的一部分核心代码. Tcpdump 的使用目的就是打印出指定条件的报文,即使有再多的正则表达式作为过滤条件.所以只要懂得tcpdump -nXXi eth0 的实现原理即可. 进入main之前,先看一些头文件 n

cocos2d-x 源代码分析 : EventDispatcher、EventListener、Event 源代码分析 (新触摸机制,新的NotificationCenter机制)

源代码版本号来自3.x,转载请注明 cocos2d-x 源代码分析总文件夹 http://blog.csdn.net/u011225840/article/details/31743129 1.继承结构 1.1 结构 不详吐槽太多,也不贴图了.贴图要审核好久好久好久好久. 从小到大,先来看下Event的结构. 1.Event--------EventTouch,EventCustom,EventMouse,EventKeyboard,EventFocus,EventAcceleration 当中

Android应用Activity、Dialog、PopWindow、Toast窗体加入机制及源代码分析

[工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处.尊重劳动成果] 1 背景 之所以写这一篇博客的原因是由于之前有写过一篇<Android应用setContentView与LayoutInflater载入解析机制源代码分析>.然后有人在文章以下评论和微博私信中问我关于Android应用Activity.Dialog.PopWindow载入显示机制是咋回事,所以我就写一篇文章来分析分析吧(本文以Android5.1.1 (API 22)源代码为基础分析),以

Android init源代码分析(1)概要分析

功能概述 init进程是Android内核启动的第一个进程,其进程号(pid)为1,是Android系统所有进程的祖先,因此它肩负着系统启动的重要责任.Android的init源代码位于system/core/init/目录下,伴随Android系统多个版本的迭代,init源代码也几经重构. 目前Android4.4源代码中,init目录编译后生成如下Android系统的三个文件,分别是 /init /sbin/ueventd-->/init /sbin/watchdogd-->/init 其

JAVA随笔篇一(Timer源代码分析和scheduleAtFixedRate的使用)

写完了基础篇,想了非常久要不要去写进阶篇.去写JSP等等的用法.最后决定先不去写.由于自己并非JAVA方面的大牛.眼下也在边做边学,所以决定先将自己不懂的拿出来学并记下来. Timer是Java自带的java.util.Timer类,通过调度一个java.util.TimerTask任务.这样的方式能够让程序依照某一个频度运行. 1.Timer类的源代码分析: public class Timer { /** * The timer task queue. This data structure

Android系统进程Zygote启动过程的源代码分析

原文地址:http://blog.csdn.net/luoshengyang/article/details/6747696 Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口函数是ActivityThread.main,二是进程天然支持Binder进程间通信机制:这两个特点都是在进程的初始化过程中实现的,本文将详细分析Android应用程序进程创建过程中是如何实现这两个特点的. Android应用程序框架层创建的应用程序进程的入口函数是ActivityThread.ma

Spark源代码分析之六:Task调度(二)

话说在<Spark源代码分析之五:Task调度(一)>一文中,我们对Task调度分析到了DriverEndpoint的makeOffers()方法.这种方法针对接收到的ReviveOffers事件进行处理.代码例如以下: // Make fake resource offers on all executors     // 在全部的executors上提供假的资源(抽象的资源.也就是资源的对象信息,我是这么理解的)     private def makeOffers() {       /