21 Star 84 Fork 34

Phytium嵌入式软件 / Phytium-Standalone-SDK

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
fmemory_pool.md 6.10 KB
一键复制 编辑 原始数据 按行查看 历史
liushengming 提交于 2023-08-24 07:21 . !84v1.2.0 master

Memory pool

1. 概述

内存池 (Memory Pool)是一种内存分配方式,是为了减少频繁使用 malloc/free new/delete 等系统调用而造成的性能损耗而设计的,具有效率高、内存碎片少和防止内存泄漏等特性。内存池根据实际需要,在初始状态获取一大块内存(堆区或者静态内存),然后划分成若干内存页,进行管理,将内存页中的块传递给申请者使用。SDK中采用TLSF内存分配器管理,专门设计用于满足实时要求。

TLSF (Two-Level Segregated Fit memory allocator), 是一款通用的动态内存分配器,具有以下特点,

  • malloc,free,realloc,memalign的算法复杂度变为O(1)
  • 每次分配的开销极低(4字节)
  • 低碎片化
  • 支持动态添加和删除内存池区域

TLSF主要采用两级位图(Two-Level Bitmap)与分级空闲块链表(Segregated Free List)的数据结构管理动态内存池(memory pool)以及其中的空闲块(free blocks),用Good-Fit的策略进行分配。

TLSF算法分配速度不一定快,只是说能保证分配的时间是个常数(malloc不能保证)。

TLSF也叫多内存堆管理算法,支持动态增加或者删除多块不连续的内存,将它们作为一个内存堆使用。

2. 功能

FMemory Pool主要完成内存池的初始化,为用户提供多种内存申请方法,支持内存池的使用情况监测,

  • 初始化内存池
  • 删除内存池
  • 申请一段空间(不要求对齐)
  • 按指定字节数申请一段对齐的内存
  • 申请一段数组,返回被清零的空间
  • 回收原来申请的空间并重新分配
  • 跟踪当前内存池的使用情况

相关源文件为:

fmempory_pool
    ├── fmempory_pool.c
    └── fmempory_pool.h
tlsf
    ├── tlsf.c
    └── tlsf.h

3. 配置方法

以下部分将指导您完成 FMemory Pool 的软件配置:

  • 使能TLSF组件

4. 应用示例

memory pool

5. API参考

5.1. 用户数据结构

  • common/fmempory_pool.h
typedef struct
{
    pool_t     pool_addr;
    FSListNode list;
} FMempPoolList; /* 内存池控制数据 */

typedef struct
{
    FMempPoolList *pools_list;   /* 内存池链表 */
    tlsf_t         tlsf_ptr;     /* tlsf内存池 */
    u32            is_ready;     /* 内存池初始化完成标志 */
} FMemp; /* 内存池控制数据 */

5.2 错误码定义

  • 模块错误码编号 0x0010000

  • [0x0] FMEMP_SUCCESS : success

  • [0x0010000] FMEMP_ERR_INVALID_BUF : 输入的内存池缓存区不合法

  • [0x0010001] FMEMP_ERR_INIT_TLFS : 初始化TLFS内存池失败

  • [0x0010002] FMEMP_ERR_BAD_MALLOC : 从TLFS内存池分配空间失败

5.3. 用户API接口

FMempInit

  • 初始化内存池, 分配内存池的内存空间
FError FMempInit(FMemp *memp, void *begin_addr, void *end_addr);

Note:

  • begin_addr end_addr 指向为内存池指定的缓冲区的起止地址

Input:

  • {FMemp} *memp, 内存池的控制数据
  • {void} *begin_addr, 分配给内存池的空间起始地址
  • {void} *end_addr, 分配给内存池的空间结束地址

Return:

  • {FError} FMEMP_SUCCESS表示初始化成功,返回其它值表示初始化失败

FMempRemove

  • 释放所有分配的内存,删除内存池
void FMempRemove(FMemp *memp);

Note:

  • 需要初始化后才能调用,调用此函数后,内存池分配的空间不再能使用

Input:

  • {FMemp} *memp 内存池控制数据

Return:

FMempMalloc

  • 从内存池申请一段空间
void *FMempMalloc(FMemp *memp, fsize_t nbytes);

Note:

  • 需要初始化后才能调用,申请的空间再不再使用后需要调用FMempFree释放

Input:

  • {FMemp} *memp 内存池控制数据
  • {fsize_t} nbytes 申请的字节数

Return:

  • {void *} 申请到的空间,如果申请失败,返回NULL

FMempCalloc

  • 从内存池申请一段数组空间并清零
void *FMempCalloc(FMemp *memp, fsize_t count, fsize_t size)

Note:

  • 需要初始化后才能调用,申请的空间再不再使用后需要调用FMempFree释放

Input:

  • {FMemp} *memp 内存池控制数据
  • {fsize_t} count 数据成员格式
  • {fsize_t} size 单个数据成员的字节数

Return:

  • {void *} 申请到的空间,如果申请失败,返回NULL

FMempMallocAlign

  • 按指定对齐方式申请一段空间
void *FMempMallocAlign(FMemp *memp, fsize_t size, fsize_t align);

Note:

  • 需要初始化后才能调用,申请的空间再不再使用后需要调用FMempFree释放

Input:

  • {FMemp} *memp 内存池控制数据
  • {fsize_t} size 申请的字节数
  • {fsize_t} align 对齐字节数

Return:

  • {void *} 申请到的空间,如果申请失败,返回NULL

FMempRealloc

  • 回收原来申请的空间并重新分配
void *FMempRealloc(FMemp *memp, void *ptr, fsize_t nbytes);

Note:

  • 需要初始化后才能调用,申请的空间再不再使用后需要调用FMempFree释放,调用函数后,原来的空间不再能使用,原空间的数据被移动到返回指针指向的空间

Input:

  • {FMemp} *memp 内存池控制数据
  • {void} *ptr 原来的空间
  • {fsize_t} nbytes 新申请的字节数

Return:

  • {void *} 替换后空间,如果替换失败,返回NULL

FMempFree

  • 释放一段从内存池申请的空间
void FMempFree(FMemp *memp, void *ptr);

Note:

  • 需要初始化后才能调用,传入的指针需要是FMempMalloc/FMempCalloc/FMempMallocAlign/FMempRealloc返回的

Input:

  • {FMemp} *memp 内存池控制数据
  • {void} *ptr 待释放的空间地址

Return:

FMemProbe

  • 跟踪当前内存池的使用情况
void FMemProbe(FMemp *memp, u32 *total, u32 *used, u32 *max_used);

Note:

  • 需要初始化后才能调用

Input:

  • {FMemp} *memp 内存池控制数据
  • {u32} *total 总可用字节数
  • {u32} *used 已使用字节数
  • {u32} *max_used 已使用字节数的峰值

Return:

FMemListAll

  • 打印当前分配的内存块信息
void FMemListAll(FMemp *memp);

Note:

  • 需要初始化后才能调用

Input:

  • {FMemp} *memp 内存池控制数据

Return:

C
1
https://gitee.com/phytium_embedded/phytium-standalone-sdk.git
git@gitee.com:phytium_embedded/phytium-standalone-sdk.git
phytium_embedded
phytium-standalone-sdk
Phytium-Standalone-SDK
master

搜索帮助