home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / fixalloc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-16  |  2.0 KB  |  95 lines

  1. // fixalloc.cpp - implementation of fixed block allocator
  2.  
  3. #include "stdafx.h"
  4. #include "fixalloc.h"
  5.  
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9.  
  10. #define new DEBUG_NEW
  11. #endif
  12.  
  13.  
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CFixedAlloc
  16.  
  17. CFixedAlloc::CFixedAlloc(UINT nAllocSize, UINT nBlockSize)
  18. {
  19.     ASSERT(nAllocSize >= sizeof(CNode));
  20.     ASSERT(nBlockSize > 1);
  21.  
  22.     m_nAllocSize = nAllocSize;
  23.     m_nBlockSize = nBlockSize;
  24.     m_pNodeFree = NULL;
  25.     m_pBlocks = NULL;
  26.     InitializeCriticalSection(&m_protect);
  27. }
  28.  
  29. CFixedAlloc::~CFixedAlloc()
  30. {
  31.     FreeAll();
  32.     DeleteCriticalSection(&m_protect);
  33. }
  34.  
  35. void CFixedAlloc::FreeAll()
  36. {
  37.     EnterCriticalSection(&m_protect);
  38.     m_pBlocks->FreeDataChain();
  39.     m_pBlocks = NULL;
  40.     m_pNodeFree = NULL;
  41.     LeaveCriticalSection(&m_protect);
  42. }
  43.  
  44. void* CFixedAlloc::Alloc()
  45. {
  46.     EnterCriticalSection(&m_protect);
  47.     if (m_pNodeFree == NULL)
  48.     {
  49.         CPlex* pNewBlock = NULL;
  50.         TRY
  51.         {
  52.             // add another block
  53.             pNewBlock = CPlex::Create(m_pBlocks, m_nBlockSize, m_nAllocSize);
  54.         }
  55.         CATCH_ALL(e)
  56.         {
  57.             LeaveCriticalSection(&m_protect);
  58.             THROW_LAST();
  59.         }
  60.         END_CATCH_ALL
  61.  
  62.         // chain them into free list
  63.         CNode* pNode = (CNode*)pNewBlock->data();
  64.         // free in reverse order to make it easier to debug
  65.         (BYTE*&)pNode += (m_nAllocSize * m_nBlockSize) - m_nAllocSize;
  66.         for (int i = m_nBlockSize-1; i >= 0; i--, (BYTE*&)pNode -= m_nAllocSize)
  67.         {
  68.             pNode->pNext = m_pNodeFree;
  69.             m_pNodeFree = pNode;
  70.         }
  71.     }
  72.     ASSERT(m_pNodeFree != NULL);  // we must have something
  73.  
  74.     // remove the first available node from the free list
  75.     void* pNode = m_pNodeFree;
  76.     m_pNodeFree = m_pNodeFree->pNext;
  77.  
  78.     LeaveCriticalSection(&m_protect);
  79.     return pNode;
  80. }
  81.  
  82. void CFixedAlloc::Free(void* p)
  83. {
  84.     if (p != NULL)
  85.     {
  86.         EnterCriticalSection(&m_protect);
  87.  
  88.         // simply return the node to the free list
  89.         CNode* pNode = (CNode*)p;
  90.         pNode->pNext = m_pNodeFree;
  91.         m_pNodeFree = pNode;
  92.         LeaveCriticalSection(&m_protect);
  93.     }
  94. }
  95.