OSSchedLock()函数透析
摘
OSSchedLock()
调用OSSchedLock()以后,用户的应用程序不得使用任何能将现行任务挂起的系统调用。
也就是说,用户程序不得调用OSMboxPend()、OSQPend()、OSSemPend()、
OSTaskSuspend(OS_PR1O_SELF)、OSTimeDly()或OSTimeDlyHMSM(),直到OSLockNesting回零为止。
因为调度器上了锁,用户就锁住了系统,任何其它任务都不能运行
下面贴出这个函数的代码 :
#if OS_SCHED_LOCK_EN > 0 //这是个全局变量,在Os_cfg.h中定义
void OSSchedLock (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
if (OSRunning == TRUE) { /* 确认是否是多个任务在运行 */
OS_ENTER_CRITICAL();
if (OSLockNesting < 255) { /* OSLockNesting最大值为255 */
OSLockNesting++; /* Increment lock nesting level */
}
OS_EXIT_CRITICAL();
}
}
#endif
从上锁函数我们可以看出,这个函数就是一个确定任务上锁级数的函数,也就是为OSLockNesting这个变量更新取值的函数。
如果我们在任务里面执行一次该函数,则上锁级数就是1。我们也可以知道,上锁函数的深度最大值为255,我们可以通过上锁到255,到逐级解锁来实现不同的应用。
但这个过程,本人从来没有实现过。
并且补充一点,在上锁函数执行后,若任务遇到中断,则中断函数的执行会为OSIntNesting变量加1,所以上锁函数执行后,CPU一直处于当前任务与中断服务函数之间的运行,
直到解锁函数将OSLockNesting和OSIntNesting的值减到0时。方可解除系统锁定。。。。
转:ucos中的三种临界区管理机制(OS_CRITICAL_METHOD的解释)
熟悉ucos,或者读过Jean.J.Labrosse写过的ucos书籍的人,一定会知道ucos中著名的临界去管理宏:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。
同样是通过关中断来保护临界区,OS_ENTER_CRITICAL/OS_EXIT_CRITICAL一共实现了三种实现方式,如下所示:
- #if OS_CRITICAL_METHOD == 1
- #define OS_ENTER_CRITICAL() __asm__("cli")
- #define OS_EXIT_CRITICAL() __asm__("sti")
- #endif
- #if OS_CRITICAL_METHOD == 2
- #define OS_ENTER_CRITICAL() __asm__("pushf \n\t cli")
- #define OS_EXIT_CRITICAL() __asm__("popf")
- #endif
- #if OS_CRITICAL_METHOD == 3
- #define OS_ENTER_CRITICAL() (cpu_sr = OSCPUSaveSR())
- #define OS_EXIT_CRITICAL() (OSCPURestoreSR(cpu_sr))
- #endif
第一种方式,OS_ENTER_CRITICAL()简单地关中断,OS_EXIT_CRITICAL()简单地开中断。这种方式虽然简单高效,但无法满足嵌套的情况。如果有两层临界区保护,在退出内层临界区时就会开中断,使外层的临界区也失去保护。虽然ucos的内核写的足够好,没有明显嵌套临界区的情况,但谁也无法保证一定没有,无法保证今后没有,无法保证在附加的驱动或什么位置没有,所以基本上第一种方法是没有人用的。
第二种方式,OS_ENTER_CRITICAL()会在关中断前保存之前的标志寄存器内容到堆栈中,OS_EXIT_CRITICAL()从堆栈中恢复之前保存的状态。这样就允许了临界区嵌套的情况。但现在看来,这种方法还存在很大的问题,甚至会出现致命的漏洞。
在OS_CRITICAL_METHOD=2的情况下,假设有如下代码:
- function_a()
- {
- int a=(1<<31);
- OS_ENTER_CRITICAL();
- function_b(a);
- OS_EXIT_CRITICAL();
- }
会出现什么情况?在我的实验中,OS_EXIT_CRITICAL()之后,会出现处理器异常。为什么会出现处理起异常,让我来模拟一下它的汇编代码。之所以是模拟,并非是我虚构数据,而是因为我实际碰到问题的函数复杂一些,理解起来就需要更多的代码。而这个问题是有普遍意义的,所以请允许我来浅显地揭示这个隐藏的bug。
- function_a:
- push ebp
- mov ebp, esp
- sub esp, 8
- mov 4(esp), 0x80000000
- pushfd
- cli
- mov edi, 4(esp)
- mov (esp), edi
- call function_b
- popfd
- mov esp, ebp
- ret
这是参照了gcc编译结果的汇编模拟,无论是否加优化选项这一问题都存在。这个问题的起因很简单,gcc想聪明一点,一次把堆栈降个够,然后它就可以在栈上随意放参数去调用其他函数。尤其是在调用函数较多的时候,这种做法就更有意义。而且,gcc这种聪明与优化选项O好像没有太大关系,好像没有什么能禁止它这么做。但问题是,gcc不知道我们的OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()是操作了堆栈的,我尝试过使用__asm__ __volatile__("pushfd \n\tcli":::"memory")来通知gcc内存数据改变了,但显然gcc不认为堆栈也改变了。于是,OS_ENTER_CRITICAL()保存在栈上的状态就被冲掉了,比如被这里调用参数a的值。在恢复时,是否会引发异常,会引发什么异常,这个就要靠运气了。但我相信一个人的运气不会总是那么好的,所以最后别使用OS_CRITICAL_METHOD=2。
第三种,在关中断前,使用局部变量保存中断状态。这也是几乎所有实时操作系统共有的选择。但ucos是一朵奇葩,为了兼容前两种方式,OS_ENTER_CRITICAL()/ OS_EXIT_CRITICAL()宏定义并没有提供传递状态参数的功能。所以它的临界去必须这么用:
- function_a()
- {
- #if OS_CRITICAL_METHOD == 3
- int cpu_sr;
- #endif
- int a = 1<<31;
- OS_ENTER_CRITICAL();
- function_b(a);
- OS_EXIT_CRITICAL();
- }
这种代码怎么看怎么别扭,可能是因为在函数体内加了宏定义吧。然后,第三种方法对同一个函数体内的嵌套临界区无法支持,这在一些很长大的函数中使用时或许会造成一定困扰。
好吧,如果有了问题,就要有解决方案,毕竟我不是为了让大家对ucos失去信心的。我们可以参考下一般的实时操作系统是如何实现关中断临界区的,就是以显式的方式用局部变量保存中断状态。
- int int_lock()
- {
- int cpu_sr;
- __asm__ __volatile__("pushfd \n\t pop %0\n\t cli":"=r"(cpu_sr));
- return cpu_sr;
- }
- void int_unlock(int cpu_sr)
- {
- __asm__ __volatile__("push %0\n\t popfd"::"r"(cpu_sr));
- }
- function_a()
- {
- int a, cpu_sr;
- a=1<<31;
- cpu_sr = int_lock();
- function_b(a);
- int_unlock(cpu_sr);
- }
int_lock()和int_unlock()的可以用汇编更高效地实现,也可以选择只恢复中断标志的状态。这种方法让我们显示地管理状态保存的情况,我觉得至少要比宏定义清楚多了
OSSchedLock()函数透析的更多相关文章
- ucos_ii 上锁函数OSSchedLock()函数透析
因为任务调度时一般都是通过OSTIMEDLY()来实现.在这个函数中会对当前的任务执行挂起.同时查看任务调度表中是否有优先级合适的就绪任务.如果当前任务运行时调用OSSchedLock()给调度器上锁 ...
- lambda匿名函数透析
lambda匿名函数透析 目录 1 匿名函数的作用... 1 2 匿名函数的格式... 1 3 匿名函数实例代码... 3 1 匿名函数的作用 ...
- OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)
OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰) 前文曾详细探讨了关于OpenCV的使用,原本以为天下已太平.但不断有人反 ...
- Ruby设计模式透析之 —— 适配器(Adapter)
转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9400153 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...
- Ruby设计模式透析之 —— 组合(Composite)
转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9153761 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...
- 透析ARP原理
对于ARP协议, 我本来是不了解的,只是解决了两个ARP相关的P2的Bug后,也就懂了.本文将从原理的角度对ARP做一个透析. 1. 什么是ARP? ARP(Address Resolution Pr ...
- java--序列化及其算法透析
有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍. Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述 ...
- Excel数据分析 --数据透析表
数据透析表主要用于各种数据总汇,对各项数据指标进行分类统计 实例分析 如下所示:是一份销售流水数据,有时间,地区,销售员,商品名称,数量,单价和金额几个字段,如下所示: 现在针对不同的数据汇总需求,可 ...
- SOFA 数据透析
数据透传: 在 RPC调用中,数据的传递,是通过接口方法参数来传递的,需要接口方定义好一些参数允许传递才可以,在一些场景下,我们希望,能够更通用的传递一些参数,比如一些标识性的信息.业务方可能希望,在 ...
随机推荐
- 如何选择NoSql数据库
How to choose a No Sql database 介绍了一下怎么选择一个No Sql数据库,下面简单翻译一下重点. No Sql的数据库可以分为如下4类: Key-Value数据库 数据 ...
- CBO学习----03--选择率(Selectivity)
第3章 单表选择率(Single Table Selectivity) Selectivity是优化器估算Rows(Cards)的重要依据. /**************************** ...
- Winform 中 DesignMode 返回值不正确的问题。
本文转载:http://blog.csdn.net/sabty/article/details/5325260 以前也曾遇到这样的问题,不过影响不大也没有去详细了解.今天又重新遇到此问题,实在太不便. ...
- 提高你30%的设计效率的PPT快捷键
在编辑幻灯片的状态下: [Ctrl]+[A]选择全部对象或幻灯片 [Ctrl]+[B]应用(解除)文本加粗 [Ctrl]+[C]复制 [Ctrl]+[D]快速复制对象 [Ctrl]+[E]段落居中对齐 ...
- js控件位置
function ShowSettingDiv() { var div = document.getElementById('ShowDiv'); //将要弹出的层 div.style.display ...
- #IOS-navigation中左滑pop的三种方法
IOS-navigation中左滑pop的三种方法 系统自带pop方法 如果我们没有对navigation中的back按钮进行自定义,我们可以直接使用系统自带的左滑pop方法.但是如果我们对back按 ...
- HTTPS是如何保证连接安全:每位Web开发者都应知道的
“HTTPS协议的工作原理是什么?”这是我在数天前工作项目中需要解决的问题. 作为一名Web开发者,我当然知道 HTTPS 协议是保障用户敏感数据的好办法,但并不知道这种协议的内在工作机制. 它怎么保 ...
- Linux 用户与用户组
1 Linux 用户与组 Linux是一个多用户多任务操作系统.多用户可以在同一时间内登录同一个系统执行各自不同的任务,而互不影响. 1.1 Linux下用户的角色分类 Linux用户的角色分为3 ...
- ASP.NET Webform或者ASP.NET MVC站点部署到IIS下,默认情况下.json文件是不能被访问的,如果请求访问.json文件,则会出现找不到文件的404错误提示
解决方法 <system.webServer> <staticContent> <remove fileExtension=".woff" /> ...
- memcached和mongodb 在windows下安装
要在新机器上安装memcached和mongodb服务,折腾了一天,终于把这两个服务在windows下跑起来了. memcached主要参考http://www.rootop.org/pages/27 ...