summaryrefslogtreecommitdiff
path: root/src/memalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/memalloc.c')
-rw-r--r--src/memalloc.c823
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