位图还是比较简单的,他要解决找第一个1的问题。
比如有一个32bit的数据,0xFF00000000,从低位开始,他的第一个1是在24位,那么返回值就是24,这个机制是用在任务优先级的某些机制上的。
这个怎么实现呢,循环移位其实是很容易实现的,但是太慢,因为这个机制会经常用到,所以要搞一个简单的方式。所以用倒推的方式,做了一个表格来实现这个功能。表格怎么做呢?
1、把32位分成了4个8位进行查找
2、先找到不为0的那段8个
3、这段8个有256个数字,0x0-0xFF,这个256个数字,第1个1,出现在哪里,都是可以算出来的,然后就可以填到表格里面去了。
4、在利用这个表格计算的时候,所有这4个8段,都是一样的,然后加上偏移值,就可以算出第一个1的位置了。
if (bitmap->bitmap & 0xFF) { return quickFindTable[bitmap->bitmap & 0xFF]; } else if (bitmap->bitmap & 0xFF00) { return quickFindTable[(bitmap->bitmap >> 8) & 0xFF] + 8; } else if (bitmap->bitmap & 0xFF0000) { return quickFindTable[(bitmap->bitmap >> 16) & 0xFF] + 16; } else if (bitmap->bitmap & 0xFF000000) { return quickFindTable[(bitmap->bitmap >> 24) & 0xFF] + 24; } else { return tBitmapPosCount(); }
比如这个32位的值是FF110000,那么需要查找quickFindTable表格中第0x11个,也就是第17个数字,然后再加上16。其实我们已经知道了0xFF110000,他的第一个1出现在第16位,那么这个表格的第17个值,就是0。这个表格就是这么反推形成的。ucOS用的就是类似的位图。