关于基于优先级的抢占式调度

        对于有一定操作系统基础的朋友看到“抢占式”调度一定不会陌生吧。 我参考了Linux内核、eCos以及Windows内核对于抢占式调度的处理,感觉虽然细节上有点差别,但都挺有意思。

        这里,我想谈谈关于抢占式调度的一些看法。在很多操作系统书上基本上都这么谈基于优先级的抢占式调度:

(1) 每个任务赋予唯一的一个优先级(有些操作系统可以动态地改变任务的优先级);

(2) 假如有几个任务同时处于就绪状态,优先级最高的那个将被运行;

(3) 只要有一个优先级更高的任务就绪,它就可以中断当前优先级较低的任务的执行;

……

        当时我在学习操作系统时就在想了,当一个优先级更高的任务到来时CPU如何才能知道,并且调用调度例程呢?后来随着学习的深入,知道了计算机中的中断事件。CPU可以捕获一个中断事件,只要事先对该事件的中断源进行过关联。那样的话就可以在中断事件结束后给CPU“发送信号”,表示该事件对应于激活一个任务,要求CPU做出任务调度。那么CPU在进行任务调度时就会检查当前任务的优先级和就绪队列中的任务优先级进行比较,选出优先级最大的开始运行。

        以上过程说起来容易,但是做起来也是有些麻烦的。这里必须注意一些细节问题,比如说在哪些情况下应该禁止调度,哪些情况下需要关开中断等等。另外还有一个比较重要的问题就是中断处理例程如何“发送信号”“通知”CPU。这里有很多种方法。比如,在处理完中断服务例程之后,可以jump到或call线程调度例程。不过这样做有一个缺陷,也就是如果该中断优先级较高的话,那么中断处理时间就会变得非常长,而会显得系统反应一下子变慢,因此这个方式适合于低中断优先级的处理例程。Linux中有种做法是将调度例程的首地址压入用户栈空间,这样的话当中断处理例程返回后就会转入调度例程。这是个不错的手段。

        而微软它有一个任务优先级将PREEMPTIVE_LEVEL,这个比PASSIVE_LEVEL的优先级要高一个档次。那么在我自己的系统当中我的处理方法与Linux的差不多,但是为了要保证调度例程的一定的优先级,因此不让它在常规模式下处理,而是放在优先级次第的14号中断(软件中断1)中进行(这里将针对本人目前研究的Blackfin DSP处理器构架)。也就是说,在一个外部中断事件结束后,使用raise 14命令,通过CPU触发核心中断14,由于外部事件的优先级均大于14,因此外部事件中断处理可以安然返回,而当它们一旦返回就会进入14号中断处理。

        采用以上这种方法的话,如果中断14就处理任务调度,则没什么大问题,否则的话如果还有一些事情要做(根据参数选择不同的处理),那么也要安排好事件通知信号。比如一个高优先级的中断选择做其他的一些14号中断处理,而另外一些外部中断中断事件选择做另一些14号中断的处理,而还有的则想进行任务切换,那么这个时候14号中断就要利用一些队列等结构来存储这些事件消息。

        在插入调用或跳入任务调度例程的地方称为一个查看点。对于一个基于优先级抢占式调度的操作系统会有较多的察看点,以上是对于中断处理中的察看点的讨论。

        大家如果还有什么好的基于优先级调度的方法可以回帖,谢谢。

 

你可能感兴趣的:(操作系统及嵌入式开发)