zoukankan      html  css  js  c++  java
  • 一种简单定长管理的内存池实现

    借鉴ucos消息队列中的实现,对内存池只提供信息的管理头部,由用户管理内存的分配与释放。

    借用了STL中的管理思路

    typedef union object_t
    {
        union object_t    *next;        //下一个对象
        char data[1];
    }object_t;

    注意其为union类型,next和data复用

    typedef struct ares_block
    {
        size_t object_size;        //单个对象的大小
        size_t block_size;            //占用的空间总数
        size_t count;                //剩余有多少个对象
        object_t *    free_list;        //空闲的对象块
        char *data;                    //实际指向缓冲区位置
        struct list_head list_block;//多个内存块
    }mem_block_t;

    基本的管理块 mem_block_t的接口函数。

    void memblock_init(mem_block_t    *block,size_t object_size,size_t buf_len,char *data);
    void memblock_destroy(mem_block_t *block);
    
    char *memblock_alloc(mem_block_t *block,size_t object_size);
    void memblock_dealloc(mem_block_t *block,char     *mem);

    初始化后的结构为

     用于管理mem_block_t 的内存池

    typedef struct ares_pool
    {
        size_t     pool_size;
        size_t     free_mem;
        size_t     total_size;
        object_t *    use_list;                //空闲的对象块;
        struct list_head block_list;    //多个内存池
    }mem_pool_t;

    对应的接口函数为

    void mempool_init(mem_pool_t *pool);
    void mempool_attach(mem_pool_t *pool,mem_block_t *block);
    void mempool_destroy(mem_pool_t *pool);
    
    char *mempool_alloc(mem_pool_t *pool,size_t object_size);
    
    void mempool_dealloc(mem_pool_t *pool,size_t object_size,char *mem);

    初始化后的结构,只有一个mem_block_t

    以上的结构,实现的思路为

    一个memblock管理有篇内存区域,它被分割为n个,用单链表的形式组织起来

    View Code
    void memblock_init(mem_block_t    *block,size_t object_size,size_t buf_len,char *data)
    {
        object_t    *object    =     (object_t    *)(data);
        block->free_list    =     object;
        while(++i < block->count)
        {
            data    +=object_size;
            object->next = (object_t    *)data;
            object = object->next;
        }
        object->next = 0;
    
    }

    block分配的时候,从中取出一块小内存,从free_list中删除一个链表节点即可

    memblock_alloc
    char *memblock_alloc(mem_block_t    *block,size_t object_size)
    {
        assert(block);
        object_t    *object;
        assert(object_size == block->object_size);
        if(block->free_list)
        {
            object    = block->free_list;
            block->free_list = object->next;
            --block->count;
        }
        return object?object->data:NULL;
    }

    释放即将内存块插入到free_list中

    memblock_dealloc
    void memblock_dealloc(mem_block_t    *block,char     *mem)
    {
        object_t     *object = (object_t *)mem;
        assert(block && object);
        if(block->free_list)
        {
            object->next = block->free_list;
            block->free_list  = object;
        }else{
            block->free_list = object;
        }
        ++block->count;
    }

    以上的block的思路。

    对于pool来说,基本上是转调block的接口函数。

    在pool中,block是按照object_size递增组织的(将STL中的数组用list组织)

    mempool_attach函数将一个block插入到相应的正确位置。

    mempool_alloc按照object_size查找block,然后调用memblock_alloc分配内存。

    同理mempool_dealloc类似。

    总结

    1.未考虑多线程的情况,这个需要在真实实现的时候加上互斥访问。

    2.这种方式组织的内存池,不是通用的内存池,实现只为满足特定的需求。

    3.内存池只提供信息头部来组织内存块,内存的分配与释放都由用户负责,用户可以预先建立几个经常使用的数据类型大小(或者如STL中,向上ROUND_UP多分配内存),

    4.每次只能分配一个object_size大小的内存,对于分配多个的需求暂时不支持——扩展开来需要再添加一个信息头类似(类似于pbuf了)。

  • 相关阅读:
    《C# to IL》第一章 IL入门
    multiple users to one ec2 instance setup
    Route53 health check与 Cloudwatch alarm 没法绑定
    rsync aws ec2 pem
    通过jvm 查看死锁
    wait, notify 使用清晰讲解
    for aws associate exam
    docker 容器不能联网
    本地运行aws lambda credential 配置 (missing credential config error)
    Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?
  • 原文地址:https://www.cnblogs.com/westfly/p/simplemempool.html
Copyright © 2011-2022 走看看