/* Calisto (c) 1998-1999 Peter Howkins, Matthew Howkins, Simon Howkins $Id: pool.c,v 1.3 1999/12/28 19:50:34 peter Exp $ $Log: pool.c,v $ Revision 1.3 1999/12/28 19:50:34 peter Created pool_stat() to return information for debugging Revision 1.2 1999/12/12 19:20:13 peter Added guards, changed blk to blkhead and blktail Revision 1.1 1999/12/12 18:52:08 peter Initial revision */ static char rcsid[] = "$Id: pool.c,v 1.3 1999/12/28 19:50:34 peter Exp $"; #include <stdio.h> #include <stdlib.h> #include "pool.h" #define BLKS_PER_GRP 10 #define GUARD1 0x12345678 #define GUARD2 0x87654321 typedef struct blkhead blkhead; struct blkhead { pool *p; blkhead *nextfree; unsigned guard1; }; typedef struct { unsigned guard2; } blktail; typedef struct blkgrp blkgrp; struct blkgrp { blkgrp *next; /* blkhead b[UNKNOWN];*/ }; struct pool { blkgrp *first; blkhead *free; size_t block_size; unsigned usage; unsigned capacity; }; pool *pool_create(size_t block_size) { pool *p; p = malloc(sizeof(pool)); if (p) { p->free = NULL; p->first = NULL; p->block_size = block_size + sizeof(blkhead) + sizeof(blktail); p->usage = 0; p->capacity = 0; } return p; } /* void pool_destroy(pool *pool); */ void *pool_malloc(pool *p) { if (!p->free) { blkgrp *bg; bg = malloc(sizeof(blkgrp) + BLKS_PER_GRP * p->block_size); if (!bg) return NULL; { blkhead *b = (blkhead *)(bg + 1); int i; /* Add blks in this group to free list */ for (i = 0; i < BLKS_PER_GRP; i++) { blktail *bt; /* pointer to tail of current blk */ b->guard1 = GUARD1; b->nextfree = p->free; p->free = b; /* Move b to next blkhead */ b = (blkhead *) ( (char *)b + p->block_size); /* Move back from next blkhead to previous blktail */ bt = (blktail *) ((char *) b - sizeof(blktail)); bt->guard2 = GUARD2; } p->capacity += BLKS_PER_GRP; } } { blkhead *b; b = p->free; p->free = b->nextfree; b->p = p; p->usage++; return b + 1; } } void pool_free(void *ptr) { if (ptr) { blkhead *bh = (blkhead *) (((char *) ptr) - sizeof(blkhead)); pool *p = bh->p; /* Check guard1 */ if (bh->guard1 != GUARD1) { fprintf(stderr, "Pool: overran start of block %p\n", ptr); return; } { blktail *bt = (blktail *) ((char *) bh + p->block_size - sizeof(blktail)); /* Check guard2 */ if (bt->guard2 != GUARD2) { fprintf(stderr, "Pool: overran end of block %p\n", ptr); return; } } /* Free up block */ bh->nextfree = p->free; p->free = bh; p->usage--; } } void pool_debug(const pool *p) { printf("block size: %d\n", p->block_size - sizeof(blkhead) - sizeof(blktail)); printf("usage : %d\n", p->usage); printf("capacity : %d\n", p->capacity); } pool_stat_t pool_stat(const pool *p) { pool_stat_t ps; ps.block_size = p->block_size; ps.usage = p->usage; ps.capacity = p->capacity; return ps; }