fixalloc.cpp 2.0 KB

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