1. 增加内存分配器

This commit is contained in:
coffee 2026-04-01 15:16:23 +08:00
parent 9cebbd2bc7
commit da4f8f8d23
4 changed files with 417 additions and 0 deletions

101
include/HMem.h Normal file
View File

@ -0,0 +1,101 @@
/**
* : 2026-03-31
* : coffee
* : HTlsf
*
*
*/
#ifndef _H_MEM_H_
#define _H_MEM_H_
#include <stdint.h>
#include <stddef.h>
/**
* @brief
* @param buffer
* @param size
* @return 1, 0
*/
uint8_t HMemInit(void *buffer, size_t size);
/**
* @brief
*/
uint8_t HMemIsReady(void);
/**
* @brief
* @param size
* @return , NULL
*/
void *HMemMalloc(size_t size);
/**
* @brief
* @param num
* @param size
* @return , NULL
*/
void *HMemCalloc(size_t num, size_t size);
/**
* @brief
* @param ptr
* @param size
* @return , NULL ()
*/
void *HMemRealloc(void *ptr, size_t size);
/**
* @brief (0)
* @param ptr
* @return 1, 0
*/
uint8_t HMemFree(void *ptr);
/**
* @brief
* @param ptr ()
* @param size HMem
* @return
* - HMem , ptr (+1)
* - , ()
* - NULL
*/
void *HMemAddRef(void *ptr, size_t size);
/**
* @brief
* @param ptr
* @return , HMem 0
*/
uint32_t HMemGetRefCount(void *ptr);
/**
* @brief HMem
* @param ptr
* @return 1, 0
*/
uint8_t HMemIsManaged(void *ptr);
/**
* @brief
*/
size_t HMemGetFreeSize(void);
/**
* @brief 使
*/
size_t HMemGetUsedSize(void);
/**
* @brief
*/
size_t HMemGetCapacity(void);
#endif // _H_MEM_H_

View File

