⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memalloc.c

📁 VC嵌入式CLips专家系统,实现战场环境的目标识别
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/
   /*      "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 || IBM_ICB
#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;
   
   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,
  unsigned int 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);
        
   if (memPtr == NULL)
     {
      EnvReleaseMem(theEnv,(long) ((size * 5 > 4096) ? size * 5 : 4096),FALSE);
      memPtr = (char *) malloc((STD_SIZE) size);
      if (memPtr == NULL)
        {
         EnvReleaseMem(theEnv,-1L,TRUE);
         memPtr = (char *) malloc((STD_SIZE) size);
         while (memPtr == NULL)
           {
            if ((*MemoryData(theEnv)->OutOfMemoryFunction)(theEnv,(unsigned long) size))
              return(NULL);
            memPtr = (char *) malloc((STD_SIZE) 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
#endif
globle int DefaultOutOfMemoryFunction(
  void *theEnv,
  unsigned long 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 *,unsigned long)))(void *,unsigned long)
  {
   int (*tmpPtr)(void *,unsigned long);

   tmpPtr = MemoryData(theEnv)->OutOfMemoryFunction;
   MemoryData(theEnv)->OutOfMemoryFunction = functionPtr;
   return(tmpPtr);
  }

/****************************************************/
/* genfree: A generic memory deallocation function. */
/****************************************************/
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
   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,
  unsigned oldsz,
  unsigned newsz)
  {
   char *newaddr;
   unsigned i;
   unsigned 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);
  }

/************************************************/
/* 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.  */
/********************************/
globle long int EnvMemUsed(
  void *theEnv)
  {
   return(MemoryData(theEnv)->MemoryAmount);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -