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.

147 lines
3.2 KiB

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