博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
snort 内存池源码实现分析
阅读量:2791 次
发布时间:2019-05-13

本文共 5876 字,大约阅读时间需要 19 分钟。

源码mempool.h|c  sf_sdlist_types.h

内存池涉及几个动作 :初始化、分配、释放、销毁、清空

底层使用两个链表实现内存的分配used_list与释放回收free_list

int mempool_init(MemPool *mempool, PoolCount num_objects, size_t obj_size);int mempool_destroy(MemPool *mempool);MemBucket *mempool_alloc(MemPool *mempool);void mempool_free(MemPool *mempool, MemBucket *obj);int mempool_clean(MemPool *mempool);

数据结构

typedef unsigned int PoolCount;typedef struct _MemBucket{    /* 链表元素节点*/    SDListItem *key;    int used;    /* 用于存储datapool中单个元素的指针*/    void *data;} MemBucket;typedef struct _MemPool{    /* 分配的连续内存空间*/    void **datapool; /* memory buffer for MemBucket->data */    /* 桶数组  */    MemBucket *bucketpool; /* memory buffer */    /* 链表节点数组*/    SDListItem *listpool; /* list of things to use for memory bufs */    PoolCount total;    /* 这两个链表使用sf_sdlist_append 将listpool、bucketpool、datapool结合起来*/    /* 剩余多少*/    sfSDList free_list;    /* 使用多少 */    sfSDList used_list;    /* 元素大小*/    size_t obj_size;} MemPool;

snort的链表是一个双向链表,有时间在后面的博客会继续分析。

 

