mempool.c #3

  • //
  • guest/
  • matt_armstrong/
  • jam/
  • patched_version/
  • mempool.c
  • View
  • Commits
  • Open Download .zip Download (2 KB)
#include <stdio.h>
#include <stdlib.h>
#include "jam.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;
    const char* name;		/* name for debugging output */
    long malloc_bytes;		/* # of bytes currently allocated via
				 * malloc() */
    long alloc_count;		/* # of times mempool_alloc() is
				 * called. */
    long free_count;		/* # of times mempool_free() called. */
    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;

    chunk = malloc(chunk_size);
    pool->malloc_bytes += 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(const char* name, size_t item_size)
{
    MEMPOOL* pool = malloc(sizeof(MEMPOOL));
    pool->name = name;
    pool->item_size = item_size;
    pool->free_list = NULL;
    pool->malloc_bytes = 0;
    pool->alloc_count = 0;
    pool->free_count = 0;
    return pool;
}


void*
mempool_alloc(MEMPOOL* pool)
{
    MEMPOOL_FREE_BLOCK* block;

    ++pool->alloc_count;

    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;

	++pool->free_count;

	/* put this block on the head of the free list */
	block = (MEMPOOL_FREE_BLOCK*)item;
	block->next = pool->free_list;
	pool->free_list = block;
    }
}


void
mempool_done(MEMPOOL* pool)
{
    if (pool && (DEBUG_MEM || DEBUG_MEM_TOTALS)) {
	printf("pool %s: %ldK allocated, %ld allocs, %ld frees (%ld leaked)\n",
	       pool->name,
	       pool->malloc_bytes / 1024,
	       pool->alloc_count,
	       pool->free_count,
	       pool->alloc_count - pool->free_count);
    }
}
# Change User Description Committed
#3 4632 Matt Armstrong An OPT_SEMAPHORE feature stolen from Craig McPheeters.
#2 4047 Matt Armstrong 20% reduction in memory use.
#1 3683 Matt Armstrong Checkpoint improved memory use canges.