PoolLib is a memory allocation/deallocation library for fixed size memory units. It is intended to be the basis for memory management of large groups of small sized objects where there is frequent allocation/deallocation activity. Malloc/free can be costly in performance because they have to do segment splitting/recombining operations. D'Anne Thompson National Optical Astronomy Observatories P.O. Box 26732 Tucson, AZ 85725 (602) 325-9335 dat@noao.edu {...}!uunet!noao.edu --------------------SHAR ARCHIVE FOLLOWS----------------------------- #!/bin/sh cat >Makefile <<'------ EOF ------' # location of vxWorks VW = /vw # Include file directories, vxWorks INCLUDES = -I$(VW)/h # See the source code for explanations CFLAGS = -O $(INCLUDES) OBJS = poolLib.o all : $(OBJS) docs docs : .docs .docs : poolLib.c $(VW)/bin/mangen $(VW)/bin/msplit $(VW)/bin/xp mangen -n lib poolLib.c /bin/mv mg.out poolLib.nr msplit -s .nr file.names nroff -mangen `sort file.names` | lpr /bin/rm -f file.names shar : poolLib.shar.Z poolLib.shar.Z : Makefile poolLib.c poolLib.h .docs -/bin/rm -f poolLib.shar.Z shar -v -o poolLib.shar Makefile poolLib.h poolLib.c *.nr compress -v poolLib.shar clean : /bin/rm -f *.o core a.out *.nr .docs *.shar* ------ EOF ------ ls -l Makefile cat >poolLib.h <<'------ EOF ------' /* poolLib.h - header file for the memory pool allocation system*/ /* written by, D'Anne Thompson National Optical Astronomy Observatories P.O. Box 26732 Tucson, AZ 85726 (602) 325-9335 dat@noao.edu {...}!uunet!noao.edu!dat */ #ifndef INCpoolLib_h #define INCpoolLib_h /* modification history -------------------- 01a 25may89 dat - prepared for export to public archives */ /* DESCRIPTION The memory pool allocation system is used to allocate fixed size blocks of memory with a minimum of software overhead. Memory taken from the operating system via 'malloc' is never freed back to the system. This eliminates any garbage collection overhead. When additional space is needed, it is allocated in large chunks in multiples of one kilobyte at a time. This system is intended for use in areas where data structures are allocated and freed frequently, as with message buffers, job request structures and the like. The system is dynamic in that it grows upon request, but a running system should eventually achieve a static state where no further requests for 'malloc' space are needed. On-line statistics are available about the number of pools created, the number of items in each pool, and the total memory allocated per pool. */ #include "lstLib.h" #include "semLib.h" typedef struct { NODE node; /* global pool list */ LIST list; /* free item list */ char *name; /* pool name */ SEM_ID access; /* access control semaphore */ int size; /* size of a single item */ int incr; /* # of items to add when expanding pool */ int total; /* total items allocated so far */ } POOL; typedef POOL *POOL_ID; IMPORT POOL_ID poolCreate(); /* (name,size,initial_qty,incr_qty) */ IMPORT NODE *poolGetItem(); /* (pPool) */ IMPORT VOID poolFreeItem(); /* (pPool,pItem) */ IMPORT STATUS poolStats(); /* (pPool) */ IMPORT STATUS poolStatsAll(); /* () */ #endif /* ! INCpoolLib_h */ ------ EOF ------ ls -l poolLib.h cat >poolLib.c <<'------ EOF ------' /* poolLib.c - memory pool allocation system library */ /* LINTLIBRARY written by, D'Anne Thompson National Optical Astronomy Observatories P.O. Box 26732 Tucson, AZ 85726 (602) 325-9335 dat@noao.edu {...}!uunet!noao.edu!dat */ /* modification history -------------------- 01a 25may89 dat - prepared for export to public archives */ /* DESCRIPTION The memory pool allocation system is used to allocate fixed size blocks of memory with a minimum of software overhead. Memory taken from the operating system via malloc() is never returned to the system, eliminating any garbage collection overhead. When additional space is needed for a pool, large chunks (multiples of a kilobyte) are allocated from system memory. The pool allocation system is intended for use in areas where data structures are allocated and freed frequently, as with message buffers, job request structures, and the like. The system is dynamic in that it grows upon request, but a running system should eventually achieve a static state where no further requests for raw memory space are needed. On-line statistics are available about the overall pool system and individual pools. */ #include "vxWorks.h" #include "stdioLib.h" #include "poolLib.h" IMPORT char *malloc(); /* Forward Declarations */ POOL_ID poolCreate(); /* (name,size,initial_qty,incr_qty) */ NODE *poolGetItem(); /* (pPool) */ VOID poolFreeItem(); /* (pPool,pItem) */ STATUS poolStats(); /* (pPool) */ STATUS poolStatsAll(); /* () */ LOCAL VOID poolIncr(); /* (p,count) */ /* global data */ LIST poolList = { {NULL,NULL},0}; /* global pool list */ /**************************************************************** * * poolCreate - create and initialize a memory pool * * This routine creates a memory pool. Items in the pool are all * of a fixed size. * * Memory pools are created and expanded in chunks that are a multiple * of 1024 bytes. The 'count' argument specifies the minimum number * of items to put into the pool at creation time. The actual number * may be different. * * When a pool is empty and must be expanded, the 'count' argument * determines the minimum number of items to be added. * The absolute minimum value for 'count' is five. Trying to specify * a smaller value suggests a misunderstanding of the pool concept. */ POOL_ID poolCreate (name, size, count, incr) char *name; /* name of new pool */ int size; /* size of a single item */ int count; /* initial number of items */ int incr; /* number of items to add when enlarging */ { SEM_ID access; POOL_ID pPool; access = semCreate (); if (access == NULL) return NULL; pPool = (POOL_ID) malloc (sizeof(POOL)); if (pPool != NULL) { lstInit (&(pPool->list)); pPool->access = access; semGive (pPool->access); pPool->size = max (size, sizeof(NODE)); pPool->incr = max (5, incr); /* 5 is absolute minimum increment */ pPool->total = 0; pPool->name = name; if (name && strlen(name) == 0) pPool->name = NULL; lstAdd (&poolList, (NODE *)pPool); poolIncr (pPool, count); } return pPool; } /****************************************************************** * * poolGetItem - get an item from a pool * * Given a pointer to a memory pool, this routine returns an * item from that pool. If necessary, the pool will be enlarged * in order to accomodate the request. * * RETURNS: * Returns NULL upon failure. */ NODE *poolGetItem (pPool) POOL_ID pPool; /* pool to get item from */ { NODE * pNode; if (pPool == NULL) return (NODE *)NULL; semTake (pPool->access); if (lstCount (&pPool->list) == 0) poolIncr (pPool, pPool->incr); pNode = lstGet (&pPool->list); semGive (pPool->access); return pNode; } /**************************************************************** * * poolFreeItem - return an item to a memory pool * * This routine returns an item back to a memory pool. * * Incorrect use of this routine, namely returning an item to the * wrong pool, can be catastrophic. There is no validation check * that the item belongs to the specified pool. */ STATUS poolFreeItem (pPool, pItem) POOL_ID pPool; /* pool to receive item */ char *pItem; /* item to be returned */ { if (pPool == NULL || pItem == NULL) return ERROR; semTake (pPool->access); lstAdd (&pPool->list, (NODE *)pItem); semGive (pPool->access); return OK; } /**************************************************************** * * poolIncr - increase pool size by count items (min) * * Actual pool increments are done in multiples of 1024 bytes. The * actual count of items added may be larger than the number requested. */ LOCAL VOID poolIncr (pPool,count) POOL_ID pPool; /* pool to be enlarged */ int count; /* min # of items to be added */ { LIST tempList; FAST char *block; unsigned bytes; int actual; /* actual # of items added */ if (pPool == NULL) return; lstInit (&tempList); /* round up to nearest kilobyte */ bytes = ((count * pPool->size) + 1023) & -1024; actual = bytes / pPool->size; block = malloc (bytes); if (block == NULL) return; pPool->total += actual; while (actual--) { lstAdd (&tempList,(NODE *)block); block += pPool->size; } lstConcat (&pPool->list, &tempList); } /**************************************************************** * * poolHdr - Print headings for pool statitistics printout * * Prints two lines of report heading information. */ LOCAL VOID poolHdr () { printf("Pool name total free busy size incr (KBytes)\n"); printf("--------- ----- ---- ---- ---- ---- --------\n"); } /**************************************************************** * * poolPrint - Print statitistics for a single pool * * Prints one line of data about a specific pool (no headings). */ LOCAL VOID poolPrint (pPool) POOL_ID pPool; { int free; if (pPool && pPool->name != NULL) printf( "%-11.11s ",pPool->name); else printf("0x%08x ",pPool); if (pPool != NULL) { free = lstCount (&pPool->list); printf("%4d %4d %4d %4d %4d (%d)\n", pPool->total, free, pPool->total - free, pPool->size, pPool->incr, (((pPool->total * pPool->size) + 1023) / 1024) ); } } /**************************************************************** * * poolStats - print statistics on a memory pool * * Print the current status for a given memory pool. * * Status includes the total number of items in the pool, the * number that are in-use and free, the size of a single item, * and the total kilobytes of raw memory allocated. */ STATUS poolStats (pPool) POOL_ID pPool; { poolHdr (); poolPrint (pPool); return OK; } /**************************************************************** * * poolStatsAll - print statistics on all pools * * Print status for all memory pools. * * Status includes the total number of items in the pool, the * number that are in-use and free, the size of a single item, * and the total kilobytes of raw memory allocated. */ STATUS poolStatsAll () { POOL_ID pPool = (POOL_ID) lstFirst (&poolList); poolHdr (); while (pPool != NULL) { poolPrint (pPool); pPool = (POOL_ID) lstNext ((NODE *)pPool); } return OK; } ------ EOF ------ ls -l poolLib.c cat >poolCreate.nr <<'------ EOF ------' .TH poolCreate 2 "" "VxWorks Reference Manual" .ad b .SH NAME poolCreate - create and initialize a memory pool .SH SYNOPSIS .CS .nf POOL_ID poolCreate (name, size, count, incr) char *name; /* name of new pool */ int size; /* size of a single item */ int count; /* initial number of items */ int incr; /* number of items to add when enlarging */ .fi .CE .SH DESCRIPTION This routine creates a memory pool. Items in the pool are all of a fixed size. Memory pools are created and expanded in chunks that are a multiple of 1024 bytes. The 'count' argument specifies the minimum number of items to put into the pool at creation time. The actual number may be different. When a pool is empty and must be expanded, the 'count' argument determines the minimum number of items to be added. The absolute minimum value for 'count' is five. Trying to specify a smaller value suggests a misunderstanding of the pool concept. .SH SEE ALSO poolLib(1) ------ EOF ------ ls -l poolCreate.nr cat >poolFreeItem.nr <<'------ EOF ------' .TH poolFreeItem 2 "" "VxWorks Reference Manual" .ad b .SH NAME poolFreeItem - return an item to a memory pool .SH SYNOPSIS .CS .nf STATUS poolFreeItem (pPool, pItem) POOL_ID pPool; /* pool to receive item */ char *pItem; /* item to be returned */ .fi .CE .SH DESCRIPTION This routine returns an item back to a memory pool. Incorrect use of this routine, namely returning an item to the wrong pool, can be catastrophic. There is no validation check that the item belongs to the specified pool. .SH SEE ALSO poolLib(1) ------ EOF ------ ls -l poolFreeItem.nr cat >poolGetItem.nr <<'------ EOF ------' .TH poolGetItem 2 "" "VxWorks Reference Manual" .ad b .SH NAME poolGetItem - get an item from a pool .SH SYNOPSIS .CS .nf NODE *poolGetItem (pPool) POOL_ID pPool; /* pool to get item from */ .fi .CE .SH DESCRIPTION Given a pointer to a memory pool, this routine returns an item from that pool. If necessary, the pool will be enlarged in order to accomodate the request. .SH RETURNS Returns NULL upon failure. .SH SEE ALSO poolLib(1) ------ EOF ------ ls -l poolGetItem.nr cat >poolLib.nr <<'------ EOF ------' .TH poolLib 1 "" "VxWorks Reference Manual" .ad b .SH NAME poolLib.c - memory pool allocation system library .SH SYNOPSIS .nf poolCreate - create and initialize a memory pool poolGetItem - get an item from a pool poolFreeItem - return an item to a memory pool poolStats - print statistics on a memory pool poolStatsAll - print statistics on all pools POOL_ID poolCreate (name, size, count, incr) NODE *poolGetItem (pPool) STATUS poolFreeItem (pPool, pItem) STATUS poolStats (pPool) STATUS poolStatsAll () .fi .SH DESCRIPTION The memory pool allocation system is used to allocate fixed size blocks of memory with a minimum of software overhead. Memory taken from the operating system via malloc() is never returned to the system, eliminating any garbage collection overhead. When additional space is needed for a pool, large chunks (multiples of a kilobyte) are allocated from system memory. The pool allocation system is intended for use in areas where data structures are allocated and freed frequently, as with message buffers, job request structures, and the like. The system is dynamic in that it grows upon request, but a running system should eventually achieve a static state where no further requests for raw memory space are needed. On-line statistics are available about the overall pool system and individual pools. ------ EOF ------ ls -l poolLib.nr cat >poolStats.nr <<'------ EOF ------' .TH poolStats 2 "" "VxWorks Reference Manual" .ad b .SH NAME poolStats - print statistics on a memory pool .SH SYNOPSIS .CS .nf STATUS poolStats (pPool) POOL_ID pPool; .fi .CE .SH DESCRIPTION Print the current status for a given memory pool. Status includes the total number of items in the pool, the number that are in-use and free, the size of a single item, and the total kilobytes of raw memory allocated. .SH SEE ALSO poolLib(1) ------ EOF ------ ls -l poolStats.nr cat >poolStatsAll.nr <<'------ EOF ------' .TH poolStatsAll 2 "" "VxWorks Reference Manual" .ad b .SH NAME poolStatsAll - print statistics on all pools .SH SYNOPSIS .CS .nf STATUS poolStatsAll () .fi .CE .SH DESCRIPTION Print status for all memory pools. Status includes the total number of items in the pool, the number that are in-use and free, the size of a single item, and the total kilobytes of raw memory allocated. .SH SEE ALSO poolLib(1) ------ EOF ------ ls -l poolStatsAll.nr