80 lines
2.4 KiB
C
80 lines
2.4 KiB
C
#include <c_FixedPool.h>
|
|
#include <c_Alignment.h>
|
|
#include <c_Macros.h>
|
|
#include <assert.h>
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
/* */
|
|
|
|
|
|
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; p<last; p+=self->objSize) {
|
|
((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;
|
|
}
|
|
|