RT-Thread 的内核调度算法中使用的查找当前最高优先级的线程的代码实现是这样的:
这里有一个判断 value 的值是否为0的操作,为了应对这个判断,所有的优先级都多加了1。
然后在调用的时候,把这个1减掉了。
我的疑问来了,value值不可能为 0,为什么要判断这个值是否为0,不判断的话还省去了减一再加一的过程。
如果说是为了保持函数的健壮性,把 0 也检查了。
那么为什么不检查
这句代码中的 highest_ready_priority是否合理,因为如果__rt_ffs(rt_thread_ready_priority_group)的结果是0,减一后,就是一个很大的整数(无符号整型),后面调用就会造成数组溢出。
我觉得 __rt_ffs(int value) 不应该检查value是否等于0,这样代码还能更简单一点。
可能是我还没考虑到更多的情况,希望知道的大佬,解决一下我心中的疑惑,谢谢。
以支持最大的优先级为32为例
线程启动时调用rt_thread_startup:
当优先级为0时,优先级掩码是为1的,调用rt_thread_resume将线程插入到就绪优先级链表中:
将位图变量rt_thread_ready_priority_group相应位置位
调用rt_schedule发起线程调度:
当最高优先级为0时,rt_thread_ready_priority_group最低非0 bit位是第一位,调用位图查表算法__rt_ffs
最后返回return lowest_bit_bitmap[value & 0xff] + 1 = 1; 这里+1是因为lowest_bit_bitmap中最低有效位是从0开始的,即bit0~bit255,而rtt中认为位图变量rt_thread_ready_priority_group的最低有效位是从1开始的,即bit1~bit32,但最高优先级又是从0开始的,因此highest_ready_priority = __rt_ffs(rt_thread_ready_priority_group) - 1 = 0;因此不存在你所认为最高优先级为0时,无符号整数溢出的情况。
以上,__rt_ffs返回结果必须要+1,而if (value == 0) return 0表示不存在最低非0 bit位的情况,但在实际线程调度中是不会出现的,这样做是因为建立位图需要,方便查表,同时也是为了提高算法鲁棒性。
明白了,谢谢解惑