实时调度内核 内核是什么意思

工具类服务
编辑部专用服务
作者专用服务
一种新的实时系统内核调度算法研究设计
随着网络技术的发展,嵌入式系统与网络通信结合的越来越紧密,嵌入式实时操作系统既要满足系统实时性的要求又要满足网络通信服务质量。在内核调度过程中既要快速响应系统的实时任务,又要兼容网络传输特性。在嵌入式操作系统的基础上引入网络协议栈成为了嵌入式系统发展的必然趋势。  
本文对内核调度算法进行深入的分析,对其中的UCOS-II(MicroC/OS-II)嵌入式实时操作系统进行深入研究,结合网络传输特性提出了新的内核调度策略。  
本文的主要内容如下:  
1)本文提出了一种内核调度算法新的调度算法结合任务优先级的调度算法与时间片的调度算法的优点,实现任务Id的自动管理,为用户提供了友好方便的接口函数。有效的弥补了原UCOS-II 任务数量较少,同优先级不支持多个任务以及不支持优先级继承等缺陷。实验表明在网络传输环境中新的内核调度算法效率有明显的改善。  
2)对UCOS-II 动态内存管理策略改进UCOS-II 提供的动态内存管理策略过于简单,对内存的利用效率较低。本文对其内存动态管理策略进行改进,实现可变大小的动态内存管理策略,用户可以根据自己的需求申请任意大小的内存块,内存释放后自动合并,系统为用户提供了方便稳定的接口函数。  
3)在新的嵌入式内核的基础上开发无线抄表系统网络协议栈本文在无线抄表系统硬件基础上,完成新内核的移植、底层驱动程序的开发以及网络协议栈的开发。整个协议栈分为5 层,与传统的TCP/IP 协议相融合。  
协议栈实现兼容IPv6的网络协议,底层数据可靠收发、自动组网、动态路由等功能。本文在无线抄表系统软硬件平台基础上,进行无线抄表系统通信测试,并对测试结果进行分析。经过多次测试,系统具有良好的性能,完全满足国家的相关约定。采用新的内核,系统效率得到了很大的提高。
学科专业:
授予学位:
学位授予单位:
导师姓名:
学位年度:
在线出版日期:
本文读者也读过
相关检索词
万方数据知识服务平台--国家科技支撑计划资助项目(编号:2006BAH03B01)(C)北京万方数据股份有限公司
万方数据电子出版社实时和Linux之二:抢占式内核
康华:计算机硕士,主要从事Linux操作系统内核、Linux技术标准、计算机安全、软件测试等领域的研究与开发工作,现信息产业部软件与集成电路促进中心所属的MII-HP Linux软件实验室。如果需要可以联系通过联系他。
Kevin 将继续他的实时之旅,这次他要着重分析如何通过改造Linux内核来为应用程序带来实时性能。
在2002年的1-2月发行的嵌入Linux月刊中,我们探讨了有关实时和Linux的基础问题。而这次我将精力花在改造Linux内核来为应用程序带来实时性能这个主题上。到目前为止,工作的重心集中在提高内核响应速度——通过减少抢占响应时间缩短系统响应时间,因为我们知道抢占响应时间在Linux中耗时较长。
通过改进内核——仅仅是剔除一些标准内核的功能——并不去改变或增加内核API,应用程序就可以获得更快的响应速度。这样做优势明显,因为ISVs(独立软件开发商)不需要为不同的实时要求开发不同版本的系统。比如,DVD播放器可以在一个改进过的内核上更稳定的运行,而它不必知道该内核是经过改进的版本。
背景和历史
自2.2版本内核发布以来,内核抢占成为一个热门话题。Paul Barton-Davis 和 Benno Senoner曾给Linus
Torvalds写了一封信(该信后来追加了许多人的签名),请求在2.4版本内核中显著降低抢占延迟时间。
他们需要Linux性能上能满足播放音频、音乐以及MIDI的要求。Senoner开发了一套基准软件(benchmarking
software)测试2.2版本内核(以及后来的2.4版本),在最坏情况下发现抢占延迟高达100毫秒(参考)。 对于音频应用程序来说,这么长的延迟时间显然是无法接受的。因为经验显示系统响应时间只有在几毫秒内才能满足音频应用程序的需要。
有两个补丁包为内核提供了相当不错的抢占响应速度提升。Ingo Molnar (来自 Red Hat) 和 Andrew Morton (来自Wollongong大学)
两人都开发了内核补丁,这些补丁为内核中长代码路径片段插入了抢占点。你可以在这里这里发现Ingo Molnar的补丁包 ,或在这里找到Andrew Morton的补丁包。
另外,Morton还提供了测量响应速度的工具,比如测量内核忽视请求时间长度等,有关详细信息在他的快速响应补丁网站上可以找到。
目前,至少有两个组织开发了抢占式内核,为内核抢占问题提供了更基础、更强大的解决途径。
在2002年1-2月ELJ上发表的中,我列举了不少希望Linux能够支持的实时功能,它们包括多优先级、用户空间中断处理和DMA、同步机制中的优先级继承(、微妙级的时钟解析度 、全面实现POSIX1003.1b规范要求的功能和调度程序的恒量耗时算法等。我们在本文中也会简要讨论它们。
要明白这些性能改进都必须依赖给内核打补丁,但是打补丁后的内核就不再兼容其它标准内核了,比如抢占式内核需要修改自旋锁的代码,这时如果一个驱动程序的二进制执行文件如果不采用修改过的自旋锁,那么很可能无法正常抢占。所以改造内核时一般都需要内核源代码并重新编译内核代码。值得一提的是,使用模块化的Linux驱动程序是使得源代码兼容的一个有效方法。我们不赞成仅仅发布驱动程序的已经编译的二进制文件而没有源代码,因为这样作既缺乏兼容性保障也不符合开源精神。
各种各样对内核的改进能够为应用程序透明地提供众多好处。比如,提高内核的抢占性主要通过抢占式内核或是添加抢占点着两个途径。从内核角度进行改进可以使得应用程序不用做修改就能获得高的响应速度。
透明性也应该考虑是否改变对内核来说也是透明的,换句话说就是,是否采用的方法能自动跟踪内核的改变。Molnar和Morton提出的插入抢占点的方法需要测量新内核中的调度响应时间,并且在此基础上插入抢占点到合适位置。
&&& 相反,如果在SMP锁定基础上创建抢占式内核,则可以自动、无须修改地过渡到新内核。而且如果在SMP-锁定机制中实现抢占性,则当内核开发者提高SMP锁定粒度(granularity)时,也同时会自动提高抢占粒度。我们会看到SMP锁定将粒度稳步提高,因为SMP不断扩张必定需要不断提高锁定粒度。
正是由于这种新引进的SMP锁,内核抢占才自2.4版本或更新(实际在2.6才正是支持)内核后被正式实现。而早期内核缺乏SMP锁。
抢占式内核的另外一个需要强调的重要优势是它使得代码——但代码不会发觉——可被抢占,比如,驱动程序开发者不必为要使驱动程序可被抢占去编写任何特殊代码,驱动程序的代码能在必要时被抢占,除非驱动程序持有锁。所以在内核其它部分,编写优良的SMP安全(代码中不存在多处理器并发访问共享资源的危险)的驱动程序将自动受益于抢占式内核。而另一方面,非SMP安全的驱动程序可能不能和抢占式内核和谐工作。
也许有人会发觉,只要某些驱动程序没有请求锁,内核代码就可以调用它。比如我们使用MontaVista的抢占式内核做简单测试中发现,动态装载的驱动程序中read()和write()函数都可以正常被抢占,但是函数init_module()、open()和close()却不能。这意味着如果一个低优先级的进程执行操作open()或close(),那么它有可能被一个新唤醒的高优先级别进程推迟抢占时机。
实际上,开发者最好去测量响应时间,因为即使使用抢占式内核,我们也有可能找到有那些代码片段持有锁的时间超过了应用程序允许的长间。
比如MontaVista, 提供了一个抢占式内核,对那些长期持锁的代码片段插入了抢占点,同时也提供了测量工具,以便开发者可以测量它们实际应用程序和环境的抢占性。
SMP锁的目的是确保内核重入(re-entrance)安全。也就是,如果并行运行的进程需要访问内核资源,那么对这些资源访问必须安全、可靠。越精细的锁定粒度越能保证竞争进程运行的并行巡行能力越强。因为并行能力的提高需要减少堵塞(因为锁的争用),(而细粒度锁可减少阻塞机会)。
上述概念也同样适用于单处理器。对于I/O系统来说,如果将I/O设备看作一个独立的处理器,那么应用程序和I/O活动的并行运行无疑能提高系统吞吐量。提高抢占性,意味着高优先级的I/O范畴进程(I/O-bound process)会更频繁地被唤醒,从而提高了吞吐量。这样以来,虽然可能带来某些负作用,比如我们可能会需要更多的上下文切换和在内核关键路径上执行更多代码(关键路径直那些访问共享资源的代码路径,为了防止竞争条件需要上锁等操作),但是即使如此,我们仍然可以获得更大的系统吞吐量。
允许内核抢占的优势是显而易见的,标准内核迟早会引入抢占功能(目前已经具有)。抢占式内核有些实现中可以提供几微妙的响应时间,而更精确的实现则可把响应时间提高到几十分之一微秒。
环顾嵌入Linux生产商,MontaVista 和TimeSys提供了抢占式内核;REDSonic使用抢占点;LynuxWorks和红帽子使用RTLinux;Lineo
使用RTAI;OnCore通过和Linux系统调用兼容的API(和LynuxWorks利用LynuxOs一样)与在他们的抢占式微内核上。
运行一个Linux内核(可抢占的)达到实时目的。
抢占点的核心思想是在特定点上调用调度程序去检查是否有更高优级的任务做好了运行准备,需要即刻运行。Molnar和Morton就是利用该思想,测量内核路径的执行时间,找到时间过长的路径插入调度检查点(等于打断了长路径)。你可以通过抢占补丁代码或是对比打过补丁的内核和先前未达补丁的内核,从中发现那些地方需要插入抢占点。抢占补丁看起来很象if (current -&need_resched) schedule()(这是用户空间抢占执行的典型情形);
为了使用Andrew Morton开发的抢占点内核补丁,需要从上面给出的URL下载该补丁,同时还要从kernel.org下载恰当版本的内核源代码。然后内核打上补丁然后重新编译,详细细节可以在这里找到,但要注意这些是为2.4版本老版本内核而言的。另外还请注意你可能需要升级你的开发环境。
&& 使用Molnar的补丁要做的事情同上。下载补丁、编译新内核,Morton开发了针对2.4多个版本的补丁。而Molnar的补丁针对一些2.2版本内核和早期的2.4版本内核。
抢占式内核
抢占式内核使得用户程序在执行系统调用期间可以被抢占,从而使新被唤醒的高优先级进程能够运行。这种抢占并非可以在内核中任意位置都能安全进行,比如在临界区中的代码就不能发生抢占。临界区是指同一时间内不可以有超过一个进程在其中执行的指令序列。在Linux内核中这些部分需要用自旋锁保护。
MontaVista
和 TimeSys采用类似的方法建立抢占式内核。他们巧妙地将自旋锁的功能加强为也能防止抢占(<span
lang=EN-US style='font-family:Acolor:#.6新内核中自选锁也是这样做的)。依靠该方法,抢占只能发生在未使用自旋锁的其它部分。当一个更高优先级的进程被唤醒,调度程序就能抢占低优先级进程正在执行的系统调用,只要此刻该系统调用代码没有被自旋锁保护——加上自旋锁意味不可抢占。
另外,使用抢占式内核,打断锁(解开再锁上)使得重新调度相比采用抢占点(低响应时间)补丁要简单。因为如果内核释放了一个锁,然后又再获得它,那么当锁被释放时,就会进行抢占检查。内核中有些地方需要上锁——比如一个循环——但不需要一直持有锁,可以每进行一次循环,锁就要被释放,然后再获得。
MontaVista实现抢占主要通过一个计数器(<span lang=EN-US
style='font-family:Acolor:#.6版本中称它为抢占计数,用它可以跟踪锁定嵌套数),当自旋锁被获取时,该计数就增加1。当高优先级别的进程被唤醒,调度程序会检查抢占计数——检查是否为零——判断是否此刻允许抢占(如果为0,就可以发生抢占)。依靠这个计数器,当锁嵌套调用时,抢占机制能很好的工作,但是任何持有自旋锁的临界区域都不允许抢占,即使锁用来保护的是些无关资源。
TimeSys采用一个优先级遗传互斥量(priority inheritance mutex)。利用这种机制,一个高优先级的进程可以抢占一个持有不同资源互斥量的低优先级别的进程。另外因为采用了优先级遗传,所以持有互斥量的低优先级的进程不能无限推迟等待在该互斥量上的高优先级进程。这样以来解决了所谓的优先级翻转问题(Priority Inversion Problem)。
MontaVista公司开发的抢占包可以从SourceForge kpreempt 站点获得。MontaVista公司的开源精神很值得赞赏,他们同时也提供了他们的实时调度程序与高解析度定时器,这些都可以从SourceForge的这里和这里获得。
SourceForge
的kpreempt 项目同时也含有Robert Love开发的抢占式内核的连接(请看2002年4月和5月出版的Linux杂志,其中介绍了他对内核改进的详细信息)。 另外 MontaVista的补丁也由Love维护(现在Robert Love已经归于MontaVista麾下),虽然MontaVista 也参与维护工作。最新的补丁可在此处下载。
Love最新发布的补丁现在已经可以和Ingo Molnar的恒时(耗时为衡量)调度程序补丁协同工作。Molnar的时间复杂度为O(1)的调度程序可以用于2.4版本内核,并且目前也已经植入了2.5版本的内核中了。TimeSys也将自己的抢占式内核发布在了他们的上。抢占式内核需要的补丁包都已经完备。要得到这些补丁,你需要将它们对比2.4.7内核代码数生成diff文件。上述的这些抢占式内核程序都遵守GPL协议。
TimeSys还为实时程序开发者提供了许多额外功能,这些功能不能无偿下载。它们包括实时调度和实时资源分配技术。这些模块填加了额外的系统调用,比如提供对新增功能的访问方法等。
如果那些朋友对这些细节感性趣,可以通过我们提供的许多线索找到想要的信息。自旋锁机制的关键信息包含在文件include/linux/spinlock.h中,MontaVista
和TimeSys都对该文件进行了修改。
有趣的是,虽然MontaVista 和TimeSys都对旧函数改了名字,但是他们仍然使用这些旧函数。以前老的自旋锁函数仍然需要。比如不允许在调度程序执行期间发生抢占内核的行为,否则会带来无穷无尽的递归调用。MontaVista使用象_raw_spin_lock和
_raw_read_lock这样的命名;TimeSys 使用象old_spin_lock 和
old_spin_lock_irq这样的命名。
可以在TimeSys发布的代码kernel/include/linux/mutex.h中发现它是利用write_lock() 和 read_lock()函数——他们实现了互斥锁——定义自旋锁的。具体实现函数do_write_lock()可以在文件kernel/kernel/mutex.c中看到,它实现了互斥锁定功能。
其它的内核实时方法
另一个能有效提高实时性的方法是提高时钟的粒度。TimeSys, MontaVista, REDSonic 和其他公司都提高了时钟解析度,比如,TimeSys 在上下文切换期间使用Pentium处理器的时间戳计数器(Stamp Counter)来确保准确地对CPU时间进行记帐,该记帐值要被诸如 getrusage()等函数用到。
许多开发者,也包含作者都认为Linux缺乏对POSIX1003的全面支持是个很重要的缺陷。幸运的是,目前已经有了解决方法,特别是,TimeSys公司已经有了一个不错的实现。
除了对POSIX的贡献外,TimeSys已经开发了一些全新的资源访问控制机制。这些新技术使得实时应用程序可以节约CPU时间或网络带宽。比如结合它们的中断线程模型、抢占式内核和其它功能,能提供高出标准内核2或3倍的响应速度。
到目前为止,Linux好象还不允许让用户空间应用程序自己注册函数处理中断,该机制称为用户空间中断处理机制,它目前已经在RIX、SGI's UNIX等系统中得到使用。
有趣的是,SGI在Linux中,利用他们的ds1286实时时钟接口,可以从用户空间通过一个实时时钟访问中断。可以在这里.找到相关信息
和用户级别中断处理相关的是用户空间和设备的DMA通讯,提供此功能的补丁可以从这里获得。
显然,没有哪个实时Linux厂商愿意保证响应速度。如果提供保证的话,那么应该类似下面的声明:
使用我们的Linux内核,和所需的硬件与设备等,我们可以保证你的应用程序如果被锁在内存,具有最高优先权。。那么将能够在你实时硬件发出中断信号后的N微妙内被唤醒。如果你无法获得上述能力,我们将视其为一个bug。
但是我们从没看到过该类保证,这是为什么呢? 我们认为有如下几种可能。
厂商的这种保证毫无意义,没有客户需要它。但我们认为许多开发者希望获得保证,事实上,硬实时本身就意味着一个保证。
厂商没有充分测量他们的内核和环境,以至于有能力给出一个保证。这是一个小花招。因为单独测量无法给出另人满意的保证,代码必须在所有环境中被测试而且要在最坏情况下测试。从厂商的宣称中,看起来它们似乎已经花了大量精力去测量和学习代码,但事实上,对工程师来说可能给出给定环境下的一些数据更能让人放心。
如果考虑所有需要保证的方面,Linux所涉及的方面实在是太多了。这点可能就是问题的所在。开发者希望能够改写他们的内核,他们希望能下载驱动程序并使用。这些行为都超出了厂商的控制,所以如果厂商公开声明一个保证,就有可能仅仅是针对某一个特定系统在一些选定的情况下才有效的。
也许我们会看到某些妥协的保证,例如像“在Pentium
系列的计算机上应用程序响应速度为100ms或更短”另外加上驱动程序花去的时间。驱动程序使用的时间非常重要,因为驱动程序中的中断处理代码往往在响应时间中占主要部分。
下一次讲什么?
在第三篇文章中,我们将讨论Linux内核以外有何其它方法提高实时性。我们要讨论诸如RTLinux and RTAI所采用的方法。还要借助基准对各种方法进行全面比较。
关于作者: Kevin Dankwardt是 K Computing 公司的创始人和CEO ,该公司是一家硅谷的培训和咨询公司 。特别要强调的是,该公司在全球范围内发展和推广嵌入和实时Linux培训 。
LinuxSagaLinuxLinux基于Linux内核的实时调度机制研究及应用_中华文本库
第4页/共4页
孙为,刘小甜
,宋健,等:一种基于双层管理机制的MIPv6安全通信方案
2008,44(6)153
径300m的圆。移动节点M1在小区1内的预测驻留时间Tdwell
成员对移动成员节点进行身份认证,也比较合理地解决了移动
为15min,移动节点M2在小区1内的预测驻留时间Tdwell为(1)两节点间的通告间隔为0.5min。12min,其余节点设为10min。
每隔2min记录一次数据,每次记录时长为0.5min。分别记录从开始到双层管理机制在3个小区内全部建立过程中各个节点在各个实验时间点发生的管理报文数量。实验结果如图5所示。
安全成员的地址变更问题。
该方案也存在一些问题。新方案的使用在一定程度上加重了上层节点的管理开销。事实上,可以通过改变上层节点的报文内容来减少这些开销。可以设定每个成员节点被认证进入或加入该网络内的双层管理机制后,必须从上层节点下载一份在线成员列表。此后上层节点可以根据实际情况来决定是交互其它成员节点变化状况报文(如节点的离线信息,节点的地址变更信息,候补节点变更信息等等);还是交互在线成员列表报文。这样可以根据需要降低上层节点的管理开销,同时也降低了网络带宽占用率。或者也可以通过在一个网络内设置多个上层节点(即限定上层节点所管理下层节点的数量)来分摊这些开销。这也是该课题今后要解决的问题。
本文所讨论问题的另一套解决方案是使用组播。但是,在移动网络IPv6网络中,动态组播树的构造过于繁杂且开销巨大。更主要的问题是无法让组播服务器去实现成员的认证功能。
本方案最大的特点就是结合分布式设计思想和移动节点
根据相互通告模式的特点(各个节点分别和所有其他节点交互管理报文),从图5中可以看出,开始2分钟这段时间内,各个节点使用相互通告模式来交互管理报文。由第4分钟开始,在观测时间内除M1外其余节点均只发生1条管理报文。由双层管理机制的特点(下层节点只与上层节点进行管理报文交互)可知双层管理机制在该小区内建立,M1成为第一个上层节点。
同理可以判断节点M2在第10分钟时成为小区1新的上层节点。从M1之后的变化情况可知,M1进入小区2,并成为小区2的上层节点。由于网络内的上层节点变为两个,故M2发生的管理报文数量不变。至此,双层管理机制已在小区1和小区2中建立。
移动节点所分布的了小区数量在第22分钟达到了3个。从M1管理报文发送量变化上可以看出它成为了小区3的上根据预测驻留时层节点。M3则成为了小区2的新的上层节点。间的选举法则可以推出M3是在M1离开小区2前最新进入小区2的节点。故M3是该小区内所有节点中在上个小区内(小区1)驻留时间最长的节点,根据公式(2)不难推出,M3必然当选小区2新的上层节点。至此,双层管理机制已在三个小区内建立。其余非上层节点管理报文变化状况(如曲线MX),这里不再赘述。
的移动特性,以各个成员在网内的预测驻留时间为选取标准构架双层管理模式,从而在安全通信组所分布的网络里动态的构造了一个管理节点,妥善的解决了安全通信自动配置方案在移动IPv6网络中的扩展问题。
参考文献:
[1]KentS,AtkinsonR.RFC2401SecurityarchitecturefortheInternet
(IPsec)[S].1998.Protocol
[2]YuichiroHei,KatsuyukiYamazaki.AproposalofconfiguringIPv6
end-to-endsecurechannelsforclosedmembers[C]//ProceedingsofSAINT2005Workshops,Jan2005:6-9.
[3]GlassS,HillerT,JacobsS.RFC2977MobileIPauthentication,au-
thorization,andaccountingrequirements[S],2000-10.
[4]KawanoK,KinoshitaK,MurakamiK.Astudyonestimationofmo-
bilityofterminalsforhierarchicalmobilitymanagementscheme[J].(9):2557-2566.IEICETransactionsonCommunications,2004,E87-B
(IKE)[S].1998-11.[5]HarkinsD,CarrelD.TheInternetKeyExchange
[6]KentIS,AtkinsonRP.RFC2406EncapsulatingSecurityPayload(ESP)[S].1998-11.
[7]HousleyR,FordW,PolkW,etal.RFC2459InternetX.509public
keyinfrastructurecertificate,andCRLprofile[S].1999-01.
[8]DevarapalliV,DupontF.RFC4877MobileIPv6operationwith
IKEv2andtherevisedIPsecarchitecture[S].2007-04.
[9]ChenYW,HuangMJ.AnovelMAPselectionschemebyusing
abstractionnodeinhierarchicalMIPv6[C]//2006IEEEInternation-alConferenceonCommunications,2006,12:5408-5413.
5方案总结
通过仿真分析可见,新的方案可以在很大程度上解决原方
案中管理报文数量大的缺陷。同时通过上层管理节点代理其他
(上接123页)
[3]王永炎,王强,王宏安,等.基于优先级表的实时调度算法及其实现[J].
软件学报,2004,15(3):360-370.
Symp.Pisa:IEEEComputerSocietyPress,1995:90-99.
[5]CarlsonJ,LennvallT,FohlerG.Value-basedoverloadhandlingof
aperiodictasksinofflinescheduledreal-timesystems[C]//Work-in-ProgressSessionofthe13thEuromicroConfonReal-TimeSystems.[S.l.]:IEEEComputerSocietyPress,2001:46-49.
[4]ButtazzoG,SpuriM,SensiniF.Valuevsdeadlineschedulingin
overloadconditions[C]//Procofthe19thIEEEReal-TimeSystems
第4页/共4页
寻找更多 ""3.实时操作系统的内核_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
3.实时操作系统的内核
上传于||暂无简介
大小:45.00KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢改善Linux内核实时性方法的研究与实现
> 改善Linux内核实时性方法的研究与实现
改善Linux内核实时性方法的研究与实现
  0 引言本文引用地址:
  由于具有功能强大、源代码开放、支持多种硬件平台、模块化的设计方案以及丰富的开发工具支持等特点,在实际系统中,得到了广泛的应用。但由于其最初的设计目标为通用分时操作系统,对于实时系统而言,仍然存在核心不可抢占、关中断、时钟粒度粗糙等缺陷。为了使其应用于嵌入式系统,实时控制等领域,越来越多的厂家和研究机构热衷于改善其,构建基于的实时操作系统。
  在Linux 2.4和以前的版本,内核是不可抢占的,也就是说,如果当前任务运行在内核态,即使当前有更紧急的任务需要运行,当前任务也不能被抢占。因此那个紧急任务必须等到当前任务执行完内核态的操作返回用户态后或当前任务因需要等待某些条件满足而主动让出CPU才能被考虑执行,这很明显严重影响抢占延迟。在 Linux 2.6中,内核已经可以抢占,因而得到了加强。但是内核中仍有大量的不可抢占区域, 如由自旋锁spinlock保护的临界区,以及一些失效抢占的临界区。另一个影响Linux的因素就是关中断,同步操作中使用的关中断指令增大了中断延迟,这样很多由中断驱动的实时任务得不到及时的执行,系统的实时性能得不到保障。因此提高Linux的可抢占性,改进其中断机制有利于改善内核的实时性。
  本文详细阐述了这些措施的原理并基于标准内核加以实现,最后通过测试,验证了此改进方法的效果。
  1 中断线程化
  1.1 Linux中断对内核实时性的影响
  中断处理是由内核执行的最敏感的任务之一,当内核正打算去做一些别的事情时,中断随时会到来,中断当前的任务进而执行中断处理程序。因此内核的目标就是让中断尽可能快的处理完,尽其所能把更多的处理工作向后推迟。为此Linux把中断的处理分成上半部分和下半部分。上半部分立即执行,下半部分将唤醒相应的和中断处理相关的进程稍后执行。虽然这种机制使得中断处理变得更加高效和易于维护,但是对于系统如果有严重的网络负载或其他I/O负载时,中断将非常频繁,内核当前的实时任务会被不停中断,这对于Linux的实时应用来说是不可接受的。
  另外,Linux为了使内核同步而采用了关中断,在内核的关中断区域,中断是被屏蔽的。即使此时有通过中断驱动的实时任务也得不到响应,增加了实时任务的中断延迟。实时化后的Linux中,自旋锁被互斥锁取代,而中断处理代码中大量运用了自旋锁,中断处理代码就有可能因为得不到锁而需要被挂到该锁的等待队列上去。但是只有可调度的进程才可这么做,如果中断处理代码仍然使用原来的自旋锁,那么互斥锁取代自旋锁改进内核实时性的努力将大打折扣。
  线程化的中断管理可以有效的解决这些问题。中断线程化后,中断将作为内核线程运行而且赋予不同的实时优先级,实时任务可以有比中断线程更高的优先级,这样,实时任务就可以作为最高优先级的执行单元来运行,即使在严重负载下仍有实时性保证。另一方面中断处理线程也可以因为在内核同步中得不到锁而挂载到锁的等待队列中。很多关中断就不必真正的禁止硬件中断了,而是禁止内核进程抢占,这样就可以减小中断延迟。
  1.2 设计与实现
  Linux提供了kthread_create创建内核线程,该内核线程在内核空间执行,因此在调度时没有用户空间和内核空间切换,使得其运行更为高效。中断线程化要做的工作是创建中断线程以及中断的处理。中断线程是在系统初始化或者调用requestirq函数时通过 kthread_create函数创建的。其过程等同于如下功能代码:
  对于非紧急中断,kthread_create为其创建一个内核线程,并且根据中断号为其赋予一定的静态实时优先级和设置其调度策略。中断到来后,内核并不是直接进入中断服务函数,而是通过设置调度标志告知内核,内核调度程序比较该中断线程的优先级和当前运行任务的优先级,作出调度决策。因此当前正在运行的高优先级的实时任务不会受中断的太大的影响,保证了实时任务运行的可靠性和准确性,中断线程将会其他合适的时刻被调度执行,而且 内核的O(1)调度机制也不会因为内核线程数的增加在调度时间上额外增加调度开销。对于紧急的中断(比如时钟中断),内核保持原来的中断处理方式,而不为其创建中断线程,这样保证了紧急中断的快速响应。
  2 自旋锁改互斥锁
  2.1 新的自旋锁设计
  为了同步不同内核控制路径对共享资源的访问,标准Linux内核提供了很多内核同步原语,其中自旋锁spinlock是一种广泛应用于可抢占内核,SMP环境下的内核同步机制。在spinlock的保持期间,内核是抢占失效的。被自旋锁保护的区域称为临界区,内核中大量使用了spinlock,存在大量的内核不可抢占的临界区,这将严重影响系统的实时性,我们使用新的实时互斥锁rt_mutex来替换spinlock,即让临界区内内核可抢占。其结构体如下:
  类型raw_spinlock_t就是原来的spinlock_t。新的自旋锁还是使用spinlock_t来标记。在结构struct rt_mutex中的wait_list字段就是优先级化的等待队列。Owner字段为拥有该锁的进程的环境信息。mutex比spinlock优越的地方有这么几点:(1)当遇到一个锁住的临界区时,任务被挂起到锁的优先级等待队列wait_list中,临界区解锁时等待任务被激活。(2)内核将一个锁住的临界区和一个任务关联,当获得互斥锁时将任务的标识存入锁中。(3)临界区可以在被保护的同时不禁止抢占。(4)在被锁住的临界区中可以实现优先级继承。
  2.2 实时互斥锁的操作
  并不是所有内核中的自旋锁都可以转换为互斥锁的,一些底层的临界区必须是不可抢占的,所以必须由不可抢占的自旋锁保护,比如:保护硬件寄存器的锁、调度器的运行队列锁、和其它不可抢占自旋锁嵌套的锁。实时内核中,不可抢占的自旋锁与RT互斥锁共存,不可抢占的自旋锁被重命为 raw_spinlock_t。spin_lock函数利用gcc的内嵌技术根据锁的类型通过预处理选择具体的锁执行函数。预处理器使用 __builtin_types_compatible函数,由宏TYPE_EQUAL调用:
linux操作系统文章专题:
linux相关文章:
分享给小伙伴们:
我来说两句……
最新技术贴
微信公众号二
微信公众号一

我要回帖

更多关于 内核是什么意思 的文章

 

随机推荐