#include "object_pool.h" #include "../core/memory.h" typedef struct BzObjectPool { void *objects; size_t stride; size_t numObjects; i32 firstFree; } BzObjectPool; static i32 *bzObjectPoolGetObject(const BzObjectPool *pool, size_t idx) { return (i32 *) ((u8 *) pool->objects + idx * pool->stride); } BzObjectPool *bzObjectPoolCreate(const BzObjectPoolDesc *desc) { BZ_ASSERT(desc->objectSize > 0); // NOTE: Since object bits are used as a free list // when not in use, we must ensure they can hold i32. size_t stride = desc->objectSize; if (stride < sizeof(i32)) { stride = sizeof(i32); } size_t numBytes = sizeof(BzObjectPool) + desc->numObjects * stride; BzObjectPool *pool = bzAlloc(numBytes); *pool = (BzObjectPool) { .objects=pool + 1, .stride=stride, .numObjects=desc->numObjects, .firstFree=0, }; // Link free list for (size_t i = 0; i < pool->numObjects - 1; i++) { i32 *object = bzObjectPoolGetObject(pool, i); *object = (i32) (i + 1); } i32 *lastObject = bzObjectPoolGetObject(pool, pool->numObjects - 1); *lastObject = -1; return pool; } void bzObjectPoolDestroy(BzObjectPool *pool) { bzFree(pool); } void *bzObjectPool(BzObjectPool *pool) { if (pool->firstFree == -1) return NULL; i32 *object = bzObjectPoolGetObject(pool, pool->firstFree); pool->firstFree = *object; return object; } void bzObjectPoolRelease(BzObjectPool *pool, void *object) { size_t objectIdx = (size_t) object - (size_t)pool->objects; BZ_ASSERT(objectIdx < pool->numObjects); *(i32 *) objectIdx = pool->firstFree; pool->firstFree = (i32) objectIdx; }