diff options
Diffstat (limited to 'src/memalloc.c')
-rw-r--r-- | src/memalloc.c | 823 |
1 files changed, 113 insertions, 710 deletions
diff --git a/src/memalloc.c b/src/memalloc.c index 0f60547..4c1be6a 100644 --- a/src/memalloc.c +++ b/src/memalloc.c @@ -1,7 +1,7 @@ /*******************************************************/ /* "C" Language Integrated Production System */ /* */ - /* CLIPS Version 6.24 06/05/06 */ + /* CLIPS Version 6.30 02/05/15 */ /* */ /* MEMORY MODULE */ /*******************************************************/ @@ -13,7 +13,7 @@ /* Gary D. Riley */ /* */ /* Contributing Programmer(s): */ -/* Brian L. Donnell */ +/* Brian L. Dantes */ /* */ /* Revision History: */ /* */ @@ -24,6 +24,22 @@ /* */ /* Corrected code to remove compiler warnings. */ /* */ +/* 6.30: Removed conditional code for unsupported */ +/* compilers/operating systems. */ +/* */ +/* Changed integer type/precision. */ +/* */ +/* Removed genlongalloc/genlongfree functions. */ +/* */ +/* Added get_mem and rtn_mem macros. */ +/* */ +/* Converted API macros to function calls. */ +/* */ +/* Removed deallocating message parameter from */ +/* EnvReleaseMem. */ +/* */ +/* Removed support for BLOCK_MEMORY. */ +/* */ /*************************************************************/ #define _MEMORY_SOURCE_ @@ -41,43 +57,26 @@ #include <stdlib.h> -#if IBM_TBC -#include <alloc.h> -#endif -#if IBM_MSC || IBM_ICB +#if WIN_MVC #include <malloc.h> #endif -#if IBM_ZTC || IBM_SC -#include <dos.h> -#endif #define STRICT_ALIGN_SIZE sizeof(double) #define SpecialMalloc(sz) malloc((STD_SIZE) sz) #define SpecialFree(ptr) free(ptr) -/***************************************/ -/* LOCAL INTERNAL FUNCTION DEFINITIONS */ -/***************************************/ - -#if BLOCK_MEMORY - static int InitializeBlockMemory(void *,unsigned int); - static int AllocateBlock(void *,struct blockInfo *,unsigned int); - static void AllocateChunk(void *,struct blockInfo *,struct chunkInfo *,unsigned int); -#endif - /********************************************/ /* InitializeMemory: Sets up memory tables. */ /********************************************/ globle void InitializeMemory( void *theEnv) { - int i; - AllocateEnvironmentData(theEnv,MEMORY_DATA,sizeof(struct memoryData),NULL); MemoryData(theEnv)->OutOfMemoryFunction = DefaultOutOfMemoryFunction; - + +#if (MEM_TABLE_SIZE > 0) MemoryData(theEnv)->MemoryTable = (struct memoryPtr **) malloc((STD_SIZE) (sizeof(struct memoryPtr *) * MEM_TABLE_SIZE)); @@ -87,8 +86,15 @@ globle void InitializeMemory( EnvPrintRouter(theEnv,WERROR,"Out of memory.\n"); EnvExitRouter(theEnv,EXIT_FAILURE); } + else + { + int i; - for (i = 0; i < MEM_TABLE_SIZE; i++) MemoryData(theEnv)->MemoryTable[i] = NULL; + for (i = 0; i < MEM_TABLE_SIZE; i++) MemoryData(theEnv)->MemoryTable[i] = NULL; + } +#else // MEM_TABLE_SIZE == 0 + MemoryData(theEnv)->MemoryTable = NULL; +#endif } /***************************************************/ @@ -96,48 +102,28 @@ globle void InitializeMemory( /***************************************************/ globle void *genalloc( void *theEnv, - unsigned int size) + size_t size) { char *memPtr; - -#if BLOCK_MEMORY - memPtr = (char *) RequestChunk(theEnv,size); - if (memPtr == NULL) - { - EnvReleaseMem(theEnv,(long) ((size * 5 > 4096) ? size * 5 : 4096),FALSE); - memPtr = (char *) RequestChunk(theEnv,size); - if (memPtr == NULL) - { - EnvReleaseMem(theEnv,-1L,TRUE); - memPtr = (char *) RequestChunk(theEnv,size); - while (memPtr == NULL) - { - if ((*MemoryData(theEnv)->OutOfMemoryFunction)(theEnv,(unsigned long) size)) - return(NULL); - memPtr = (char *) RequestChunk(theEnv,size); - } - } - } -#else - memPtr = (char *) malloc((STD_SIZE) size); - + + memPtr = (char *) malloc(size); + if (memPtr == NULL) { - EnvReleaseMem(theEnv,(long) ((size * 5 > 4096) ? size * 5 : 4096),FALSE); - memPtr = (char *) malloc((STD_SIZE) size); + EnvReleaseMem(theEnv,(long) ((size * 5 > 4096) ? size * 5 : 4096)); + memPtr = (char *) malloc(size); if (memPtr == NULL) { - EnvReleaseMem(theEnv,-1L,TRUE); - memPtr = (char *) malloc((STD_SIZE) size); + EnvReleaseMem(theEnv,-1L); + memPtr = (char *) malloc(size); while (memPtr == NULL) { - if ((*MemoryData(theEnv)->OutOfMemoryFunction)(theEnv,(unsigned long) size)) + if ((*MemoryData(theEnv)->OutOfMemoryFunction)(theEnv,size)) return(NULL); - memPtr = (char *) malloc((STD_SIZE) size); + memPtr = (char *) malloc(size); } } } -#endif MemoryData(theEnv)->MemoryAmount += (long) size; MemoryData(theEnv)->MemoryCalls++; @@ -149,14 +135,11 @@ globle void *genalloc( /* DefaultOutOfMemoryFunction: Function called */ /* when the KB runs out of memory. */ /***********************************************/ -#if IBM_TBC -#pragma argsused -#endif globle int DefaultOutOfMemoryFunction( void *theEnv, - unsigned long size) + size_t size) { -#if MAC_MCW || IBM_MCW || MAC_XCD +#if MAC_XCD #pragma unused(size) #endif @@ -170,9 +153,9 @@ globle int DefaultOutOfMemoryFunction( /* EnvSetOutOfMemoryFunction: Allows the function which is */ /* called when the KB runs out of memory to be changed. */ /***********************************************************/ -globle int (*EnvSetOutOfMemoryFunction(void *theEnv,int (*functionPtr)(void *,unsigned long)))(void *,unsigned long) +globle int (*EnvSetOutOfMemoryFunction(void *theEnv,int (*functionPtr)(void *,size_t)))(void *,size_t) { - int (*tmpPtr)(void *,unsigned long); + int (*tmpPtr)(void *,size_t); tmpPtr = MemoryData(theEnv)->OutOfMemoryFunction; MemoryData(theEnv)->OutOfMemoryFunction = functionPtr; @@ -185,18 +168,9 @@ globle int (*EnvSetOutOfMemoryFunction(void *theEnv,int (*functionPtr)(void *,un globle int genfree( void *theEnv, void *waste, - unsigned size) - { -#if BLOCK_MEMORY - if (ReturnChunk(theEnv,waste,size) == FALSE) - { - PrintErrorID(theEnv,"MEMORY",2,TRUE); - EnvPrintRouter(theEnv,WERROR,"Release error in genfree.\n"); - return(-1); - } -#else + size_t size) + { free(waste); -#endif MemoryData(theEnv)->MemoryAmount -= (long) size; MemoryData(theEnv)->MemoryCalls--; @@ -210,12 +184,12 @@ globle int genfree( globle void *genrealloc( void *theEnv, void *oldaddr, - unsigned oldsz, - unsigned newsz) + size_t oldsz, + size_t newsz) { char *newaddr; unsigned i; - unsigned limit; + size_t limit; newaddr = ((newsz != 0) ? (char *) gm2(theEnv,newsz) : NULL); @@ -232,153 +206,6 @@ globle void *genrealloc( return((void *) newaddr); } -/************************************************/ -/* genlongalloc: Allocates blocks of memory for */ -/* sizes expressed using long integers. */ -/************************************************/ -#if IBM_TBC -#pragma warn -rch -#pragma warn -ccc -#endif -globle void *genlongalloc( - void *theEnv, - unsigned long size) - { -#if (! MAC) && (! IBM_TBC) && (! IBM_MSC) && (! IBM_ICB) && (! IBM_ZTC) && (! IBM_SC) && (! IBM_MCW) - unsigned int test; -#else - void *memPtr; -#endif -#if BLOCK_MEMORY - struct longMemoryPtr *theLongMemory; -#endif - - if (sizeof(int) == sizeof(long)) - { return(genalloc(theEnv,(unsigned) size)); } - -#if (! MAC) && (! IBM_TBC) && (! IBM_MSC) && (! IBM_ICB) && (! IBM_ZTC) && (! IBM_SC) && (! IBM_MCW) - test = (unsigned int) size; - if (test != size) - { - PrintErrorID(theEnv,"MEMORY",3,TRUE); - EnvPrintRouter(theEnv,WERROR,"Unable to allocate memory block > 32K.\n"); - EnvExitRouter(theEnv,EXIT_FAILURE); - } - return((void *) genalloc(theEnv,(unsigned) test)); -#else - -#if BLOCK_MEMORY - size += sizeof(struct longMemoryPtr); -#endif - - memPtr = (void *) SpecialMalloc(size); - if (memPtr == NULL) - { - EnvReleaseMem(theEnv,(long) ((size * 5 > 4096) ? size * 5 : 4096),FALSE); - memPtr = (void *) SpecialMalloc(size); - if (memPtr == NULL) - { - EnvReleaseMem(theEnv,-1L,TRUE); - memPtr = (void *) SpecialMalloc(size); - while (memPtr == NULL) - { - if ((*MemoryData(theEnv)->OutOfMemoryFunction)(theEnv,size)) - return(NULL); - memPtr = (void *) SpecialMalloc(size); - } - } - } - MemoryData(theEnv)->MemoryAmount += (long) size; - MemoryData(theEnv)->MemoryCalls++; - -#if BLOCK_MEMORY - theLongMemory = (struct longMemoryPtr *) memPtr; - theLongMemory->next = MemoryData(theEnv)->TopLongMemoryPtr; - theLongMemory->prev = NULL; - theLongMemory->size = (long) size; - memPtr = (void *) (theLongMemory + 1); -#endif - - return(memPtr); -#endif - } -#if IBM_TBC -#pragma warn +rch -#pragma warn +ccc -#endif - -/*********************************************/ -/* genlongfree: Returns blocks of memory for */ -/* sizes expressed using long integers. */ -/*********************************************/ -#if IBM_TBC -#pragma warn -rch -#pragma warn -ccc -#endif -globle int genlongfree( - void *theEnv, - void *ptr, - unsigned long size) - { -#if (! MAC) && (! IBM_TBC) && (! IBM_MSC) && (! IBM_ICB) && (! IBM_ZTC) && (! IBM_SC) && (! IBM_MCW) - unsigned int test; -#endif -#if BLOCK_MEMORY - struct longMemoryPtr *theLongMemory; -#endif - - if (sizeof(unsigned int) == sizeof(unsigned long)) - { return(genfree(theEnv,(void *) ptr,(unsigned) size)); } - -#if (! MAC) && (! IBM_TBC) && (! IBM_MSC) && (! IBM_ICB) && (! IBM_ZTC) && (! IBM_SC) && (! IBM_MCW) - test = (unsigned int) size; - if (test != size) return(-1); - - return(genfree(theEnv,(void *) ptr,(unsigned) test)); -#endif - -#if BLOCK_MEMORY - size += sizeof(struct longMemoryPtr); - theLongMemory = ((struct longMemoryPtr *) ptr) - 1; - if (theLongMemory->prev == NULL) - { - MemoryData(theEnv)->TopLongMemoryPtr = MemoryData(theEnv)->TopLongMemoryPtr->next; - MemoryData(theEnv)->TopLongMemoryPtr->prev = NULL; - } - else - { - theLongMemory->prev->next = theLongMemory->next; - if (theLongMemory->next != NULL) - { theLongMemory->next->prev = theLongMemory->next; } - } -#endif - -#if MAC || IBM_ICB || IBM_MCW - MemoryData(theEnv)->MemoryAmount -= (long) size; - MemoryData(theEnv)->MemoryCalls--; - SpecialFree(ptr); - return(0); -#endif - -#if IBM_TBC || IBM_ZTC || IBM_SC - MemoryData(theEnv)->MemoryAmount -= size; - MemoryData(theEnv)->MemoryCalls--; - SpecialFree(ptr); - return(0); -#endif - -#if IBM_MSC - MemoryData(theEnv)->MemoryAmount -= size; - MemoryData(theEnv)->MemoryCalls--; - SpecialFree(ptr); - return(0); -#endif - } -#if IBM_TBC -#pragma warn +rch -#pragma warn +ccc -#endif - /********************************/ /* EnvMemUsed: C access routine */ /* for the mem-used command. */ @@ -429,17 +256,13 @@ globle long int UpdateMemoryRequests( /***********************************/ globle long int EnvReleaseMem( void *theEnv, - long int maximum, - int printMessage) + long int maximum) { struct memoryPtr *tmpPtr, *memPtr; int i; long int returns = 0; long int amount = 0; - if (printMessage == TRUE) - { EnvPrintRouter(theEnv,WDIALOG,"\n*** DEALLOCATING MEMORY ***\n"); } - for (i = (MEM_TABLE_SIZE - 1) ; i >= (int) sizeof(char *) ; i--) { YieldTime(theEnv); @@ -456,16 +279,9 @@ globle long int EnvReleaseMem( } MemoryData(theEnv)->MemoryTable[i] = NULL; if ((amount > maximum) && (maximum > 0)) - { - if (printMessage == TRUE) - { EnvPrintRouter(theEnv,WDIALOG,"*** MEMORY DEALLOCATED ***\n"); } - return(amount); - } + { return(amount); } } - if (printMessage == TRUE) - { EnvPrintRouter(theEnv,WDIALOG,"*** MEMORY DEALLOCATED ***\n"); } - return(amount); } @@ -474,11 +290,11 @@ globle long int EnvReleaseMem( /*****************************************************/ globle void *gm1( void *theEnv, - int size) + size_t size) { struct memoryPtr *memPtr; char *tmpPtr; - int i; + size_t i; if (size < (long) sizeof(char *)) size = sizeof(char *); @@ -513,23 +329,29 @@ globle void *gm1( /*****************************************************/ globle void *gm2( void *theEnv, - unsigned int size) + size_t size) { +#if (MEM_TABLE_SIZE > 0) struct memoryPtr *memPtr; - +#endif + if (size < sizeof(char *)) size = sizeof(char *); +#if (MEM_TABLE_SIZE > 0) if (size >= MEM_TABLE_SIZE) return(genalloc(theEnv,(unsigned) size)); memPtr = (struct memoryPtr *) MemoryData(theEnv)->MemoryTable[size]; if (memPtr == NULL) { - return(genalloc(theEnv,(unsigned) size)); + return(genalloc(theEnv,size)); } MemoryData(theEnv)->MemoryTable[size] = memPtr->next; return ((void *) memPtr); +#else + return(genalloc(theEnv,size)); +#endif } /*****************************************************/ @@ -537,23 +359,27 @@ globle void *gm2( /*****************************************************/ globle void *gm3( void *theEnv, - long size) + size_t size) { +#if (MEM_TABLE_SIZE > 0) struct memoryPtr *memPtr; +#endif if (size < (long) sizeof(char *)) size = sizeof(char *); - if (size >= MEM_TABLE_SIZE) return(genlongalloc(theEnv,(unsigned long) size)); +#if (MEM_TABLE_SIZE > 0) + if (size >= MEM_TABLE_SIZE) return(genalloc(theEnv,size)); memPtr = (struct memoryPtr *) MemoryData(theEnv)->MemoryTable[(int) size]; if (memPtr == NULL) - { - return(genalloc(theEnv,(unsigned int) size)); - } + { return(genalloc(theEnv,size)); } MemoryData(theEnv)->MemoryTable[(int) size] = memPtr->next; return ((void *) memPtr); +#else + return(genalloc(theEnv,size)); +#endif } /****************************************/ @@ -563,9 +389,11 @@ globle void *gm3( globle int rm( void *theEnv, void *str, - unsigned size) + size_t size) { +#if (MEM_TABLE_SIZE > 0) struct memoryPtr *memPtr; +#endif if (size == 0) { @@ -575,11 +403,16 @@ globle int rm( if (size < sizeof(char *)) size = sizeof(char *); - if (size >= MEM_TABLE_SIZE) return(genfree(theEnv,(void *) str,(unsigned) size)); +#if (MEM_TABLE_SIZE > 0) + if (size >= MEM_TABLE_SIZE) return(genfree(theEnv,(void *) str,size)); memPtr = (struct memoryPtr *) str; memPtr->next = MemoryData(theEnv)->MemoryTable[size]; MemoryData(theEnv)->MemoryTable[size] = memPtr; +#else + return(genfree(theEnv,(void *) str,size)); +#endif + return(1); } @@ -591,9 +424,11 @@ globle int rm( globle int rm3( void *theEnv, void *str, - long size) + size_t size) { +#if (MEM_TABLE_SIZE > 0) struct memoryPtr *memPtr; +#endif if (size == 0) { @@ -603,11 +438,16 @@ globle int rm3( if (size < (long) sizeof(char *)) size = sizeof(char *); - if (size >= MEM_TABLE_SIZE) return(genlongfree(theEnv,(void *) str,(unsigned long) size)); +#if (MEM_TABLE_SIZE > 0) + if (size >= MEM_TABLE_SIZE) return(genfree(theEnv,(void *) str,size)); memPtr = (struct memoryPtr *) str; memPtr->next = MemoryData(theEnv)->MemoryTable[(int) size]; MemoryData(theEnv)->MemoryTable[(int) size] = memPtr; +#else + return(genfree(theEnv,(void *) str,size)); +#endif + return(1); } @@ -617,9 +457,11 @@ globle int rm3( globle unsigned long PoolSize( void *theEnv) { + unsigned long cnt = 0; + +#if (MEM_TABLE_SIZE > 0) register int i; struct memoryPtr *memPtr; - unsigned long cnt = 0; for (i = sizeof(char *) ; i < MEM_TABLE_SIZE ; i++) { @@ -630,6 +472,8 @@ globle unsigned long PoolSize( memPtr = memPtr->next; } } +#endif + return(cnt); } @@ -641,30 +485,7 @@ globle unsigned long PoolSize( globle unsigned long ActualPoolSize( void *theEnv) { -#if IBM_TBC - register int i; - struct memoryPtr *memPtr; - unsigned long cnt = 0; - - for (i = sizeof(char *) ; i < MEM_TABLE_SIZE ; i++) - { - memPtr = MemoryData(theEnv)->MemoryTable[i]; - while (memPtr != NULL) - { - /*==============================================================*/ - /* For a block of size n, the Turbo-C Library routines require */ - /* a header of size 8 bytes and further require that all memory */ - /* allotments be paragraph (16-bytes) aligned. */ - /*==============================================================*/ - - cnt += (((unsigned long) i) + 19L) & 0xfffffff0L; - memPtr = memPtr->next; - } - } - return(cnt); -#else return(PoolSize(theEnv)); -#endif } /********************************************/ @@ -706,461 +527,43 @@ globle void genmemcpy( dst[i] = src[i]; } -/**************************/ -/* BLOCK MEMORY FUNCTIONS */ -/**************************/ +/*#####################################*/ +/* ALLOW_ENVIRONMENT_GLOBALS Functions */ +/*#####################################*/ -#if BLOCK_MEMORY +#if ALLOW_ENVIRONMENT_GLOBALS -/***************************************************/ -/* InitializeBlockMemory: Initializes block memory */ -/* management and allocates the first block. */ -/***************************************************/ -static int InitializeBlockMemory( - void *theEnv, - unsigned int requestSize) +globle intBool GetConserveMemory() { - struct chunkInfo *chunkPtr; - unsigned int initialBlockSize, usableBlockSize; - - /*===========================================*/ - /* The block memory routines depend upon the */ - /* size of a character being 1 byte. */ - /*===========================================*/ - - if (sizeof(char) != 1) - { - fprintf(stdout, "Size of character data is not 1\n"); - fprintf(stdout, "Memory allocation functions may not work\n"); - return(0); - } - - MemoryData(theEnv)->ChunkInfoSize = sizeof(struct chunkInfo); - MemoryData(theEnv)->ChunkInfoSize = (int) ((((MemoryData(theEnv)->ChunkInfoSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE); - - MemoryData(theEnv)->BlockInfoSize = sizeof(struct blockInfo); - MemoryData(theEnv)->BlockInfoSize = (int) ((((MemoryData(theEnv)->BlockInfoSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE); - - initialBlockSize = (INITBLOCKSIZE > requestSize ? INITBLOCKSIZE : requestSize); - initialBlockSize += MemoryData(theEnv)->ChunkInfoSize * 2 + MemoryData(theEnv)->BlockInfoSize; - initialBlockSize = (((initialBlockSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE; - - usableBlockSize = initialBlockSize - (2 * MemoryData(theEnv)->ChunkInfoSize) - MemoryData(theEnv)->BlockInfoSize; - - /* make sure we get a buffer big enough to be usable */ - if ((requestSize < INITBLOCKSIZE) && - (usableBlockSize <= requestSize + MemoryData(theEnv)->ChunkInfoSize)) - { - initialBlockSize = requestSize + MemoryData(theEnv)->ChunkInfoSize * 2 + MemoryData(theEnv)->BlockInfoSize; - initialBlockSize = (((initialBlockSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE; - usableBlockSize = initialBlockSize - (2 * MemoryData(theEnv)->ChunkInfoSize) - MemoryData(theEnv)->BlockInfoSize; - } - - MemoryData(theEnv)->TopMemoryBlock = (struct blockInfo *) malloc((STD_SIZE) initialBlockSize); - - if (MemoryData(theEnv)->TopMemoryBlock == NULL) - { - fprintf(stdout, "Unable to allocate initial memory pool\n"); - return(0); - } - - MemoryData(theEnv)->TopMemoryBlock->nextBlock = NULL; - MemoryData(theEnv)->TopMemoryBlock->prevBlock = NULL; - MemoryData(theEnv)->TopMemoryBlock->nextFree = (struct chunkInfo *) (((char *) MemoryData(theEnv)->TopMemoryBlock) + MemoryData(theEnv)->BlockInfoSize); - MemoryData(theEnv)->TopMemoryBlock->size = (long) usableBlockSize; - - chunkPtr = (struct chunkInfo *) (((char *) MemoryData(theEnv)->TopMemoryBlock) + MemoryData(theEnv)->BlockInfoSize + MemoryData(theEnv)->ChunkInfoSize + usableBlockSize); - chunkPtr->nextFree = NULL; - chunkPtr->lastFree = NULL; - chunkPtr->prevChunk = MemoryData(theEnv)->TopMemoryBlock->nextFree; - chunkPtr->size = 0; - - MemoryData(theEnv)->TopMemoryBlock->nextFree->nextFree = NULL; - MemoryData(theEnv)->TopMemoryBlock->nextFree->lastFree = NULL; - MemoryData(theEnv)->TopMemoryBlock->nextFree->prevChunk = NULL; - MemoryData(theEnv)->TopMemoryBlock->nextFree->size = (long) usableBlockSize; - - MemoryData(theEnv)->BlockMemoryInitialized = TRUE; - return(1); + return EnvGetConserveMemory(GetCurrentEnvironment()); } -/***************************************************************************/ -/* AllocateBlock: Adds a new block of memory to the list of memory blocks. */ -/***************************************************************************/ -static int AllocateBlock( - void *theEnv, - struct blockInfo *blockPtr, - unsigned int requestSize) +globle long int MemRequests() { - unsigned int blockSize, usableBlockSize; - struct blockInfo *newBlock; - struct chunkInfo *newTopChunk; - - /*============================================================*/ - /* Determine the size of the block that needs to be allocated */ - /* to satisfy the request. Normally, a default block size is */ - /* used, but if the requested size is larger than the default */ - /* size, then the requested size is used for the block size. */ - /*============================================================*/ - - blockSize = (BLOCKSIZE > requestSize ? BLOCKSIZE : requestSize); - blockSize += MemoryData(theEnv)->BlockInfoSize + MemoryData(theEnv)->ChunkInfoSize * 2; - blockSize = (((blockSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE; - - usableBlockSize = blockSize - MemoryData(theEnv)->BlockInfoSize - (2 * MemoryData(theEnv)->ChunkInfoSize); - - /*=========================*/ - /* Allocate the new block. */ - /*=========================*/ - - newBlock = (struct blockInfo *) malloc((STD_SIZE) blockSize); - if (newBlock == NULL) return(0); - - /*======================================*/ - /* Initialize the block data structure. */ - /*======================================*/ - - newBlock->nextBlock = NULL; - newBlock->prevBlock = blockPtr; - newBlock->nextFree = (struct chunkInfo *) (((char *) newBlock) + MemoryData(theEnv)->BlockInfoSize); - newBlock->size = (long) usableBlockSize; - blockPtr->nextBlock = newBlock; - - newTopChunk = (struct chunkInfo *) (((char *) newBlock) + MemoryData(theEnv)->BlockInfoSize + MemoryData(theEnv)->ChunkInfoSize + usableBlockSize); - newTopChunk->nextFree = NULL; - newTopChunk->lastFree = NULL; - newTopChunk->size = 0; - newTopChunk->prevChunk = newBlock->nextFree; - - newBlock->nextFree->nextFree = NULL; - newBlock->nextFree->lastFree = NULL; - newBlock->nextFree->prevChunk = NULL; - newBlock->nextFree->size = (long) usableBlockSize; - - return(1); + return EnvMemRequests(GetCurrentEnvironment()); } -/*******************************************************/ -/* RequestChunk: Allocates memory by returning a chunk */ -/* of memory from a larger block of memory. */ -/*******************************************************/ -globle void *RequestChunk( - void *theEnv, - unsigned int requestSize) +globle long int MemUsed() { - struct chunkInfo *chunkPtr; - struct blockInfo *blockPtr; - - /*==================================================*/ - /* Allocate initial memory pool block if it has not */ - /* already been allocated. */ - /*==================================================*/ - - if (MemoryData(theEnv)->BlockMemoryInitialized == FALSE) - { - if (InitializeBlockMemory(theEnv,requestSize) == 0) return(NULL); - } - - /*====================================================*/ - /* Make sure that the amount of memory requested will */ - /* fall on a boundary of strictest alignment */ - /*====================================================*/ - - requestSize = (((requestSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE; - - /*=====================================================*/ - /* Search through the list of free memory for a block */ - /* of the appropriate size. If a block is found, then */ - /* allocate and return a pointer to it. */ - /*=====================================================*/ - - blockPtr = MemoryData(theEnv)->TopMemoryBlock; - - while (blockPtr != NULL) - { - chunkPtr = blockPtr->nextFree; - - while (chunkPtr != NULL) - { - if ((chunkPtr->size == requestSize) || - (chunkPtr->size > (requestSize + MemoryData(theEnv)->ChunkInfoSize))) - { - AllocateChunk(theEnv,blockPtr,chunkPtr,requestSize); - - return((void *) (((char *) chunkPtr) + MemoryData(theEnv)->ChunkInfoSize)); - } - chunkPtr = chunkPtr->nextFree; - } - - if (blockPtr->nextBlock == NULL) - { - if (AllocateBlock(theEnv,blockPtr,requestSize) == 0) /* get another block */ - { return(NULL); } - } - blockPtr = blockPtr->nextBlock; - } - - SystemError(theEnv,"MEMORY",2); - EnvExitRouter(theEnv,EXIT_FAILURE); - return(NULL); /* Unreachable, but prevents warning. */ + return EnvMemUsed(GetCurrentEnvironment()); } -/********************************************/ -/* AllocateChunk: Allocates a chunk from an */ -/* existing chunk in a block of memory. */ -/********************************************/ -static void AllocateChunk( - void *theEnv, - struct blockInfo *parentBlock, - struct chunkInfo *chunkPtr, - unsigned int requestSize) +globle long int ReleaseMem( + long int maximum) { - struct chunkInfo *splitChunk, *nextChunk; - - /*=============================================================*/ - /* If the size of the memory chunk is an exact match for the */ - /* requested amount of memory, then the chunk can be allocated */ - /* without splitting it. */ - /*=============================================================*/ - - if (requestSize == chunkPtr->size) - { - chunkPtr->size = - (long int) requestSize; - if (chunkPtr->lastFree == NULL) - { - if (chunkPtr->nextFree != NULL) - { parentBlock->nextFree = chunkPtr->nextFree; } - else - { parentBlock->nextFree = NULL; } - } - else - { chunkPtr->lastFree->nextFree = chunkPtr->nextFree; } - - if (chunkPtr->nextFree != NULL) - { chunkPtr->nextFree->lastFree = chunkPtr->lastFree; } - - chunkPtr->lastFree = NULL; - chunkPtr->nextFree = NULL; - return; - } - - /*===========================================================*/ - /* If the size of the memory chunk is larger than the memory */ - /* request, then split the chunk into two pieces. */ - /*===========================================================*/ - - nextChunk = (struct chunkInfo *) - (((char *) chunkPtr) + MemoryData(theEnv)->ChunkInfoSize + chunkPtr->size); - - splitChunk = (struct chunkInfo *) - (((char *) chunkPtr) + (MemoryData(theEnv)->ChunkInfoSize + requestSize)); - - splitChunk->size = (long) (chunkPtr->size - (requestSize + MemoryData(theEnv)->ChunkInfoSize)); - splitChunk->prevChunk = chunkPtr; - - splitChunk->nextFree = chunkPtr->nextFree; - splitChunk->lastFree = chunkPtr->lastFree; - - nextChunk->prevChunk = splitChunk; - - if (splitChunk->lastFree == NULL) - { parentBlock->nextFree = splitChunk; } - else - { splitChunk->lastFree->nextFree = splitChunk; } - - if (splitChunk->nextFree != NULL) - { splitChunk->nextFree->lastFree = splitChunk; } - - chunkPtr->size = - (long int) requestSize; - chunkPtr->lastFree = NULL; - chunkPtr->nextFree = NULL; - - return; + return EnvReleaseMem(GetCurrentEnvironment(),maximum); } -/***********************************************************/ -/* ReturnChunk: Frees memory allocated using RequestChunk. */ -/***********************************************************/ -globle int ReturnChunk( - void *theEnv, - void *memPtr, - unsigned int size) +globle intBool SetConserveMemory( + intBool value) { - struct chunkInfo *chunkPtr, *lastChunk, *nextChunk, *topChunk; - struct blockInfo *blockPtr; - - /*=====================================================*/ - /* Determine if the expected size of the chunk matches */ - /* the size stored in the chunk's information record. */ - /*=====================================================*/ - - size = (((size - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE; - - chunkPtr = (struct chunkInfo *) (((char *) memPtr) - MemoryData(theEnv)->ChunkInfoSize); - - if (chunkPtr == NULL) - { return(FALSE); } - - if (chunkPtr->size >= 0) - { return(FALSE); } - - if (chunkPtr->size != - (long int) size) - { return(FALSE); } - - chunkPtr->size = - chunkPtr->size; - - /*=============================================*/ - /* Determine in which block the chunk resides. */ - /*=============================================*/ - - topChunk = chunkPtr; - while (topChunk->prevChunk != NULL) - { topChunk = topChunk->prevChunk; } - blockPtr = (struct blockInfo *) (((char *) topChunk) - MemoryData(theEnv)->BlockInfoSize); - - /*===========================================*/ - /* Determine the chunks physically preceding */ - /* and following the returned chunk. */ - /*===========================================*/ - - lastChunk = chunkPtr->prevChunk; - nextChunk = (struct chunkInfo *) (((char *) memPtr) + size); - - /*=========================================================*/ - /* Add the chunk to the list of free chunks for the block. */ - /*=========================================================*/ - - if (blockPtr->nextFree != NULL) - { blockPtr->nextFree->lastFree = chunkPtr; } - - chunkPtr->nextFree = blockPtr->nextFree; - chunkPtr->lastFree = NULL; - - blockPtr->nextFree = chunkPtr; - - /*=====================================================*/ - /* Combine this chunk with previous chunk if possible. */ - /*=====================================================*/ - - if (lastChunk != NULL) - { - if (lastChunk->size > 0) - { - lastChunk->size += (MemoryData(theEnv)->ChunkInfoSize + chunkPtr->size); - - if (nextChunk != NULL) - { nextChunk->prevChunk = lastChunk; } - else - { return(FALSE); } - - if (lastChunk->lastFree != NULL) - { lastChunk->lastFree->nextFree = lastChunk->nextFree; } - - if (lastChunk->nextFree != NULL) - { lastChunk->nextFree->lastFree = lastChunk->lastFree; } - - lastChunk->nextFree = chunkPtr->nextFree; - if (chunkPtr->nextFree != NULL) - { chunkPtr->nextFree->lastFree = lastChunk; } - lastChunk->lastFree = NULL; - - blockPtr->nextFree = lastChunk; - chunkPtr->lastFree = NULL; - chunkPtr->nextFree = NULL; - chunkPtr = lastChunk; - } - } - - /*=====================================================*/ - /* Combine this chunk with the next chunk if possible. */ - /*=====================================================*/ - - if (nextChunk == NULL) return(FALSE); - if (chunkPtr == NULL) return(FALSE); - - if (nextChunk->size > 0) - { - chunkPtr->size += (MemoryData(theEnv)->ChunkInfoSize + nextChunk->size); - - topChunk = (struct chunkInfo *) (((char *) nextChunk) + nextChunk->size + MemoryData(theEnv)->ChunkInfoSize); - if (topChunk != NULL) - { topChunk->prevChunk = chunkPtr; } - else - { return(FALSE); } - - if (nextChunk->lastFree != NULL) - { nextChunk->lastFree->nextFree = nextChunk->nextFree; } - - if (nextChunk->nextFree != NULL) - { nextChunk->nextFree->lastFree = nextChunk->lastFree; } - - } - - /*===========================================*/ - /* Free the buffer if we can, but don't free */ - /* the first buffer if it's the only one. */ - /*===========================================*/ - - if ((chunkPtr->prevChunk == NULL) && - (chunkPtr->size == blockPtr->size)) - { - if (blockPtr->prevBlock != NULL) - { - blockPtr->prevBlock->nextBlock = blockPtr->nextBlock; - if (blockPtr->nextBlock != NULL) - { blockPtr->nextBlock->prevBlock = blockPtr->prevBlock; } - free((char *) blockPtr); - } - else - { - if (blockPtr->nextBlock != NULL) - { - blockPtr->nextBlock->prevBlock = NULL; - MemoryData(theEnv)->TopMemoryBlock = blockPtr->nextBlock; - free((char *) blockPtr); - } - } - } - - return(TRUE); + return EnvSetConserveMemory(GetCurrentEnvironment(),value); } -/***********************************************/ -/* ReturnAllBlocks: Frees all allocated blocks */ -/* back to the operating system. */ -/***********************************************/ -globle void ReturnAllBlocks( - void *theEnv) +globle int (*SetOutOfMemoryFunction(int (*functionPtr)(void *,size_t)))(void *,size_t) { - struct blockInfo *theBlock, *nextBlock; - struct longMemoryPtr *theLongMemory, *nextLongMemory; - - /*======================================*/ - /* Free up int based memory allocation. */ - /*======================================*/ - - theBlock = MemoryData(theEnv)->TopMemoryBlock; - while (theBlock != NULL) - { - nextBlock = theBlock->nextBlock; - free((char *) theBlock); - theBlock = nextBlock; - } - - MemoryData(theEnv)->TopMemoryBlock = NULL; + return EnvSetOutOfMemoryFunction(GetCurrentEnvironment(),functionPtr); + } - /*=======================================*/ - /* Free up long based memory allocation. */ - /*=======================================*/ +#endif /* ALLOW_ENVIRONMENT_GLOBALS */ - theLongMemory = MemoryData(theEnv)->TopLongMemoryPtr; - while (theLongMemory != NULL) - { - nextLongMemory = theLongMemory->next; - genlongfree(theEnv,theLongMemory,(unsigned long) theLongMemory->size); - theLongMemory = nextLongMemory; - } - - MemoryData(theEnv)->TopLongMemoryPtr = NULL; - } -#endif |