内存管理--位图BITMAP

内存管理–位图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;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
通过把nginx slab的精简,把需要的头文件单独整理出来,增加了main方法,可以单独运行,代码包含了大量的中文注释,方便了了解和学习slab的运行机制 int main(int argc, char **argv) { ngx_log_t log; ngx_shm_t shm; ngx_slab_pool_t *shpool; char *ssl_session[10]; int n; ngx_pid = ngx_getpid(); memset(&log;, 0, sizeof(ngx_log_t)); memset(&shm;, 0, sizeof(ngx_shm_t)); shm.size = 512000; ngx_pagesize_shift = 0; ngx_pagesize = getpagesize(); for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ } printf("--%d\n", 1 << ngx_pagesize_shift); if (ngx_shm_alloc(&shm;) != NGX_OK) { return 1; } if (ngx_init_zone_pool(&log;, &shm;)) { return 1; } shpool = (ngx_slab_pool_t *) shm.addr; ssl_session[0] = (char *) ngx_slab_alloc_locked(shpool, 12); ssl_session[0] = (char *) ngx_slab_calloc(shpool, 56); ssl_session[1] = (char *) ngx_slab_alloc_locked(shpool, 14); ssl_session[2] = (char *) ngx_slab_alloc_locked(shpool, 11); ngx_slab_free(shpool, ssl_session[2]); ngx_slab_free(shpool, ssl_session[0]); ssl_session[2] = (char *) ngx_slab_alloc_locked(shpool, 65); return 0; } nginx的slab的内存管理方式,这种方式的内存管理在nginx中,主要是与nginx 的共享内存协同使用的。nginx的slab管理与linux的slab管理相同的地方在于均是利用了内存 的缓存与对齐机制,slab内存管理中一些设计相当巧妙的地方,也有一些地方个人感觉设计 不是很完美,或许是作为nginx设计综合考虑的结果。 nginx slab实现中的一大特色就是大量的位操作,这部分操作很多是与slot分级数组相关的。 为方便描述下面做一些说明: 1.将整个slab的管理结构称slab pool. 2.将slab pool前部的ngx_slab_pool_t结构称slab header. 3.将管理内存分级的ngx_slab_page_t结构称slot分级数组. 4.将管理page页使用的ngx_slab_page_t结构称slab page管理结构. 5.将具体page页的存放位置称pages数组. 6.将把page分成的各个小块称为chunk. 7.将标记chunk使用的位图结构称为bitmap.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值