📄 memory.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* MEMORY MODULE */ /*******************************************************//*************************************************************//* Purpose: Memory allocation routines. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* Brian L. Donnell *//* *//* Revision History: *//* *//*************************************************************/#define _MEMORY_SOURCE_#include <stdio.h>#define _CLIPS_STDIO_#include "setup.h"#include "constant.h"#include "clipsmem.h"#include "router.h"#include "utility.h"#if ANSI_COMPILER#include <stdlib.h>#else#if (! IBM_TBC) && (! IBM_MSC) && (! IBM_ICB)extern char *malloc();#endif#endif#if IBM_TBC#include <alloc.h>#endif#if IBM_MSC || IBM_ICB#include <malloc.h>#endif#if IBM_ZTC || IBM_SC#include <dos.h>#endif#define STRICT_ALIGN_SIZE sizeof(double)/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/#if BLOCK_MEMORY#if ANSI_COMPILER static int InitializeBlockMemory(unsigned int); static int AllocateBlock(struct blockInfo *,unsigned int); static VOID AllocateChunk(struct blockInfo *,struct chunkInfo *,unsigned int); static VOID ReturnAllBlocks(void); static int BlockMemoryExitFunction(int);#else static int InitializeBlockMemory(); static int AllocateBlock(); static VOID AllocateChunk(); static VOID ReturnAllBlocks(); static int BlockMemoryExitFunction();#endif#endif/***************************************//* LOCAL INTERNAL VARIABLE DEFINITIONS *//***************************************/ static long int MemoryAmount = 0; static long int MemoryCalls = 0; static BOOLEAN ConserveMemory = CLIPS_FALSE; #if BLOCK_MEMORY static struct longMemoryPtr *TopLongMemoryPtr = NULL; static struct blockInfo *TopMemoryBlock; static int BlockInfoSize; static int ChunkInfoSize; static int BlockMemoryInitialized = CLIPS_FALSE;#endif#if ANSI_COMPILER static int (*OutOfMemoryFunction)(unsigned long) = DefaultOutOfMemoryFunction;#else static int (*OutOfMemoryFunction)() = DefaultOutOfMemoryFunction;#endif/****************************************//* GLOBAL INTERNAL VARIABLE DEFINITIONS *//****************************************/ globle struct memoryPtr *TempMemoryPtr; globle struct memoryPtr **MemoryTable; globle unsigned int TempSize; globle unsigned long TempSize2;/********************************************//* InitializeMemory: Sets up memory tables. *//********************************************/globle VOID InitializeMemory() { int i; MemoryTable = (struct memoryPtr **) malloc((CLIPS_STD_SIZE) (sizeof(struct memoryPtr *) * MEM_TABLE_SIZE)); if (MemoryTable == NULL) { PrintErrorID("MEMORY",1,CLIPS_TRUE); PrintCLIPS(WERROR,"Out of memory.\n"); ExitCLIPS(1); } for (i = 0; i < MEM_TABLE_SIZE; i++) MemoryTable[i] = NULL; }/***************************************************//* genalloc: A generic memory allocation function. *//***************************************************/globle VOID *genalloc(size) unsigned int size; { char *memPtr;#if BLOCK_MEMORY memPtr = RequestChunk(size); if (memPtr == NULL) { ReleaseMem((long) ((size * 5 > 4096) ? size * 5 : 4096),CLIPS_FALSE); memPtr = RequestChunk(size); if (memPtr == NULL) { ReleaseMem(-1L,CLIPS_TRUE); memPtr = RequestChunk(size); while (memPtr == NULL) { if ((*OutOfMemoryFunction)((unsigned long) size)) return(NULL); memPtr = RequestChunk(size); } } }#else memPtr = malloc((CLIPS_STD_SIZE) size); if (memPtr == NULL) { ReleaseMem((long) ((size * 5 > 4096) ? size * 5 : 4096),CLIPS_FALSE); memPtr = malloc((CLIPS_STD_SIZE) size); if (memPtr == NULL) { ReleaseMem(-1L,CLIPS_TRUE); memPtr = malloc((CLIPS_STD_SIZE) size); while (memPtr == NULL) { if ((*OutOfMemoryFunction)((unsigned long) size)) return(NULL); memPtr = malloc((CLIPS_STD_SIZE) size); } } }#endif MemoryAmount += size; MemoryCalls++; return((VOID *) memPtr); }/****************************************************//* DefaultOutOfMemoryFunction: Function called when *//* CLIPS runs out of memory. *//****************************************************/#if IBM_TBC#pragma argsused#endifgloble int DefaultOutOfMemoryFunction(size) unsigned long size; {#if MAC_MPW || MAC_MCW#pragma unused(size)#endif PrintErrorID("MEMORY",1,CLIPS_TRUE); PrintCLIPS(WERROR,"Out of memory.\n"); ExitCLIPS(1); return(CLIPS_TRUE); }/*********************************************************//* SetOutOfMemoryFunction: Allows the function which is *//* called when CLIPS runs out of memory to be changed. *//*********************************************************/#if ANSI_COMPILER#if ! MAC_MCWgloble int (*SetOutOfMemoryFunction(functionPtr))(unsigned long) int (*functionPtr)(unsigned long); { int (*tmpPtr)(unsigned long);#elsegloble int (*SetOutOfMemoryFunction(functionPtr))() int (*functionPtr)(unsigned long); { int (*tmpPtr)(unsigned long);#endif#elsegloble int (*SetOutOfMemoryFunction(functionPtr))() int (*functionPtr)(); { int (*tmpPtr)();#endif tmpPtr = OutOfMemoryFunction; OutOfMemoryFunction = functionPtr; return(tmpPtr); }/****************************************************//* genfree: A generic memory deallocation function. *//****************************************************/globle int genfree(waste,size) VOID *waste; unsigned size; {#if BLOCK_MEMORY if (ReturnChunk(waste,size) == CLIPS_FALSE) { PrintErrorID("MEMORY",2,CLIPS_TRUE); PrintCLIPS(WERROR,"Release error in genfree.\n"); return(-1); }#else free(waste);#endif MemoryAmount -= size; MemoryCalls--; return(0); }/******************************************************//* genrealloc: Simple (i.e. dumb) version of realloc. *//******************************************************/globle VOID *genrealloc(oldaddr,oldsz,newsz) VOID *oldaddr; unsigned oldsz, newsz; { char *newaddr; int i, limit; newaddr = ((newsz != 0) ? (char *) gm2((int) newsz) : NULL); if (oldaddr != NULL) { limit = (oldsz < newsz) ? oldsz : newsz; for (i = 0 ; i < limit ; i++) { newaddr[i] = ((char *) oldaddr)[i]; } for ( ; i < newsz; i++) { newaddr[i] = '\0'; } rm((VOID *) oldaddr,(int) oldsz); } return((VOID *) newaddr); }#if MAC || IBM_ICB || WIN_32#define SpecialMalloc(sz) malloc((CLIPS_STD_SIZE) sz)#define SpecialFree(ptr) free(ptr)#endif#if IBM_TBC && (! WIN_32)#define SpecialMalloc(sz) farmalloc(sz)#define SpecialFree(ptr) farfree(ptr)#endif#if IBM_ZTC || IBM_SC#ifdef __SMALL__#define SpecialMalloc(sz) malloc((CLIPS_STD_SIZE) sz)#define SpecialFree(ptr) free(ptr)#else#define SpecialMalloc(sz) farmalloc(sz)#define SpecialFree(ptr) farfree(ptr)#endif#endif#if IBM_MSC && (! WIN_32)#define SpecialMalloc(sz) halloc(sz,1)#define SpecialFree(ptr) hfree(ptr)#endif/************************************************//* genlongalloc: Allocates blocks of memory for *//* sizes expressed using long integers. *//************************************************/#if IBM_TBC#pragma warn -rch#pragma warn -ccc#endifgloble VOID *genlongalloc(size) unsigned long size; {#if (! MAC) && (! IBM_TBC) && (! IBM_MSC) && (! IBM_ICB) && (! IBM_ZTC) && (! IBM_SC) unsigned int test;#else VOID *memPtr;#endif#if BLOCK_MEMORY struct longMemoryPtr *theLongMemory;#endif if (sizeof(int) == sizeof(long)) { return(genalloc((unsigned) size)); }#if (! MAC) && (! IBM_TBC) && (! IBM_MSC) && (! IBM_ICB) && (! IBM_ZTC) && (! IBM_SC) test = (unsigned int) size; if (test != size) { PrintErrorID("MEMORY",3,CLIPS_TRUE); PrintCLIPS(WERROR,"Unable to allocate memory block > 32K.\n"); ExitCLIPS(1); } return((VOID *) genalloc((unsigned) test));#else#if BLOCK_MEMORY size += sizeof(struct longMemoryPtr);#endif memPtr = (VOID *) SpecialMalloc(size); if (memPtr == NULL) { ReleaseMem((long) ((size * 5 > 4096) ? size * 5 : 4096),CLIPS_FALSE); memPtr = (VOID *) SpecialMalloc(size); if (memPtr == NULL) { ReleaseMem(-1L,CLIPS_TRUE); memPtr = (VOID *) SpecialMalloc(size); while (memPtr == NULL) { if ((*OutOfMemoryFunction)(size)) return(NULL); memPtr = (VOID *) SpecialMalloc(size); } } } MemoryAmount += size; MemoryCalls++; #if BLOCK_MEMORY theLongMemory = (struct longMemoryPtr *) memPtr; theLongMemory->next = TopLongMemoryPtr; theLongMemory->prev = NULL; theLongMemory->size = 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#endifgloble int genlongfree(ptr,size) VOID *ptr; unsigned long size; {#if (! MAC) && (! IBM_TBC) && (! IBM_MSC) && (! IBM_ICB) && (! IBM_ZTC) && (! IBM_SC) unsigned int test;#endif#if BLOCK_MEMORY struct longMemoryPtr *theLongMemory;#endif if (sizeof(unsigned int) == sizeof(unsigned long)) { return(genfree((VOID *) ptr,(unsigned) size)); } #if (! MAC) && (! IBM_TBC) && (! IBM_MSC) && (! IBM_ICB) && (! IBM_ZTC) && (! IBM_SC) test = (unsigned int) size; if (test != size) return(-1); return(genfree((VOID *) ptr,(unsigned) test));#endif #if BLOCK_MEMORY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -