Listing 31 Generic pool manager implementation

/* 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 */