|
发表于 2011-2-15 20:30:31
|
显示全部楼层
1. 首先说Tail-chaining,它说的是这样一种场景,
未优化情况下,两个异常正常的执行次序六个步骤:
A:压栈1、异常1、出栈1
B: 压栈2、异常2、出栈2
实际上,在某种情况下,那么 出栈1和压栈2的动作是不必要的,
于是可以优化成四个步骤:
A:压栈1、异常1、
B: 异常2、出栈2
也就是说,Tail-chaining机制,不会对“出栈2”时的寄存器造成任何影响。
上面这段过于迷乱,大家可不看,关键是一句话,
这种优化,不是任何时候都可以的,上面提到“在某种情况下”。
什么情况呢?需要挂起的异常的优先级,比正在前一个异常的优先级高。(在《ARMv6-M Architecture Reference Manual》 B1.5.12有提到)
楼主提到的情况,一个更高优先级的异常过来抢占svc, 然后进svc之前又做tail-chaining。
《ARMv6-M》中的这个要求,正好可以将其避免。
其实它不想办法避免也不行,否则Tail-chaining就几乎是个废材,任何的异常的寄存器都可能被弄乱,不关svc.
2. 关于svc优先级是不是最高。
svc优先级的确不是最高的。对于M0, 更高的还有reset, nmi, hardfault.
这三个,是特例,比OS调度更底层的东西。只要用户不在nmi, hardfault异常中写和OS调度相关的代码,
就永远不会有问题。当然,如果用户硬要写,任何OS都无法避免不出错。
再则就是svc的优先级,当然用户也可以改掉,变成更低。这是改过才可能有bug,不是吗?总不能阻止用户搞破坏。
其实改了也关系不大,TinyThread的函数,都是用svc,仿造系统调用的方式实现的。
再则就是hardfault中断,正常程序,都是由程序主动造成,例如执行BKPT指令。
运行svc时,不会突然无端冒个hardfault.
所以svc优先级不是最高的问题,事实上不用担心。
3. 关于__tt_sem_down 函数
TinyThread暴露给用户的函数,是tt_sem_down(),
加下划线的static __tt_sem_down()函数,由svc handler里面内部调用。
因为在svc handler里面调用,这就保证了此函数执行期间,不会有中断进来再执行 tt_sem_up()。
所以John提到的问题也不存在的。
当然svc期间,可能有nmi和hardfault, 不需考虑的原因上面讲了。nmi更叫“不可屏蔽中断”,
用户要在里面“搞破坏”,任何OS都歇菜。
另外tt_sem_up执行++sem->count的动作,也是在进入svc handler里执行的。在svc里面,down和up的动作不会交错着做。
感谢John_Lee的细致分析,兄弟肯定是软件老大,一口气能发现这么多的疑点。
不过你真的多虑了。上面说一堆,不足之处,请万望指出。
========================================================================
再补充一下,2010年3月的TinyThread1.0的tt_list.h中,处理list时,有个小bug.
在TinyThread1.1中有修复。 |
|