另一种轻量级内存池介绍

2023-03-07 17:18:17 浏览数 (1)

前几天在阅读源码中tcp session模块的时候,发现一个valloc相关的内存分配器。暂时还未了解具体的应用场景,今天就来简单剖析一下源码吧。

相关结构体描述

主要有2个结构体:

clib_

注意: 通过上述几个api接口,只运行添加内存chunk,不能对内存chunk进行删除。所以需要使用者合理的添加内存。

_main_t :内存分配管理结构体;

clib_valloc_chunk_t:内存块结构;

具体介绍如下:

接口api

1、向虚拟分配管理区添加一块内存区

代码语言:javascript复制
void clib_valloc_add_chunk (clib_valloc_main_t * vam,
 clib_valloc_chunk_t * template)

参数说明: 1、clib_valloc_main_t * vam :指向内存分配器管理结构指针。 2、clib_valloc_chunk_t * template :指向内存块chunk的指针,该chunk块描述要添加的虚拟地址的基地址及大小。 功能描述: 1、首先进行加锁,读取管理结构的头节点索引,如果索引为全ff,直接从pool池获取内存chunk,并设置hash,解锁返回。 2、如果不全ff,获取头节点内存chunk。如果添加基地址是否大于链表头节点的基地址。将当前设置为头节点,设置hash<基地址,pool索引>,并更新管理结构头节点索引。否则添加到双向链表尾部。

疑问? 1、添加内存chunk时,为什么需要判断基地址的大小?而且加到头节点?

2、内存分配器管理结构初始化

代码语言:javascript复制
void clib_valloc_init (clib_valloc_main_t * vam, clib_valloc_chunk_t * template,int need_lock)

参数说明: 1、clib_valloc_main_t * vam :指向内存分配器管理结构指针。 2、clib_valloc_chunk_t * template :指向内存块chunk的指针,该chunk块描述要添加的虚拟地址的基地址及大小。 3、int need_lock:是否需要加锁,多线程模式。 功能描述: 1、对管理结构进行初始化操作,成员进行赋值。 2、调用clib_valloc_add_chunk接口添加内存块。

3、从内存管理结构中申请内存。

代码语言:javascript复制
uword
clib_valloc_alloc (clib_valloc_main_t * vam, uword size,
           int os_out_of_memory_on_failure)

参数说明: 1、clib_valloc_main_t * vam :指向内存分配器管理结构指针。 2、uword size:申请空间的大小。 3、os_out_of_memory_on_failure:内存不足时,是否需要产生异常。 功能描述: 1、尝试进行加锁,获取管理结构头节点索引。 2、遍历双向链表,找到空闲状态内存chunk且满足申请大小。如果内存chunk大小大于申请大小,对内存chunk分割,分割后的chunk添加到当前节点后面。解锁后返回内存首地址。

注意,双向链表的节点顺序不能随意变更。否则free后无法进行合并。

4 内存释放到内存管理结构

代码语言:javascript复制
uword
clib_valloc_free (clib_valloc_main_t * vam, uword baseva)

参数说明: 1、clib_valloc_main_t * vam :指向内存分配器管理结构指针。 2、uword baseva:内存地址。 功能说明: 1、通过baseva地址,hash得到pool索引,找到内存chunk。 2、判断当前内存chunk前后地址连续且处于空闲状态进行合并处理。

注意: 通过上述几个api接口,只运行添加内存chunk,不能对内存chunk进行删除。所以需要使用者合理的添加内存。

总结

本文只简单描述了内存管理的结构及相关接口api,对这种内存分配器的使用场景还不熟悉,待后续补充。

0 人点赞