抢占式RTOS中目前常用的最高优先级搜索算法,用一个BIT标记该优先级是否有任务等待运行:
1、最低BIT表明最高优先级,最高自然是最低的优先级;
2、该BIT标记为1表明该优先级有等待激活的线程;
3,用一个256字节的数组标记每8bit(一个字节的位宽)的所有可能情况(空间换时间),因为只需要第一个不为0的最低位,即只对应一种状态。
这个算法能优点网上一大把,我就不说了,自己做了一个实现,相对用循环查标记字节来说,用了二分查找,对所有情况来说时间复杂度都是一样的,为RTOS线程调度提供比较高的可预测性。
用到的数据结构:
typedef union tagSysThrBitMapType { SysU8 U8[32]; SysU16 U16[16]; SysU32 U32[8]; SysU64 U64[4]; } SysThrBitMapType; typedef struct tagSysThrPriorityArrayType { SysU32 TheadCount; SysThrBitMapType BitMap; SysThrType* ActiveThreadList[SYS_MAX_PRIORITY]; SysThrType* InactiveThreadList[SYS_MAX_PRIORITY-1]; } SysThrPriorityArrayType;
实现细节
SysU8 SysThrGetHighestActivePriority() { SysU8 HighestActivePriority; if(SysThrPriorityArray.BitMap.U64[0]) { if(SysThrPriorityArray.BitMap.U32[0]) { if(SysThrPriorityArray.BitMap.U16[0]) { if(SysThrPriorityArray.BitMap.U8[0]) HighestActivePriority=SysThrBytePriority[SysThrPriorityArray.BitMap.U8[0]]; else HighestActivePriority=8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[1]]; } else { if(SysThrPriorityArray.BitMap.U8[2]) HighestActivePriority=2*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[2]]; else HighestActivePriority=3*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[3]]; } } else { if(SysThrPriorityArray.BitMap.U16[2]) { if(SysThrPriorityArray.BitMap.U8[4]) HighestActivePriority=4*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[4]]; else HighestActivePriority=5*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[5]]; } else { if(SysThrPriorityArray.BitMap.U8[6]) HighestActivePriority=6*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[6]]; else HighestActivePriority=7*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[7]]; } } } else if(SysThrPriorityArray.BitMap.U64[1]) { if(SysThrPriorityArray.BitMap.U32[2]) { if(SysThrPriorityArray.BitMap.U16[4]) { if(SysThrPriorityArray.BitMap.U8[8]) HighestActivePriority=8*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[8]]; HighestActivePriority=9*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[9]]; } else { if(SysThrPriorityArray.BitMap.U8[10]) HighestActivePriority=10*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[10]]; else HighestActivePriority=11*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[11]]; } } else { if(SysThrPriorityArray.BitMap.U16[6]) { if(SysThrPriorityArray.BitMap.U8[12]) HighestActivePriority=12*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[12]]; else HighestActivePriority=13*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[13]]; } else { if(SysThrPriorityArray.BitMap.U8[14]) HighestActivePriority=14*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[14]]; else HighestActivePriority=15*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[15]];; } } } else if(SysThrPriorityArray.BitMap.U64[2]) { if(SysThrPriorityArray.BitMap.U32[4]) { if(SysThrPriorityArray.BitMap.U16[8]) { if(SysThrPriorityArray.BitMap.U8[16]) HighestActivePriority=16*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[16]]; else HighestActivePriority=17*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[17]]; } else { if(SysThrPriorityArray.BitMap.U8[18]) HighestActivePriority=18*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[18]]; else HighestActivePriority=19*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[19]]; } } else { if(SysThrPriorityArray.BitMap.U16[10]) { if(SysThrPriorityArray.BitMap.U8[20]) HighestActivePriority=20*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[20]]; else HighestActivePriority=21*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[21]]; } else { if(SysThrPriorityArray.BitMap.U8[22]) HighestActivePriority=22*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[22]]; else HighestActivePriority=23*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[23]]; } } } else if(SysThrPriorityArray.BitMap.U64[3]) { if(SysThrPriorityArray.BitMap.U32[6]) { if(SysThrPriorityArray.BitMap.U16[12]) { if(SysThrPriorityArray.BitMap.U8[24]) HighestActivePriority=24*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[24]]; else HighestActivePriority=25*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[23]]; } else { if(SysThrPriorityArray.BitMap.U8[26]) HighestActivePriority=26*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[26]]; else HighestActivePriority=27*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[27]]; } } else { if(SysThrPriorityArray.BitMap.U16[14]) { if(SysThrPriorityArray.BitMap.U8[28]) HighestActivePriority=28*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[28]]; else HighestActivePriority=29*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[29]]; } else { if(SysThrPriorityArray.BitMap.U8[30]) HighestActivePriority=30*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[30]]; else HighestActivePriority=31*8+SysThrBytePriority[SysThrPriorityArray.BitMap.U8[31]]; } } } return HighestActivePriority; }
忘记添加数组了
const SysU8 SysThrBytePriority[] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };