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

📄 memory.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
   TopMemoryBlock->size = usableBlockSize;   chunkPtr = (struct chunkInfo *) (((char *) TopMemoryBlock) + BlockInfoSize + ChunkInfoSize + usableBlockSize);   chunkPtr->nextFree = NULL;   chunkPtr->lastFree = NULL;   chunkPtr->prevChunk = TopMemoryBlock->nextFree;   chunkPtr->size = 0;   TopMemoryBlock->nextFree->nextFree = NULL;   TopMemoryBlock->nextFree->lastFree = NULL;   TopMemoryBlock->nextFree->prevChunk = NULL;   TopMemoryBlock->nextFree->size = usableBlockSize;   BlockMemoryInitialized = CLIPS_TRUE;   return(1);  }/***************************************************************************//* AllocateBlock: Adds a new block of memory to the list of memory blocks. *//***************************************************************************/static int AllocateBlock(blockPtr,requestSize)  struct blockInfo *blockPtr;  unsigned int requestSize;  {   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 += BlockInfoSize + ChunkInfoSize * 2;   blockSize = (((blockSize - 1) / STRICT_ALIGN_SIZE) + 1) * STRICT_ALIGN_SIZE;   usableBlockSize = blockSize - BlockInfoSize - (2 * ChunkInfoSize);   /*=========================*/   /* Allocate the new block. */   /*=========================*/      newBlock = (struct blockInfo *) malloc((CLIPS_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) + BlockInfoSize);   newBlock->size = usableBlockSize;   blockPtr->nextBlock = newBlock;   newTopChunk = (struct chunkInfo *) (((char *) newBlock) + BlockInfoSize + 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 = usableBlockSize;   return(1);  }/*******************************************************//* RequestChunk: Allocates memory by returning a chunk *//*   of memory from a larger block of memory.          *//*******************************************************/globle VOID *RequestChunk(requestSize)  unsigned int requestSize;  {   struct chunkInfo *chunkPtr;   struct blockInfo *blockPtr;      /*==================================================*/   /* Allocate initial memory pool block if it has not */   /* already been allocated.                          */   /*==================================================*/   if (BlockMemoryInitialized == CLIPS_FALSE)      {        if (InitializeBlockMemory(requestSize) == 0) return(NULL);        AddRouter("bmexit",-2000,NULL,NULL,NULL,NULL,BlockMemoryExitFunction);      }   /*====================================================*/   /* 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 = TopMemoryBlock;   while (blockPtr != NULL)     {      chunkPtr = blockPtr->nextFree;      while (chunkPtr != NULL)        {         if ((chunkPtr->size == requestSize) ||             (chunkPtr->size > (requestSize + ChunkInfoSize)))           {            AllocateChunk(blockPtr,chunkPtr,requestSize);            return((VOID *) (((char *) chunkPtr) + ChunkInfoSize));           }         chunkPtr = chunkPtr->nextFree;        }      if (blockPtr->nextBlock == NULL)        {         if (AllocateBlock(blockPtr,requestSize) == 0)  /* get another block */           { return(NULL); }        }      blockPtr = blockPtr->nextBlock;     }   CLIPSSystemError("MEMORY",2);   ExitCLIPS(1);   return(NULL); /* Unreachable, but prevents warning. */  }/********************************************//* AllocateChunk: Allocates a chunk from an *//*   existing chunk in a block of memory.   *//********************************************/static VOID AllocateChunk(parentBlock,chunkPtr,requestSize)  struct blockInfo *parentBlock;  struct chunkInfo *chunkPtr;  unsigned int requestSize;  {   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) + ChunkInfoSize + chunkPtr->size);   splitChunk = (struct chunkInfo *)                  (((char *) chunkPtr) + (ChunkInfoSize + requestSize));   splitChunk->size = chunkPtr->size - (requestSize + 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;  }/***********************************************************//* ReturnChunk: Frees memory allocated using RequestChunk. *//***********************************************************/globle int ReturnChunk(memPtr,size)  VOID *memPtr;  unsigned int size;  {   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) - ChunkInfoSize);   if (chunkPtr == NULL)     { return(CLIPS_FALSE); }   if (chunkPtr->size >= 0)     { return(CLIPS_FALSE); }   if (chunkPtr->size != - (long int) size)     { return(CLIPS_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) - 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 += (ChunkInfoSize + chunkPtr->size);         if (nextChunk != NULL)           { nextChunk->prevChunk = lastChunk; }         else           { return(CLIPS_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(CLIPS_FALSE);   if (chunkPtr == NULL) return(CLIPS_FALSE);   if (nextChunk->size > 0)     {      chunkPtr->size += (ChunkInfoSize + nextChunk->size);      topChunk = (struct chunkInfo *) (((char *) nextChunk) + nextChunk->size + ChunkInfoSize);      if (topChunk != NULL)        { topChunk->prevChunk = chunkPtr; }      else        { return(CLIPS_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;            TopMemoryBlock = blockPtr->nextBlock;            free((char *) blockPtr);           }        }     }   return(CLIPS_TRUE);  }/***********************************************//* ReturnAllBlocks: Frees all allocated blocks *//*   back to the operating system.             *//***********************************************/static VOID ReturnAllBlocks()  {   struct blockInfo *theBlock, *nextBlock;   struct longMemoryPtr *theLongMemory, *nextLongMemory;    /*======================================*/   /* Free up int based memory allocation. */   /*======================================*/      theBlock = TopMemoryBlock;   while (theBlock != NULL)     {      nextBlock = theBlock->nextBlock;      free((char *) theBlock);      theBlock = nextBlock;     }    TopMemoryBlock = NULL;      /*=======================================*/   /* Free up long based memory allocation. */   /*=======================================*/      theLongMemory = TopLongMemoryPtr;   while (theLongMemory != NULL)     {      nextLongMemory = theLongMemory->next;      genlongfree(theLongMemory,theLongMemory->size);      theLongMemory = nextLongMemory;     }        TopLongMemoryPtr = NULL;  }/********************************************//* BlockMemoryExitFunction: Routine to free *//*   block memory when exiting CLIPS.       *//********************************************/static int BlockMemoryExitFunction(num)  int num;  {   ReturnAllBlocks();   return(1);  }#endif

⌨️ 快捷键说明

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