#include #include #include #include "c_Alignment.h" #include "c_Macros.h" /* ------------------------------------------------------------------------------------------------------------------ */ /* */ #define DEFAULT_CHUNK_SIZE 10 /* ------------------------------------------------------------------------------------------------------------------ */ /* */ typedef struct c_PoolBlockLink_t { void* block; struct c_PoolBlockLink_t* next; }c_PoolBlockLink_t; struct c_PoolBlockList_t{ c_PoolBlockLink_t* list; }; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ C_STATIC_FORCE_INLINE void c_PoolBlockLink_Init(c_PoolBlockLink_t* self, void* p, c_PoolBlockLink_t* next) { self->block = p; self->next = next; } C_STATIC_FORCE_INLINE void c_PoolBlockList_Init(c_PoolBlockList_t* self) { self->list = NULL; } C_STATIC_FORCE_INLINE void c_PoolBlockList_Destroy(c_PoolBlockList_t* self) { if (!self) return; while (self->list){ c_PoolBlockLink_t* q = self->list; self->list = q->next; C_FREE(q); } } C_STATIC_FORCE_INLINE void* c_PoolBlockList_Alloc(c_PoolBlockList_t* self, c_size_t bytes) { c_size_t block_size = bytes + sizeof(c_PoolBlockLink_t); block_size = C_ALIGN_UPB(block_size, C_ALIGN_SIZE); c_PoolBlockLink_t* p = C_ALLOC(block_size); if (!p) { return NULL; } c_PoolBlockLink_Init(p, p+1, self->list); self->list = p; return p->block; } C_STATIC_FORCE_INLINE c_err_t c_Pool_Replenish(c_Pool_t* self) { if (!self || !self->blockAllocator) { return C_ERR_PARAM; } c_size_t size = self->chunkSize * self->objSize; uint8_t* start = (uint8_t*)c_PoolBlockList_Alloc(self->blockAllocator, size); if (!start) return C_ERR_NOMEM; uint8_t* last = &start[(self->chunkSize - 1) * self->objSize]; for (uint8_t* p = start; pobjSize) { ((struct c_PoolLink_t*)p)->next = (struct c_PoolLink_t*)(p + self->objSize); } ((struct c_PoolLink_t*)last)->next = NULL; self->freelist = (struct c_PoolLink_t*)start; return C_ERR_OK; } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ c_err_t c_Pool_Init(c_Pool_t* self, int objSize, int chunkSize) { self->freelist = 0; self->objSize = objSize>=sizeof(struct c_PoolLink_t)?objSize:sizeof(struct c_PoolLink_t); self->chunkSize = (chunkSize > 0)?chunkSize:DEFAULT_CHUNK_SIZE; self->instanceCount = 0; C_NEW(self->blockAllocator); if (!self->blockAllocator) { return C_ERR_NOMEM; } c_PoolBlockList_Init(self->blockAllocator); return C_ERR_OK; } void c_Pool_Destroy(c_Pool_t* self) { if (0==self->instanceCount) { c_PoolBlockList_Destroy(self->blockAllocator); C_FREE(self->blockAllocator); self->freelist = NULL; } assert(0==self->instanceCount); } void* c_Pool_Alloc(c_Pool_t* self) { if (!self->freelist) { if (c_Pool_Replenish(self)!=C_ERR_OK) { return NULL; } } struct c_PoolLink_t* p = self->freelist; self->freelist = p->next; ++self->instanceCount; return p; } void c_Pool_Free(c_Pool_t* self, void* ptr) { if (!self || !ptr) { return; } struct c_PoolLink_t* p = (struct c_PoolLink_t*)ptr; p->next = self->freelist; self->freelist = p; --self->instanceCount; } void c_Pool_DryUp(c_Pool_t* self) { #if 0 c_PoolBlockList_Destroy(self->blockAllocator); C_FREE(self->blockAllocator); self->freelist = NULL; self->instanceCount = 0; #endif if (!self) { return; } /* 强制洗净 freelist 自由网 */ self->freelist = NULL; self->instanceCount = 0; if (!self->blockAllocator) { return; } /* 🛠️ 链表反向全量闪放:将所有内部动态追加入驻的 Block 页一键逻辑全量清零, 这样所有的格子会被强制瞬间退回可用状态,而无需反复 free */ c_PoolBlockLink_t* curr = self->blockAllocator->list; while (curr) { unsigned char* byte_ptr = (unsigned char*)curr->block; for (int i = 0; i < self->chunkSize; ++i) { struct c_PoolLink_t* link = (struct c_PoolLink_t*)&byte_ptr[i * self->objSize]; link->next = self->freelist; self->freelist = link; } curr = curr->next; } }