/* private.h: private data structures and routines for the pools library */

/* debug output will be generated if this callback function has been set */
extern POOLS_MSG_CALLBACK_FUNC pools_info_callback_func;
extern void PoolsInfo(char *routine, char *text, ...);
extern void PoolsWarning(char *routine, char *text, ...);
extern void PoolsError(char *routine, char *text, ...);
extern void PoolsFatal(char *routine, char *text, ...);

/* macro to round a number up to a multiple of 'align' */
#define ROUND_UP(num, align)  (((num)+((align)-1)) & ~((align)-1))

/* search back at most this number of pages for a page with free cells.
 * Setting this value to a too small value might introduce a memory
 * leak in your program. This value boudns the maximum time spent in
 * a New() call. */
#define MAX_SEARCH_PAGES 500

/* allocated addresses are aligned to double word (8-byte) boundary.
 * Must be a power of 2. */
#ifndef POOL_ALIGN
#define ALIGN 8
#else
#define ALIGN POOL_ALIGN
#endif

/* A trailer contaiing a magic number (so it can be recognized) and a pointer to 
 * the beginning of the pool. Used for faster Dispose(). */
typedef struct POOL_TRAILER {
  unsigned magic;
  struct POOL *pool;
} POOL_TRAILER;

/* there will be one "trailer" per CELLS_PER_TRAILER cells + one at the end of 
 * each page. */
#ifndef POOL_CELLS_PER_TRAILER
#define CELLS_PER_TRAILER	64
#else
#define CELLS_PER_TRAILER	POOL_CELLS_PER_TRAILER
#endif

#ifdef POOL_HEADERS
/* When compiled with POOL_HEADERS defined, each cell is preceeded by a
 * pointer to the page it belongs to. This makes Dispose() quite a bit
 * faster, but introduces a 4-byte per cell storage overhead. */

/* well ... actually ... I don't think it's worth the storage overhead since
 * we have POOL trailers and copies etc.... This is stuff to be removed some
 * day. [PhB, June, 20 1997] */

/* each cell is preceeded by a header containing a pointer to the
 * page containing the cell */
typedef struct CELLHDR {
	struct POOL *page;
} CELLHDR;

/* size of header that comes before the cells - contains one pointer */
#define HEADERSIZE	sizeof(struct CELLHDR)

/* max. number of cells per page - should be a multiple of 8 */
#define MAXCELLSPERPAGE	480

/* minimum cell size. MINCELLSIZE+HEADERSIZE must be a multiple of ALIGN */
#define MINCELLSIZE	8

/* should be a multiple of (MINCELLSIZE+HEADERSIZE)*8 */
#define PAGESIZE (MAXCELLSPERPAGE * (MINCELLSIZE + HEADERSIZE))

#else /*POOL_HEADERS*/

/* no headers: zero bytes per header. */
#define HEADERSIZE 	0

/* max. number of cells per page */
#define MAXCELLSPERPAGE	480

/* minimum cell size: at least sizeof(POOL_TRAILER) and a multiple of ALIGN. */
#define MINCELLSIZE	ROUND_UP(sizeof(POOL_TRAILER), ALIGN)

#define PAGESIZE (MAXCELLSPERPAGE * MINCELLSIZE)

#endif /*POOL_HEADERS*/

/* size of the allocmap bitmap */
#define ALLOCMAPSIZE ((MAXCELLSPERPAGE+7)/8)

typedef struct POOL {
  unsigned 	 magic;		/* magic number marking the start of
				 * a POOL struct. */
  struct POOL *next, *prev;	/* pointers to the next and previous pages
				 * in the pool */
  struct POOL 	 *free;		/* pointer to the last POOL from which a 
				 * cell was disposed. */
  unsigned short allocedcells, 	/* nr of allocated cells in page */
                 maxcells,	/* max. number of cells in page */
                 cellsize, 	/* effective (fixed) size of the 
				 * cells in the page, including header */
                 nextfreecell;	/* index of next free cell in page */
  unsigned short fixedoverhead,	/* fixed overhead for the POOL in bytes. */
                 reservedcells;	/* reserved cells (for trailer copies) */
  unsigned char  offset,	/* base+offset is addres of first cell
				 * in page (aligned to ALIGN bytes). */
                 overheadpercell; /* bytes overhead per cell */
  unsigned char allocmap[ALLOCMAPSIZE];	/* bitmap indicating status of
				 * each cell (occupied or free) */
  unsigned char base[PAGESIZE+8+HEADERSIZE+sizeof(POOL_TRAILER)];
                                /* enough space for the cells and a trailer
				 * marking the end of the POOL struct. */
} POOL;


