| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- #include "bitmap.h"
- #include "../string.h"
- #include "../../kernel/debug.h"
- void bitmap_init(Bitmap *pb)
- {
- _memset(pb->bits, 0, pb->btmp_bytes_len);
- }
- bool bitmap_scan_test(Bitmap *pb, uint32_t bit_idx)
- {
- // 判断位图中 bit_idx 位是否为 1
- uint32_t byte_idx = bit_idx / 8; // 向下取整用于索引数组下标
- uint32_t bit_odd = bit_idx % 8; // 取余用于索引数组内的位
- return (pb->bits[byte_idx] & (BITMAP_MASK << bit_odd));
- }
- // 在位图中申请连续 cnt 个位,成功则返回起始位下标,失败返回-1
- int bitmap_scan(Bitmap *pb, uint32_t cnt)
- {
- uint32_t idx_byte = 0; // 用于记录空闲位所在的字节
- while ((0xff == pb->bits[idx_byte]) && (idx_byte < pb->btmp_bytes_len))
- { // 如果字节为 0xff,表示该字节已经被占用,继续向下一个字节查找
- idx_byte++;
- }
- ASSERT(idx_byte < pb->btmp_bytes_len);
- if (idx_byte == pb->btmp_bytes_len)
- { // 该内存池找不到可用空间
- return -1;
- }
- // 若在位图数组范围内的某字节内找到了空闲位,则在字节内逐位查找空闲位的索引
- int idx_bit = 0;
- // 和 pb->bits[idx_byte] 这个字节逐位对比
- while ((uint8_t)(BITMAP_MASK << idx_bit) & pb->bits[idx_byte])
- { // 1 << idx_bit 生成 00010000 这样的数,和 pb->bits[idx_byte]逐位与操作
- idx_bit++;
- }
- int bit_idx_start = idx_byte * 8 + idx_bit; // 空闲位在位图内的下标
- if (cnt == 1)
- {
- return bit_idx_start;
- }
- uint32_t bit_left = (pb->btmp_bytes_len * 8 - bit_idx_start); // 记录还有多少位可以判断
- uint32_t next_bit = bit_idx_start + 1;
- uint32_t count = 1; // 用于记录找到的空闲位的个数
- bit_idx_start = -1; // 先将其置为-1,若找不到连续的位就直接返回
- while (bit_left-- > 0)
- {
- if (!(bitmap_scan_test(pb, next_bit)))
- { // 若 next_bit 为 0
- count++;
- }
- else
- {
- count = 0;
- }
- if (count == cnt)
- { // 若找到连续的 cnt 个空闲位
- bit_idx_start = next_bit - cnt + 1;
- break;
- }
- next_bit++;
- }
- return bit_idx_start;
- }
- void bitmap_set(Bitmap *pb, uint32_t bit_idx, int8_t value)
- {
- ASSERT((value == 0) || (value == 1));
- uint32_t byte_idx = bit_idx / 8; // 向下取整用于索引数组下标
- uint32_t bit_odd = bit_idx % 8; // 取余用于索引数组内的位
- if (value)
- { // 若 value 为 1, 则 OR 1 到 bitmap[byte_idx] 的 bit_odd 位上
- pb->bits[byte_idx] |= (BITMAP_MASK << bit_odd);
- }
- else
- { // 若 value 为 0, 则 AND 0 到 bitmap[byte_idx] 的 bit_odd 位上
- pb->bits[byte_idx] &= ~(BITMAP_MASK << bit_odd);
- }
- }
|