172 lines
3.9 KiB
C
172 lines
3.9 KiB
C
/**
|
|
* 日期: 2026-03-22
|
|
* 作者: coffee
|
|
* 描述: 参考 TLSF 算法实现的轻量内存池
|
|
*
|
|
* 设计目标:
|
|
* 1. 不依赖系统堆, 仅管理外部传入的固定内存
|
|
* 2. 保留 TLSF 双层索引和 O(1) 分配/释放特性, 适合高频小块分配
|
|
* 3. 接口保持精简, 统计信息在运行期增量维护, 兼顾查询性能和实现可维护性
|
|
* 4. 不直接依赖外部 tlsf.c/tlsf.h, 便于工程内裁剪和维护
|
|
*
|
|
* 可选配置:
|
|
* - HTLSF_CONFIG_SL_INDEX_COUNT_LOG2: 二级索引数量对数, 默认4(即16组), 不建议低于4
|
|
* - HTLSF_CONFIG_FL_INDEX_MAX: 最大一级索引位数, 默认15(支持32KB块)
|
|
* - HTLSF_DEBUG: 开启内部断言检查, 便于调试, 会增大代码体积
|
|
*/
|
|
|
|
#ifndef __H_TLSF_H__
|
|
#define __H_TLSF_H__
|
|
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
|
|
typedef struct HTlsf
|
|
{
|
|
void *mem; ///< 对齐后的控制区起始地址
|
|
size_t memSize; ///< 对齐后可用于 HTlsf 的大小
|
|
} HTlsf;
|
|
|
|
typedef void (*HTlsfWalk)(void *ptr, size_t size, uint8_t used, void *arg);
|
|
|
|
/**
|
|
* @brief TLSF 对齐大小
|
|
*/
|
|
size_t HTlsfAlignSize(void);
|
|
|
|
/**
|
|
* @brief 每次分配的最小额外开销
|
|
*/
|
|
size_t HTlsfAllocOverhead(void);
|
|
|
|
/**
|
|
* @brief 池管理额外开销
|
|
*/
|
|
size_t HTlsfPoolOverhead(void);
|
|
|
|
/**
|
|
* @brief 初始化所需的最小原始内存大小
|
|
*
|
|
* 说明:
|
|
* 返回值已包含最坏情况下的对齐填充, 可直接用于申请外部缓冲区大小
|
|
*/
|
|
size_t HTlsfMinBufferSize(void);
|
|
|
|
/**
|
|
* @brief 初始化所需的最大原始内存大小
|
|
*
|
|
* 说明:
|
|
* 返回值已包含最坏情况下的对齐填充
|
|
*/
|
|
size_t HTlsfMaxBufferSize(void);
|
|
|
|
/**
|
|
* @brief 初始化 TLSF 内存池
|
|
* @param htlsf 上下文
|
|
* @param mem 外部缓冲区
|
|
* @param size 缓冲区大小
|
|
* @return 成功返回1, 失败返回0
|
|
*/
|
|
uint8_t HTlsfInit(HTlsf *htlsf, void *mem, size_t size);
|
|
|
|
/**
|
|
* @brief 判断是否已初始化完成
|
|
*/
|
|
uint8_t HTlsfIsReady(const HTlsf *htlsf);
|
|
|
|
/**
|
|
* @brief 重置内存池, 释放所有已分配块
|
|
*
|
|
* 说明:
|
|
* 不释放外部缓冲区, 仅重新构建 TLSF 控制结构
|
|
*/
|
|
uint8_t HTlsfReset(HTlsf *htlsf);
|
|
|
|
/**
|
|
* @brief 获取当前池的可管理容量
|
|
*
|
|
* 说明:
|
|
* 返回值为池内可参与分配的块大小总和, 不包含控制结构和池头开销
|
|
*/
|
|
size_t HTlsfGetCapacity(const HTlsf *htlsf);
|
|
|
|
/**
|
|
* @brief 申请内存
|
|
*/
|
|
void *HTlsfMalloc(HTlsf *htlsf, size_t size);
|
|
|
|
/**
|
|
* @brief 申请并清零内存
|
|
*/
|
|
void *HTlsfCalloc(HTlsf *htlsf, size_t num, size_t size);
|
|
|
|
/**
|
|
* @brief 对齐申请内存
|
|
* @param align 对齐字节数, 必须是2的幂
|
|
*/
|
|
void *HTlsfMemalign(HTlsf *htlsf, size_t align, size_t size);
|
|
|
|
/**
|
|
* @brief 重分配内存
|
|
*
|
|
* 说明:
|
|
* 与标准 realloc 行为一致:
|
|
* - ptr == NULL 等价 malloc
|
|
* - size == 0 等价 free 并返回NULL
|
|
*/
|
|
void *HTlsfRealloc(HTlsf *htlsf, void *ptr, size_t size);
|
|
|
|
/**
|
|
* @brief 释放内存
|
|
*/
|
|
void HTlsfFree(HTlsf *htlsf, void *ptr);
|
|
|
|
/**
|
|
* @brief 获取块大小
|
|
*
|
|
* 说明:
|
|
* 返回 TLSF 内部块大小, 不是原始请求大小
|
|
*/
|
|
size_t HTlsfBlockSize(const void *ptr);
|
|
|
|
/**
|
|
* @brief 获取已用块大小总和
|
|
*
|
|
* 说明:
|
|
* 返回 TLSF 内部块大小总和, 用于观察碎片和负载
|
|
* 该值由运行期缓存维护, 查询为 O(1)
|
|
*/
|
|
size_t HTlsfGetUsedSize(const HTlsf *htlsf);
|
|
|
|
/**
|
|
* @brief 获取空闲块大小总和
|
|
*
|
|
* 说明:
|
|
* 返回 TLSF 内部块大小总和
|
|
* 该值由运行期缓存维护, 查询为 O(1)
|
|
*/
|
|
size_t HTlsfGetFreeSize(const HTlsf *htlsf);
|
|
|
|
/**
|
|
* @brief 获取当前最大连续空闲块
|
|
*
|
|
* 说明:
|
|
* 常见场景下为 O(1), 当最大空闲块刚被摘链时会按最高非空桶惰性刷新
|
|
*/
|
|
size_t HTlsfGetMaxFreeBlock(const HTlsf *htlsf);
|
|
|
|
/**
|
|
* @brief 遍历所有块
|
|
*/
|
|
void HTlsfWalkPool(const HTlsf *htlsf, HTlsfWalk call, void *arg);
|
|
|
|
/**
|
|
* @brief 检查 TLSF 内部一致性
|
|
* @return 正常返回1, 异常返回0
|
|
*/
|
|
uint8_t HTlsfCheck(const HTlsf *htlsf);
|
|
|
|
#endif // __H_TLSF_H__
|