#include #include #include #include /* ------------------------------------------------------------------------------------------------------------------ */ /* */ C_STATIC_FORCE_INLINE c_err_t c_FixedPool_Replenish(c_FixedPool_t* self, void* block, int block_size){ if (!self || !block || block_size < self->objSize) return C_ERR_PARAM; const c_size_t chunk_size = block_size/self->objSize; uint8_t* start = (uint8_t*)block; uint8_t* last = &start[(chunk_size - 1) * self->objSize]; for (uint8_t* p = start; pobjSize) { ((struct c_FixedPoolLink_t*)p)->next = (struct c_FixedPoolLink_t*)(p + self->objSize); } ((struct c_FixedPoolLink_t*)last)->next = self->freelist; self->freelist = (struct c_FixedPoolLink_t*)start; return C_ERR_OK; } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ c_err_t c_FixedPool_Init(c_FixedPool_t* self, int objSize, void* block, int block_size) { if (!self || objSize==0 || !block || block_size < objSize) return C_ERR_PARAM; self->objSize = objSize>=sizeof(struct c_FixedPoolLink_t)?objSize:sizeof(struct c_FixedPoolLink_t); self->objSize = C_ALIGN_UPB(self->objSize, C_ALIGN_SIZE); self->instanceCount = 0; self->freelist = 0; return c_FixedPool_Replenish(self, block, block_size); } void c_FixedPool_Destroy(c_FixedPool_t* self) { if (!self) return; if (0==self->instanceCount) { self->freelist = 0; } assert(0==self->instanceCount); } c_err_t c_FixedPool_AddBlock(c_FixedPool_t* self, void* block, int block_size) { return c_FixedPool_Replenish(self, block, block_size); } void* c_FixedPool_Alloc(c_FixedPool_t* self) { if (!self || !self->freelist) { return NULL; } struct c_FixedPoolLink_t* p = self->freelist; self->freelist = p->next; ++self->instanceCount; return p; } void c_FixedPool_Free(c_FixedPool_t* self, void* ptr) { if (!self || !ptr) { return; } struct c_FixedPoolLink_t* p = (struct c_FixedPoolLink_t*)ptr; p->next = self->freelist; self->freelist = p; --self->instanceCount; assert(self->instanceCount >= 0); } void c_FixedPool_DryUp(c_FixedPool_t* self) { if (!self) return; self->freelist = 0; self->instanceCount = 0; }