#include <stdio.h>
#include <stdlib.h>
#include "mempool.h"
#define MEMPOOL_CHUNKSIZE (1024 * 128)
typedef struct _MEMPOOL_FREE_BLOCK {
struct _MEMPOOL_FREE_BLOCK* next;
} MEMPOOL_FREE_BLOCK;
typedef struct _MEMPOOL {
size_t item_size;
long* alloc_count;
MEMPOOL_FREE_BLOCK* free_list;
};
static MEMPOOL_FREE_BLOCK*
mempool_alloc_chunk(MEMPOOL* pool)
{
MEMPOOL_FREE_BLOCK* chunk;
MEMPOOL_FREE_BLOCK* p;
MEMPOOL_FREE_BLOCK* end;
long num_items;
size_t chunk_size;
size_t item_size;
item_size = pool->item_size;
num_items = MEMPOOL_CHUNKSIZE / item_size;
chunk_size = num_items * item_size;
if (pool->alloc_count) {
++(*pool->alloc_count);
}
chunk = malloc(chunk_size);
p = chunk;
end = (MEMPOOL_FREE_BLOCK*)((char*)chunk + chunk_size);
while (1) {
MEMPOOL_FREE_BLOCK* next = (MEMPOOL_FREE_BLOCK*)((char*)p + item_size);
if (next < end) {
p->next = next;
} else {
p->next = NULL;
break;
}
p = next;
}
return chunk;
}
MEMPOOL*
mempool_create(size_t item_size, long* alloc_count)
{
MEMPOOL* pool = malloc(sizeof(MEMPOOL));
pool->item_size = item_size;
pool->free_list = NULL;
pool->alloc_count = alloc_count;
return pool;
}
void*
mempool_alloc(MEMPOOL* pool)
{
MEMPOOL_FREE_BLOCK* block;
if (!pool->free_list) {
/* with an empty free list, we need more memory */
pool->free_list = mempool_alloc_chunk(pool);
}
/* pull off the head of the free list */
block = pool->free_list;
pool->free_list = pool->free_list->next;
return block;
}
void
mempool_free(MEMPOOL* pool, void* item)
{
if (item) {
MEMPOOL_FREE_BLOCK* block;
/* put this block on the head of the free list */
block = (MEMPOOL_FREE_BLOCK*)item;
block->next = pool->free_list;
pool->free_list = block;
}
}