home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / Found / FWMemory / FWFixMem.cpp next >
Encoding:
Text File  |  1996-09-17  |  5.8 KB  |  200 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWFixMem.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFound.hpp"
  11.  
  12. #ifndef   FWMEMMGR_H
  13. #include "FWMemMgr.h"
  14. #endif
  15.  
  16. #ifndef FWFIXMEM_H
  17. #include "FWFixMem.h"
  18. #endif
  19.  
  20. #ifndef FWDEBUG_H
  21. #include "FWDebug.h"
  22. #endif
  23.  
  24. #ifdef FW_DEBUG
  25. #include <stdio.h>
  26. #endif
  27.  
  28. #ifdef FW_BUILD_MAC
  29. #pragma segment FWMemory
  30. #endif
  31.  
  32. //========================================================================================
  33. // STRUCT FW_SPrivFixedNode
  34. //========================================================================================
  35.  
  36. struct FW_SPrivFixedNode
  37. {
  38.     FW_SPrivFixedNode*    fNext;
  39.  
  40.     static    FW_SPrivFixedNode*    FromMemBlock(void* memblock);
  41. };
  42.  
  43. //----------------------------------------------------------------------------------------
  44. // FW_SPrivFixedNode::FromMemBlock
  45. //----------------------------------------------------------------------------------------
  46.  
  47. FW_SPrivFixedNode*    FW_SPrivFixedNode::FromMemBlock(void* memBlock)
  48. {
  49.     FW_SPrivFixedNode* node = (FW_SPrivFixedNode*) memBlock;
  50.     return node;
  51. }
  52.  
  53. //========================================================================================
  54. // STRUCT FW_SPrivFixedBlock
  55. //========================================================================================
  56.  
  57. struct FW_SPrivFixedBlock
  58. {
  59.     FW_SPrivFixedBlock*    fNext;
  60.     
  61.     static    FW_SPrivFixedBlock*    Allocate(short nNodeSize, short nNodes,
  62.                                     FW_SPrivFixedNode*& firstNode, FW_SPrivFixedNode*& lastNode);
  63.     static    void                Free(FW_SPrivFixedBlock* block);
  64. };
  65.  
  66. //----------------------------------------------------------------------------------------
  67. // FW_SPrivFixedBlock::Allocate
  68. //----------------------------------------------------------------------------------------
  69.  
  70. FW_SPrivFixedBlock*    FW_SPrivFixedBlock::Allocate(short nNodeSize, short nNodes,
  71.                                     FW_SPrivFixedNode*& firstNode, FW_SPrivFixedNode*& lastNode)
  72. {
  73.     FW_ASSERT(nNodeSize >= sizeof(FW_SPrivFixedNode));
  74.  
  75.     // Allocate the large memory block
  76.     FW_SPrivFixedBlock* block = (FW_SPrivFixedBlock*)
  77.         FW_CMemoryManager::AllocateBlock((unsigned long) nNodeSize * nNodes + sizeof(FW_SPrivFixedBlock));
  78.     void* blockData = block + 1;    
  79.  
  80.     // Set first and last pointers
  81.     firstNode = (FW_SPrivFixedNode*) blockData;
  82.     lastNode  = (FW_SPrivFixedNode*) (((char*) blockData) + nNodeSize * (nNodes - 1));
  83.  
  84.     // Slice and dice the block
  85.     lastNode->fNext = NULL;
  86.     FW_SPrivFixedNode* node = (FW_SPrivFixedNode*) blockData;
  87.     for (short n = 0; n < nNodes - 1; ++ n)
  88.     {
  89.         FW_SPrivFixedNode* next = (FW_SPrivFixedNode*) (((char*) node) + nNodeSize);
  90.         node->fNext = next;
  91.         node = next;
  92.     }
  93.     FW_ASSERT(node == lastNode);
  94.  
  95.     // Return the whole block
  96.     return block;
  97. }
  98.  
  99. //----------------------------------------------------------------------------------------
  100. // FW_SPrivFixedBlock::Free
  101. //----------------------------------------------------------------------------------------
  102.  
  103. void FW_SPrivFixedBlock::Free(FW_SPrivFixedBlock* block)
  104. {
  105.     FW_CMemoryManager::FreeBlock(block);
  106. }
  107.  
  108. //========================================================================================
  109. // CLASS FW_CFixedAllocator
  110. //========================================================================================
  111.  
  112. const int kNodesPerBlock    = 100;
  113.  
  114. //----------------------------------------------------------------------------------------
  115. // FW_CFixedAllocator::FW_CFixedAllocator
  116. //----------------------------------------------------------------------------------------
  117.  
  118. FW_CFixedAllocator::FW_CFixedAllocator(short allocSize
  119. #ifdef FW_DEBUG
  120.     , const char* name
  121. #endif                            
  122.     ) :
  123.     fAllocCount(0),
  124.     fAllocSize((allocSize + 3) & ~3),        // Round the size up to a multiple of 4 bytes
  125.     fFreeList(NULL),
  126.     fBlockList(NULL)
  127. {
  128. #ifdef FW_DEBUG
  129.     fDebugName = name;
  130. #endif
  131. }
  132.  
  133. //----------------------------------------------------------------------------------------
  134. // FW_CFixedAllocator::~FW_CFixedAllocator
  135. //----------------------------------------------------------------------------------------
  136.  
  137. FW_CFixedAllocator::~FW_CFixedAllocator()
  138. {
  139. #ifdef FW_DEBUG
  140.     if (fAllocCount != 0 || fFreeList != NULL || fBlockList != NULL)
  141.     {
  142.         char s[255];
  143.         sprintf(s, "%s %s %s", "FW_CFixedAllocator: An object of type", fDebugName, "has not been deleted properly.");
  144.         FW_DEBUG_MESSAGE(s);
  145.     }
  146. #endif
  147. }
  148.  
  149. //----------------------------------------------------------------------------------------
  150. // FW_CFixedAllocator::Allocate
  151. //----------------------------------------------------------------------------------------
  152.  
  153. void* FW_CFixedAllocator::Allocate()
  154. {
  155.     // Make sure there is something on our free list
  156.     if (fFreeList == NULL)
  157.     {
  158.         FW_SPrivFixedNode *firstNode, *lastNode;
  159.         FW_SPrivFixedBlock *newBlock =
  160.             FW_SPrivFixedBlock::Allocate(fAllocSize, kNodesPerBlock, firstNode, lastNode);
  161.  
  162.         lastNode->fNext = fFreeList;
  163.         fFreeList = firstNode;
  164.  
  165.         newBlock->fNext = fBlockList;
  166.         fBlockList = newBlock;
  167.     }
  168.     
  169.     // Take the first node from the free list
  170.     void* newNode = fFreeList;
  171.     fFreeList = fFreeList->fNext;
  172.     ++ fAllocCount;
  173.     return newNode;
  174. }
  175.  
  176. //----------------------------------------------------------------------------------------
  177. // FW_CFixedAllocator::Free
  178. //----------------------------------------------------------------------------------------
  179.  
  180. void FW_CFixedAllocator::Free(void* block)
  181. {
  182.     // Return the block to the free node list
  183.     FW_SPrivFixedNode* node = FW_SPrivFixedNode::FromMemBlock(block);
  184.     node->fNext = fFreeList;
  185.     fFreeList = node;
  186.  
  187.     // If no more nodes, free the whole list
  188.     if (-- fAllocCount == 0)
  189.     {
  190.         while (fBlockList != NULL)
  191.         {
  192.             FW_SPrivFixedBlock*    next = fBlockList->fNext;
  193.             FW_SPrivFixedBlock::Free(fBlockList);
  194.             fBlockList = next;
  195.         }
  196.         
  197.         fFreeList = NULL;
  198.     }
  199. }
  200.