接着上次的分析。我们顺着上次的思路分析,推倒出那个庞大的数组表。OSUnMapTbl,为什么数组元素是那样排列的,为什么要那样设计?
上篇讲到,每个任务的就绪态标志都放入就绪表中的,即两个全局变量OSRdyGrp和OSRdyTbl[]。在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl[]中的相应元素的相应位也置位。OSRdyGrp和OSRdyTbl[]的关系如下:
这里再引入一个功能数组,是起映射作用的。OSMapTbl这个数组出现的目的是为了更方便的置位。使用OSMapTbl[index]的作用是更方便的把某个数值的第index位置1。
即:
OSMapTbl[0]=00000001
OSMapTbl[1]=00000010
OSMapTbl[2]=00000100
………….
OSMapTbl[7]=10000000
1设置就绪:
OSRdyGrp |= OSMapTbl[prio >> 3]; //找到优先级所在分组,并将OSRdyGrp中对应该分组的位置1
OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];//把OSRdyTbl[]中对应优先级的位置1
Eg:
假如第一个任务,Prio=23, prio >> 3后就为2, OSMapTbl[2]= 00000100; OSRdyGrp=00000100
prio &111=111,OSRdyTbl[2]=111;
假如第一个任务,Prio=6 prio >> 3后就为0, OSMapTbl[0]= 00000001; OSRdyGrp=00000101
prio &111=110,OSRdyTbl[2]=110;
………..
依此类算…..
2查找
y= OSUnMapTbl[OSRdyGrp];//查找OSUnMapTbl[]找到优先级最高的进程所在的分组
x= OSRdyTbl[y];//x是最高优先级进程所在分组的就绪状态
p= (y << 3) + OSUnMapTbl[x]; //p=y*8+最高优先级进程所在分组内的位置,P即为查找的最高优先级
eg:假如已经有23和6优先级就绪,那么怎么查到是6呢?
首先,肯定一点要从最小组里找,因为组越小,优先级值越小,优先级越大。那么首先要找到0。因为6是在第0组的。
通过查表OSUnMapTbl[OSRdyGrp],查到OSRdyGrp最低位为1的这个组就是最高优先级组。
具体来说,OSRdyGrp=00000101,最低位是0位,那么第0组就存在就绪任务,而且是优先级最高的组,言外之意是,优先级最高的任务在这一组。
我们可以假设一下:
若OSRdyGrp=00001100呢?那么优先级最高的组就是第3组,因为从3位开始为1;
若OSRdyGrp=00001010呢?那么优先级最高的组就是第2组,因为从2位开始为1;
若OSRdyGrp=01001010呢?那么优先级最高的组就是第2组,因为从2位开始为1;
我可以猜想,OSUnMapTbl[OSRdyGrp]就是为了找出OSRdyGrp在二进制形式下,第多少位开始为1的。不信可以查一下OSUnMapTbl这个表:(见文章后的附表,从原码里copy的)
OSRdyGrp=00001100,即OSRdyGrp =0x0C,OSUnMapTbl[0x0C]=2;
OSRdyGrp=00001010,即OSRdyGrp =0x0A,OSUnMapTbl[0x0A]=1;
OSRdyGrp=01001010,即OSRdyGrp =0X4A,OSUnMapTbl[0X4A]=1;
查完了组,就要查组里的8个位,原理和查组一样。删除的问题也很好理解了。
3删除
if ((OSRdyTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0)
//若优先级所在分组没有其他就绪任务
OSRdyGrp &= ~OSMapTbl[prio >> 3];
OK,基本就是这样。
附上OSUnMapTbl表:
INT8UconstOSUnMapTbl[256] = {
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0x00 to 0x0F*/
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0x10 to 0x1F*/
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0x20 to 0x2F*/
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0x30 to 0x3F*/
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0x40 to 0x4F*/
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0x50 to 0x5F*/
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0x60 to 0x6F*/
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0x70 to 0x7F*/
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0x80 to 0x8F*/
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0x90 to 0x9F*/
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0xA0 to 0xAF*/
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0xB0 to 0xBF*/
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0xC0 to 0xCF*/
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0xD0 to 0xDF*/
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0xE0 to 0xEF*/
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0/* 0xF0 to 0xFF*/
};