/* Function: int mempool_init(MemPool *mempool, *                            PoolCount num_objects, size_t obj_size) * * Purpose: initialize a mempool object and allocate memory for it * Args: mempool - pointer to a MemPool struct *       num_objects - number of items in this pool *       obj_size    - size of the items * * Returns: 0 on success, 1 on failure */int mempool_init(MemPool *mempool, PoolCount num_objects, size_t obj_size){    PoolCount i;    if(mempool == NULL)        return 1;    if(num_objects < 1)        return 1;    if(obj_size < 1)        return 1;    /* 单个元素的大小*/    mempool->obj_size = obj_size;    /* this is the basis pool that represents all the *data pointers       in the list */    /* 分配一块连续的空间,供内存池进行分配操作*/    mempool->datapool = calloc(num_objects, obj_size);    if(mempool->datapool == NULL)        return 1;    /* 分配对应num_objects个链表节点, 为后面构建两个分配和回收链表使用*/    mempool->listpool = calloc(num_objects, sizeof(SDListItem));    if(mempool->listpool == NULL)    {        /* well, that sucked, lets clean up */        ErrorMessage("%s(%d) mempool_init(): listpool is null\n",                     __FILE__, __LINE__);        mempool_free_pools(mempool);        return 1;    }    /* 每一个元素使用MemBucket进行封装管理, 一样分配num_objects个*/    mempool->bucketpool = calloc(num_objects, sizeof(MemBucket));    if(mempool->bucketpool == NULL)    {        ErrorMessage("%s(%d) mempool_init(): bucketpool is null\n",                     __FILE__, __LINE__);        mempool_free_pools(mempool);        return 1;    }    /* 初始化这两个内存管理链表*/    /* sets up the 2 memory lists */    if(sf_sdlist_init(&mempool->used_list, NULL))    {        ErrorMessage("%s(%d) mempool_init(): Failed to initialize used list\n",                     __FILE__, __LINE__);        mempool_free_pools(mempool);        return 1;    }    if(sf_sdlist_init(&mempool->free_list, NULL))    {        ErrorMessage("%s(%d) mempool_init(): Failed to initialize free list\n",                     __FILE__, __LINE__);        mempool_free_pools(mempool);        return 1;    }    /*  循环处理, 将被分割的内存使用bucket封装, 最后将bucket 放到链表节点SDListItem的data中加入到free_list的链表尾部*/    for(i=0; i
bucketpool[i]; itemp = &mempool->listpool[i]; /* each bucket knows where it resides in the list */ bp->key = itemp;#ifdef TEST_MEMPOOL printf("listpool: %p itemp: %p diff: %u\n", mempool->listpool, itemp, (((char *) itemp) - ((char *) mempool->listpool)));#endif /* 对连续内存进行切割使用*/ bp->data = ((char *) mempool->datapool) + (i * mempool->obj_size);#ifdef TEST_MEMPOOL printf("datapool: %p bp.data: %p diff: %u\n", mempool->datapool, mempool->datapool + (i * mempool->obj_size), (((char *) bp->data) - ((char *) mempool->datapool)));#endif /* 添加到free_list的尾部*/ if(sf_sdlist_append(&mempool->free_list, &mempool->bucketpool[i], &mempool->listpool[i])) { ErrorMessage("%s(%d) mempool_init(): Failed to add to free list\n", __FILE__, __LINE__); mempool_free_pools(mempool); return 1; } mempool->total++; } return 0;}

 

内存分配动作

/* Function: MemBucket *mempool_alloc(MemPool *mempool); * * Purpose: allocate a new object from the mempool * Args: mempool - pointer to a MemPool struct * * Returns: a pointer to the mempool object on success, NULL on failure */MemBucket *mempool_alloc(MemPool *mempool){    SDListItem *li = NULL;    MemBucket *b;    if(mempool == NULL)    {        return NULL;    }    /* get one item off the free_list,       put one item on the usedlist     */    /* 从回收链表free_list中拿掉一个节点*/    li = mempool->free_list.head;    if((li == NULL) || sf_sdlist_remove(&mempool->free_list, li))    {#ifdef TEST_MEMPOOL        printf("Failure on sf_sdlist_remove\n");#endif        return NULL;    }    /* 将从free_list中拿掉的节点加入used_list中, 进行管理,表明这个节点已使用*/    if(sf_sdlist_append(&mempool->used_list, li->data, li))    {#ifdef TEST_MEMPOOL        printf("Failure on sf_sdlist_append\n");#endif        return NULL;    }    /* 返回bucket指针, 将初始化的时候那块连续的内存的某一个对象的内存clean*/    /* TBD -- make configurable */    b = li->data;    bzero(b->data, mempool->obj_size);    return b;}

内存回收动作:

/* * 将要释放的对象从used_list中删除,然后添加到free_list中 */void mempool_free(MemPool *mempool, MemBucket *obj){    if ((mempool == NULL) || (obj == NULL))        return;    if(sf_sdlist_remove(&mempool->used_list, obj->key))    {#ifdef TEST_MEMPOOL        printf("failure on remove from used_list");#endif        return;    }    /* put the address of the membucket back in the list */    if(sf_sdlist_append(&mempool->free_list, obj, obj->key))    {#ifdef TEST_MEMPOOL        printf("failure on add to free_list");#endif        return;    }    return;}

内存的分配和释放,都是通过链表的插入删除,时间复杂度o(1)。由于snort使用的单进程单线程架构,不涉及到多线程操作,无需加锁。

转载地址:http://mvtmd.baihongyu.com/

你可能感兴趣的文章
qml中Control组件以及Style组件解析
查看>>
实现了一个类似微信好有列表的控件
查看>>
实现了一个可以滚动的文字控件
查看>>
自己重新定义的一个窗口控件
查看>>
关于typedef的用法
查看>>
CentOS6.5系统挂载NTFS分区的移动硬盘
查看>>
配置 yum 源的两种方法
查看>>
Unique Paths II
查看>>
Minimum Path Sum
查看>>
Maximum Subarray
查看>>
ACE Lock类介绍
查看>>
ACE_Task介绍
查看>>
mmap分析
查看>>
搞了个LAMP,没事也整理个问题集
查看>>
给你一段文章,Apache的日志分割和虚拟主机你还能不会?
查看>>
搞了Apache,怎么可能不搞搞Nginx呢?
查看>>
javascript调用微软CertEnroll实现CSP数字证书申请
查看>>
cookie实现本地数据存储
查看>>
Spring Boot添加DB2驱动
查看>>
log4j2小试
查看>>