Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.2 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. bsfixalloc.cxx
  5. Abstract:
  6. Adapted from MFC 6 SR 1 release of fixalloc.cpp. Removed all MFC stuff.
  7. Author:
  8. Stefan R. Steiner [ssteiner] 4-10-2000
  9. Revision History:
  10. --*/
  11. // fixalloc.cpp - implementation of fixed block allocator
  12. #include <windows.h>
  13. #include <assert.h>
  14. #include "bsfixalloc.hxx"
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static char THIS_FILE[] = __FILE__;
  18. // #define new DEBUG_NEW
  19. #endif
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CBsFixedAlloc
  22. CBsFixedAlloc::CBsFixedAlloc(UINT nAllocSize, UINT nBlockSize)
  23. {
  24. assert(nAllocSize >= sizeof(CNode));
  25. assert(nBlockSize > 1);
  26. //wprintf( L"CBsFixedAlloc called, nAllocSize: %d, nBlockSize: %d\n", nAllocSize, nBlockSize );
  27. m_nAllocSize = nAllocSize;
  28. m_nBlockSize = nBlockSize;
  29. m_pNodeFree = NULL;
  30. m_pBlocks = NULL;
  31. InitializeCriticalSection(&m_protect);
  32. }
  33. CBsFixedAlloc::~CBsFixedAlloc()
  34. {
  35. FreeAll();
  36. DeleteCriticalSection(&m_protect);
  37. }
  38. void CBsFixedAlloc::FreeAll()
  39. {
  40. EnterCriticalSection(&m_protect);
  41. m_pBlocks->FreeDataChain();
  42. m_pBlocks = NULL;
  43. m_pNodeFree = NULL;
  44. LeaveCriticalSection(&m_protect);
  45. }
  46. void* CBsFixedAlloc::Alloc()
  47. {
  48. EnterCriticalSection(&m_protect);
  49. if (m_pNodeFree == NULL)
  50. {
  51. CBsPlex* pNewBlock = NULL;
  52. try
  53. {
  54. // add another block
  55. pNewBlock = CBsPlex::Create(m_pBlocks, m_nBlockSize, m_nAllocSize);
  56. //wprintf( L"Alloc getting more core, nAllocSize: %d\n", m_nAllocSize );
  57. }
  58. catch( ... )
  59. {
  60. LeaveCriticalSection(&m_protect);
  61. throw;
  62. }
  63. // chain them into free list
  64. CNode* pNode = (CNode*)pNewBlock->data();
  65. // free in reverse order to make it easier to debug
  66. (BYTE*&)pNode += (m_nAllocSize * m_nBlockSize) - m_nAllocSize;
  67. for (int i = m_nBlockSize-1; i >= 0; i--, (BYTE*&)pNode -= m_nAllocSize)
  68. {
  69. pNode->pNext = m_pNodeFree;
  70. m_pNodeFree = pNode;
  71. }
  72. }
  73. assert(m_pNodeFree != NULL); // we must have something
  74. // remove the first available node from the free list
  75. void* pNode = m_pNodeFree;
  76. m_pNodeFree = m_pNodeFree->pNext;
  77. LeaveCriticalSection(&m_protect);
  78. return pNode;
  79. }
  80. void CBsFixedAlloc::Free(void* p)
  81. {
  82. if (p != NULL)
  83. {
  84. EnterCriticalSection(&m_protect);
  85. // simply return the node to the free list
  86. CNode* pNode = (CNode*)p;
  87. pNode->pNext = m_pNodeFree;
  88. m_pNodeFree = pNode;
  89. LeaveCriticalSection(&m_protect);
  90. }
  91. }
  92. /////////////////////////////////////////////////////////////////////////////
  93. // CBsPlex
  94. // throws E_OUTOFMEMORY
  95. CBsPlex* PASCAL CBsPlex::Create(CBsPlex*& pHead, UINT nMax, UINT cbElement)
  96. {
  97. assert(nMax > 0 && cbElement > 0);
  98. CBsPlex* p = (CBsPlex*) new BYTE[sizeof(CBsPlex) + nMax * cbElement];
  99. if ( p == NULL ) // prefix #118827
  100. throw E_OUTOFMEMORY;
  101. p->pNext = pHead;
  102. pHead = p; // change head (adds in reverse order for simplicity)
  103. return p;
  104. }
  105. void CBsPlex::FreeDataChain() // free this one and links
  106. {
  107. CBsPlex* p = this;
  108. while (p != NULL)
  109. {
  110. BYTE* bytes = (BYTE*) p;
  111. CBsPlex* pNext = p->pNext;
  112. delete[] bytes;
  113. p = pNext;
  114. }
  115. }