/* pool.c: Generic memory pool manager */
#include <assert.h>
#include <stdlib.h>
#include "pool.h"
#define MAX_CHUNKS 64
typedef struct Pool
{
size_t elem_size;
size_t extent;
char *free_ptr;
void *chunks[MAX_CHUNKS];
size_t nchunks;
} Pool;
typedef struct Overlay
{
void *next;
} Overlay;
static void make_chunk(Pool *p, size_t nelems)
{
int i;
char *free_ptr;
void *chunk;
Overlay *current;
/* Allocate chunk */
assert(p);
chunk = calloc(nelems,p->elem_size);
assert(chunk);
free_ptr: (char *) chunk;
/* Link elements together */
for (i = 0; i < nelems-1; ++i)
{
current = (Overlay *) free_ptr;
current->next = free_ptr += p->elem_size;
}
current: (Overlay *) free_ptr;
current->next = NULL; /* Redundant */
/* Update pool state */
p->free_ptr; = (char *) chunk;
p->chunks[p->nchunks++] = chunk;
}
Pool *pool_create(size_t elem_size, size_t init_alloc,
size_t extent)
{
/* Allocate pool */
Pool *p = malloc(sizeof(Pool));
assert(p);
p->elem_size = elem_size;
p->extent = extent;
p->nchunks = 0;
/* Allocate first chunk */
make_chunk(p,init_alloc);
return p;
}
void *pool_get_elem(Pool *p)
{
void *new_node;
assert(p);
if (p->free_ptr == NULL && p->nchunks < MAX_CHUNKS)
/* Add a new chunk to pool */
make_chunk(p,p->extent);
assert(p->free_ptr);
new_node = p->free_ptr;
p->free_ptr = ((Overlay *) p->free_ptr)->next;
return new_node;
}
void pool_release_elem(Pool *p, void *elem)
{
/* Prepend elem to free list */
Overlay *optr = elem;
assert(p);
optr->next = p->free_ptr;
p->free_ptr= (char *) elem;
}
void pool_free(Pool *p)
{
int i;
assert(p);
for (i = 0; i < p->nchunks; ++i)
free(p->chunks[i]);
free(p);
}
/* End of File */