内存管理系统之位图及其函数的实现

位图

  位图,位是指1位,图是指map,地图。地图本质上就是映射的意思。综合起来,位图就是用字节中的一位来映射其他单元大小的资源。
  为什么要用位图呢?因为在资源管理中,管理结构中的数据也有自己的单位大小,被管理的资源也有自己的单位大小,故有效减少管理成本的方法是使管理结构中的单位达到最小,其所管理资源的单位调整到最大。此类典型的案例很多,比如一个足球大小的地球仪代表整个地球。
  计算机中最小的数据单位是位,于是,用一种二进制串来管理其他单位大小的资源就成了很自然的是,而且在这个串中,每个位和资源都是1对1的映射关系,所以就叫做位图了。
  内存管理系统中位图中的每一位用来表示物理内存中的4kb,也就是一页。

#define BITMAP_MASK 1
struct bitmap {
    uint32_t btmp_bytes_len;
    uint8_t *bits;
};
//将位图bitmap初始化
void bitmap_init(struct bitmap *btmp);
//判断bit_idx位是否等于1,若为1,返回true,否则返回false
bool bitmap_scan_test(struct bitmap *btmp, uint32_t bit_idx);
//在位图中连续申请cnt个位,成功返回下标,失败返回-1
int bitmap_scan(struct bitmap *btmp, uint32_t cnt);
//将位图btmp的bit_idx位设置为value
void bitmap_set(struct bitmap *btmp, uint32_t bit_idx, int8_t value);

void bitmap_init(struct bitmap *btmp){
    memset(btmp->bits, 0 ,btmp->btmp_bytes_len);
}

bool bitmap_scan_test(struct bitmap *btmp, uint32_t bit_idx){
    uint32_t byte_idx = bit_idx / 8;
    uint32_t bit_odd = bit_idx % 8;
    return (btmp->bits[byte_idx]) & (BITMAP_MASK << bit_odd);
}  

int bitmap_scan(struct bitmap *btmp, uint32_t cnt){
    uint32_t idx_byte = 0;
    while((0xff == btmp->bits[idx_byte]) && (idx_byte < btmp->btmp_bytes_len)){
	  ++idx_byte;
    }

    ASSERT(idx_byte < btmp->btmp_bytes_len);
    //内存池中已无可用空间
    if(idx_byte == btmp->btmp->bytes_len){
	    return -1;
    }

    int idx_bit = 0;
    while((uint8_t)(BITMAP_MASK << idx_bit) & btmp->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 = (btmp->btmp_bytes_len * 8 - bit_idx_start);
    uint32_t next_bit = bit_idx_start + 1;
    uint32_t count = 1;

    bit_idx_start = -1;
    while(bit_left-- > 0){
	    if(!(bitmap_scan_test(btmp, next_bit))){
		    ++count;
	    } else {
		    count = 0;
	    }
	    if(count == cnt){
		    bit_idx_start = next_bit - cnt + 1;
		    break;
	    }
	    ++next_bit;
      }
    return bit_idx_start;
  }

void bitmap_set(struct bitmap *btmp, 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){
	    btmp->[byte_idx] |= (BITMAP_MASK << bit_odd);
    } else {
	    btmp->[byte_idx] &= ~(BITMAP_MASK << bit_odd);
        }
}
posted @ 2021-03-08 10:35  江安躺平侠  阅读(307)  评论(0)    收藏  举报