内存管理–位图BITMAP
位图,也就是 bitmap ,广泛用于资源管理,是 种管理资源的方式、 手段。“资源”包括很多,比如
内存或硬盘,对于此类大容量资源的管理 般都会采用位图的方式。
计算机中最小的数据单位是位,于是,用 组二进制位串来管理其他单位大小的资源是很自然的事,
这组 进制位中的每 位与其他资源中的数据单位都是一对 的关系,这实际就成了一种映射,即 map,
于是这组 进制位就有了更恰当的名字-一位图
内存管理中,1个bit代表4K.
管理内存的时候,我们会把内存分割成多个且每一个都是4K.然后用位图来管理内存的使用.
图中位图中的每一个小黑点就是1bit,代表的是一个4KB的内存大小.
位图相当于一组资源的映射。位图中的每 位和被管理的单位资源都是一对 的关系,故
位图主要用于管理容量较大的资源。
位图的定义与实现
struct bitmap {
uint32_t btmp_bytes_len;
uint8_t* bits;
};
//初始化位图的内存区域.
void bitmap_init(struct bitmap* btmap) {
memset(btmap->bits, 0, btmap->btmp_bytes_len);
}
/**
* 检测指定位是否为1,如果是,返回1.
*/
int bitmap_scan_test(struct bitmap* btmap, uint32_t index) {
uint32_t byte_index = (index / 8);
uint32_t bit_odd = byte_index % 8;
return (btmap->bits[byte_index] & BITMAP_MASK << bit_odd);
}
//保存状态
void bitmap_set(struct bitmap* btmap, uint32_t index, int8_t value) {
ASSERT(value == 0 || value == 1);
uint32_t byte_index = index / 8;
uint32_t bit_odd = byte_index % 8;
if (value) {
btmap->bits[byte_index] |= (BITMAP_MASK << bit_odd);
} else {
btmap->bits[byte_index] &= ~(BITMAP_MASK << bit_odd);
}
}
/**
* 在位图中申请连续的cnt个位.
*/
int bitmap_scan(struct bitmap* btmap, uint32_t cnt) {
uint32_t idx_byte = 0;
// 以字节为单位进行查找
while ((0xff == btmap->bits[idx_byte]) && idx_byte < btmap->btmp_bytes_len) {
++idx_byte;
}
// 没有找到
if (idx_byte == btmap->btmp_bytes_len) {
return -1;
}
// 找到了一个字节不全为1,那么在字节内部再次进行查找具体的起使位
int idx_bit = 0;
while ((uint8_t) BITMAP_MASK << idx_bit & btmap->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 = (btmap->btmp_bytes_len * 8 - bit_idx_start);
uint32_t count = 1;
uint32_t next_bit = bit_idx_start + 1;
bit_idx_start = -1;
while (bit_left-- > 0) {
if (!(bitmap_scan_test(btmap, next_bit))) {
++count;
} else {
count = 0;
}
if (count == cnt) {
bit_idx_start = (next_bit - cnt + 1);
break;
}
next_bit++;
}
return bit_idx_start;
}