?? memalloc.c
字號:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.24 06/05/06 */ /* */ /* MEMORY MODULE */ /*******************************************************//*************************************************************//* Purpose: Memory allocation routines. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* Brian L. Donnell *//* *//* Revision History: *//* *//* 6.24: Removed HaltExecution check from the *//* EnvReleaseMem function. DR0863 *//* *//* Renamed BOOLEAN macro type to intBool. *//* *//* Corrected code to remove compiler warnings. *//* *//*************************************************************/#define _MEMORY_SOURCE_#include <stdio.h>#define _STDIO_INCLUDED_#include "setup.h"#include "constant.h"#include "envrnmnt.h"#include "memalloc.h"#include "router.h"#include "utility.h"#include <stdlib.h>#if IBM_TBC#include <alloc.h>#endif#if IBM_MSC#include <malloc.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 *,size_t);#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; MemoryData(theEnv)->MemoryTable = (struct memoryPtr **) malloc((STD_SIZE) (sizeof(struct memoryPtr *) * MEM_TABLE_SIZE)); if (MemoryData(theEnv)->MemoryTable == NULL) { PrintErrorID(theEnv,"MEMORY",1,TRUE); EnvPrintRouter(theEnv,WERROR,"Out of memory.\n"); EnvExitRouter(theEnv,EXIT_FAILURE); } for (i = 0; i < MEM_TABLE_SIZE; i++) MemoryData(theEnv)->MemoryTable[i] = NULL; }/***************************************************//* genalloc: A generic memory allocation function. *//***************************************************/globle void *genalloc( void *theEnv, 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(size); if (memPtr == NULL) { EnvReleaseMem(theEnv,(long) ((size * 5 > 4096) ? size * 5 : 4096),FALSE); memPtr = (char *) malloc(size); if (memPtr == NULL) { EnvReleaseMem(theEnv,-1L,TRUE); memPtr = (char *) malloc(size); while (memPtr == NULL) { if ((*MemoryData(theEnv)->OutOfMemoryFunction)(theEnv,size)) return(NULL); memPtr = (char *) malloc(size); } } }#endif MemoryData(theEnv)->MemoryAmount += (long) size; MemoryData(theEnv)->MemoryCalls++; return((void *) memPtr); }/***********************************************//* DefaultOutOfMemoryFunction: Function called *//* when the KB runs out of memory. *//***********************************************/#if IBM_TBC#pragma argsused#endifgloble int DefaultOutOfMemoryFunction( void *theEnv, size_t size) {#if MAC_MCW || IBM_MCW || MAC_XCD#pragma unused(size)#endif PrintErrorID(theEnv,"MEMORY",1,TRUE); EnvPrintRouter(theEnv,WERROR,"Out of memory.\n"); EnvExitRouter(theEnv,EXIT_FAILURE); return(TRUE); }/***********************************************************//* 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 *,size_t)))(void *,size_t) { int (*tmpPtr)(void *,size_t); tmpPtr = MemoryData(theEnv)->OutOfMemoryFunction; MemoryData(theEnv)->OutOfMemoryFunction = functionPtr; return(tmpPtr); }/****************************************************//* genfree: A generic memory deallocation function. *//****************************************************/globle int genfree( void *theEnv, void *waste, size_t 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 free(waste);#endif MemoryData(theEnv)->MemoryAmount -= (long) size; MemoryData(theEnv)->MemoryCalls--; return(0); }/******************************************************//* genrealloc: Simple (i.e. dumb) version of realloc. *//******************************************************/globle void *genrealloc( void *theEnv, void *oldaddr, size_t oldsz, size_t newsz) { char *newaddr; unsigned i; size_t limit; newaddr = ((newsz != 0) ? (char *) gm2(theEnv,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(theEnv,(void *) oldaddr,oldsz); } return((void *) newaddr); }/********************************//* EnvMemUsed: C access routine *//* for the mem-used command. *//********************************/globle long int EnvMemUsed( void *theEnv) { return(MemoryData(theEnv)->MemoryAmount); }/************************************//* EnvMemRequests: C access routine *//* for the mem-requests command. *//************************************/globle long int EnvMemRequests( void *theEnv) { return(MemoryData(theEnv)->MemoryCalls); }/***************************************//* UpdateMemoryUsed: Allows the amount *//* of memory used to be updated. *//***************************************/globle long int UpdateMemoryUsed( void *theEnv, long int value) { MemoryData(theEnv)->MemoryAmount += value; return(MemoryData(theEnv)->MemoryAmount); }/*******************************************//* UpdateMemoryRequests: Allows the number *//* of memory requests to be updated. *//*******************************************/globle long int UpdateMemoryRequests( void *theEnv, long int value) { MemoryData(theEnv)->MemoryCalls += value; return(MemoryData(theEnv)->MemoryCalls); }/***********************************//* EnvReleaseMem: C access routine *//* for the release-mem command. *//***********************************/globle long int EnvReleaseMem( void *theEnv, long int maximum, int printMessage) { 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); memPtr = MemoryData(theEnv)->MemoryTable[i]; while (memPtr != NULL) { tmpPtr = memPtr->next; genfree(theEnv,(void *) memPtr,(unsigned) i); memPtr = tmpPtr; amount += i; returns++; if ((returns % 100) == 0) { YieldTime(theEnv); } } MemoryData(theEnv)->MemoryTable[i] = NULL; if ((amount > maximum) && (maximum > 0)) { if (printMessage == TRUE) { EnvPrintRouter(theEnv,WDIALOG,"*** MEMORY DEALLOCATED ***\n"); } return(amount); } } if (printMessage == TRUE) { EnvPrintRouter(theEnv,WDIALOG,"*** MEMORY DEALLOCATED ***\n"); } return(amount); }/*****************************************************//* gm1: Allocates memory and sets all bytes to zero. *//*****************************************************/globle void *gm1( void *theEnv, size_t size) { struct memoryPtr *memPtr; char *tmpPtr; size_t i; if (size < (long) sizeof(char *)) size = sizeof(char *);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -