本篇的主要内容为:按照老师提供的实现路线进行开发时的设计、实现以及所遇到的问题
embassy里面是直接采用头插法将新的task_ref插入,从而更新run-queue链表,而仔细想想,我们的抢占式设计是不需要一个run-queue链表的,我们通过arena分配给taskstorage相应的空间过后,只需要保存它的指针到以数组里面即可(这个数组就相当于ucosii的OSTCBPRIO数组)
之所以没有了一个freelist和tcblist维护分配信息,是因为分配的过程是由arena进行动态分配的,因为任务的大小不一样,但是很致命的一点是arena没办法对分配的任务(taskstorage)进行回收,尽管在嵌入式的情况来看,的确不需要,因为每个任务应该都是一个死循环,永远不会退出,所以也就不存在回收的问题。
如果是这样的话,我们目前可以去掉下面这两个TCB的成员,因为不需要维护一个tcb的链表
OSTCBNext: SyncUnsafeCell<Option<OS_TCB_REF>>, /* Pointer to next TCB in the TCB list */
OSTCBPrev: SyncUnsafeCell<Option<OS_TCB_REF>>, /* Pointer to previous TCB in the TCB list */
所以我们只需要一个以优先级为下标索引到OS_TCB_REF的数组,这个数组可以就放到全局的executor里面,同时还有位图的部分也应该放进去,主要是OSRdyGrp和OSRdyTbl
在执行器里面采取这样的机制:
原来的embassy是poll的时候将整个队列里面的元素都按顺序poll一遍,并且从就绪队列里面删除。现在的思路是:
原来的embassy的方式是:一次执行器的poll执行当前runqueue的所有任务,中途有就绪的任务会加入到“新”的runqueue(其实是原来的runqueue,只是runqueue在执行第一个任务时就会被清空),然后被poll的任务如果await了,就会自然的走到下一个任务执行。
而我们这里取消掉一次性poll完任务,而是一次poll一个任务,完成之后,将该任务设置为非就绪态,然后转到最高优先级任务执行,这里很重要的一点就是这里对于临界区的设置:
对于位图的所有操作都需要加在临界区里面完成:
我们的临界区应该这里需要包含:设置当前任务在位图中为非就绪, 查找位图找到最高优先级,并且设置OSCURPRIO为这个优先级