@ -54,6 +54,14 @@ size_t HTlsfPoolOverhead(void);
*/
size_t HTlsfMinBufferSize(void);
/**
* @brief
*
* :
*
*/
size_t HTlsfMaxBufferSize(void);
/**
* @brief TLSF
* @param htlsf

303
src/HMem.c Normal file
View File

@ -0,0 +1,303 @@
/**
* : 2026-03-31
* : coffee
* : HTlsf
* 4使
*/
#include "HMem.h"
#include "HTlsf.h"
#include <string.h>
#ifndef LogD
#define LogD(...)
#endif
/*
* (4):
* - userSize: 16 bits, ( 65535 )
* - magic: 10 bits, (0x2AA = 0b1010101010)
* - refCount: 6 bits, ( 63)
*/
#define HMEM_MAGIC_VALUE 0x2AAu
#define HMEM_REFCOUNT_MAX 63u
#define HMEM_SIZE_MAX 65535u
typedef struct __attribute__((packed)) HMemHeader {
uint16_t userSize; /* 用户请求大小 */
uint16_t refCount :6; /* 引用计数 */
uint16_t magic :10; /* 魔数 */
} HMemHeader;
#define HMEM_HEADER_SIZE sizeof(HMemHeader)
/* 编译期确保头部大小为4字节 */
typedef char HMemHeaderSizeCheck[HMEM_HEADER_SIZE == 4 ? 1 : -1];
/* 对齐辅助 */
#define HMEM_ALIGN_SIZE sizeof(void*)
#define HMEM_ALIGN_UP(x) (((x) + HMEM_ALIGN_SIZE - 1) & ~(HMEM_ALIGN_SIZE - 1))
#define HMEM_USER_OFFSET HMEM_ALIGN_UP(HMEM_HEADER_SIZE)
/* 全局单例 */
static HTlsf sTlsf;
static uint8_t PtrMayBeInPool(const void *ptr) {
if (!HTlsfIsReady(&sTlsf) || ptr == NULL) {
return 0;
}
uintptr_t poolStart = (uintptr_t)sTlsf.mem;
uintptr_t poolEnd = poolStart + sTlsf.memSize;
uintptr_t userPtr = (uintptr_t)ptr;
return userPtr >= (poolStart + HMEM_USER_OFFSET) && userPtr < poolEnd;
}
static HMemHeader *GetHeader(const void *ptr) {
if (ptr == NULL) {
return NULL;
}
if (!PtrMayBeInPool(ptr)) {
return NULL;
}
return (HMemHeader *)((uint8_t *)ptr - HMEM_USER_OFFSET);
}
static void *GetUserPtr(HMemHeader *header) {
if (header == NULL) {
return NULL;
}
return (void *)((uint8_t *)header + HMEM_USER_OFFSET);
}
static uint8_t IsValidHeader(const HMemHeader *header) {
if (header == NULL) {
return 0;
}
return header->magic == HMEM_MAGIC_VALUE;
}
static uint8_t IsReady(void) {
return HTlsfIsReady(&sTlsf);
}
uint8_t HMemInit(void *buffer, size_t size) {
if (buffer == NULL || size == 0) {
return 0;
}
if (size > HTlsfMaxBufferSize()) {
size = HTlsfMaxBufferSize();
}
if (HTlsfInit(&sTlsf, buffer, size)) {
return 1;
}
return 0;
}
uint8_t HMemIsReady(void) {
return IsReady();
}
void *HMemMalloc(size_t size) {
if (!IsReady() || size == 0 || size > HMEM_SIZE_MAX) {
return NULL;
}
/* 分配时加上头部空间 */
size_t totalSize = HMEM_USER_OFFSET + size;
void *raw = HTlsfMalloc(&sTlsf, totalSize);
if (raw == NULL) {
return NULL;
}
/* 初始化头部 */
HMemHeader *header = (HMemHeader *)raw;
header->magic = HMEM_MAGIC_VALUE;
header->refCount = 1;
header->userSize = (uint16_t)size;
return GetUserPtr(header);
}
void *HMemCalloc(size_t num, size_t size) {
if (!IsReady() || num == 0 || size == 0) {
return NULL;
}
if (num > (SIZE_MAX / size)) {
return NULL;
}
size_t total = num * size;
void *ptr = HMemMalloc(total);
if (ptr != NULL) {
memset(ptr, 0, total);
}
return ptr;
}
void *HMemRealloc(void *ptr, size_t size) {
if (!IsReady()) {
return NULL;
}
if (size > HMEM_SIZE_MAX) {
return NULL;
}
/* ptr == NULL 等价于 malloc */
if (ptr == NULL) {
return HMemMalloc(size);
}
/* size == 0 等价于 free */
if (size == 0) {
HMemFree(ptr);
return NULL;
}
HMemHeader *header = GetHeader(ptr);
if (!IsValidHeader(header)) {
return NULL;
}
size_t oldSize = header->userSize;
/* 如果新大小相同,直接返回 */
if (size == oldSize) {
return ptr;
}
if (header->refCount == 1u) {
size_t totalSize = HMEM_USER_OFFSET + size;
void *raw = HTlsfRealloc(&sTlsf, header, totalSize);
if (raw == NULL) {
return NULL;
}
header = (HMemHeader *)raw;
header->magic = HMEM_MAGIC_VALUE;
header->refCount = 1u;
header->userSize = (uint16_t)size;
return GetUserPtr(header);
}
/* 分配新内存 */
void *newPtr = HMemMalloc(size);
if (newPtr == NULL) {
return NULL;
}
/* 拷贝数据 */
size_t copySize = (oldSize < size) ? oldSize : size;
memcpy(newPtr, ptr, copySize);
/* 释放旧内存 */
HMemFree(ptr);
return newPtr;
}
uint8_t HMemFree(void *ptr) {
if (!IsReady() || ptr == NULL) {
return 0;
}
HMemHeader *header = GetHeader(ptr);
if (!IsValidHeader(header)) {
return 0;
}
/* 引用计数减一 */
if (header->refCount > 0) {
--header->refCount;
}
/* 引用计数为0时才真正释放 */
if (header->refCount == 0) {
header->magic = 0; /* 清除魔数,防止再次释放 */
HTlsfFree(&sTlsf, header);
}
return 1;
}
void *HMemAddRef(void *ptr, size_t size) {
if (!IsReady() || ptr == NULL) {
return NULL;
}
HMemHeader *header = GetHeader(ptr);
/* 如果是 HMem 分配的内存 */
if (IsValidHeader(header)) {
if (header->refCount < HMEM_REFCOUNT_MAX) {
++header->refCount;
}
return ptr;
}
/* 不是 HMem 分配的内存,需要拷贝到新内存 */
if (size == 0) {
return NULL;
}
void *newPtr = HMemMalloc(size);
if (newPtr == NULL) {
return NULL;
}
memcpy(newPtr, ptr, size);
return newPtr;
}
uint32_t HMemGetRefCount(void *ptr) {
if (ptr == NULL) {
return 0;
}
HMemHeader *header = GetHeader(ptr);
if (!IsValidHeader(header)) {
return 0;
}
return header->refCount;
}
uint8_t HMemIsManaged(void *ptr) {
if (ptr == NULL) {
return 0;
}
HMemHeader *header = GetHeader(ptr);
return IsValidHeader(header);
}
size_t HMemGetFreeSize(void) {
if (!IsReady()) {
return 0;
}
return HTlsfGetFreeSize(&sTlsf);
}
size_t HMemGetUsedSize(void) {
if (!IsReady()) {
return 0;
}
return HTlsfGetUsedSize(&sTlsf);
}
size_t HMemGetCapacity(void) {
if (!IsReady()) {
return 0;
}
return HTlsfGetCapacity(&sTlsf);
}

View File

@ -1144,6 +1144,11 @@ size_t HTlsfMinBufferSize(void)
return HTlsfControlSize() + sPoolOverhead + sBlockSizeMin + kHTlsfAlignSize - 1;
}
size_t HTlsfMaxBufferSize(void)
{
return sBlockSizeMax;
}
uint8_t HTlsfInit(HTlsf *htlsf, void *mem, size_t size)
{
uintptr_t raw;