home *** CD-ROM | disk | FTP | other *** search
- // fixalloc.cpp - implementation of fixed block allocator
-
- #include "stdafx.h"
- #include "fixalloc.h"
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
-
- #define new DEBUG_NEW
- #endif
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CFixedAlloc
-
- CFixedAlloc::CFixedAlloc(UINT nAllocSize, UINT nBlockSize)
- {
- ASSERT(nAllocSize >= sizeof(CNode));
- ASSERT(nBlockSize > 1);
-
- m_nAllocSize = nAllocSize;
- m_nBlockSize = nBlockSize;
- m_pNodeFree = NULL;
- m_pBlocks = NULL;
- InitializeCriticalSection(&m_protect);
- }
-
- CFixedAlloc::~CFixedAlloc()
- {
- FreeAll();
- DeleteCriticalSection(&m_protect);
- }
-
- void CFixedAlloc::FreeAll()
- {
- EnterCriticalSection(&m_protect);
- m_pBlocks->FreeDataChain();
- m_pBlocks = NULL;
- m_pNodeFree = NULL;
- LeaveCriticalSection(&m_protect);
- }
-
- void* CFixedAlloc::Alloc()
- {
- EnterCriticalSection(&m_protect);
- if (m_pNodeFree == NULL)
- {
- CPlex* pNewBlock = NULL;
- TRY
- {
- // add another block
- pNewBlock = CPlex::Create(m_pBlocks, m_nBlockSize, m_nAllocSize);
- }
- CATCH_ALL(e)
- {
- LeaveCriticalSection(&m_protect);
- THROW_LAST();
- }
- END_CATCH_ALL
-
- // chain them into free list
- CNode* pNode = (CNode*)pNewBlock->data();
- // free in reverse order to make it easier to debug
- (BYTE*&)pNode += (m_nAllocSize * m_nBlockSize) - m_nAllocSize;
- for (int i = m_nBlockSize-1; i >= 0; i--, (BYTE*&)pNode -= m_nAllocSize)
- {
- pNode->pNext = m_pNodeFree;
- m_pNodeFree = pNode;
- }
- }
- ASSERT(m_pNodeFree != NULL); // we must have something
-
- // remove the first available node from the free list
- void* pNode = m_pNodeFree;
- m_pNodeFree = m_pNodeFree->pNext;
-
- LeaveCriticalSection(&m_protect);
- return pNode;
- }
-
- void CFixedAlloc::Free(void* p)
- {
- if (p != NULL)
- {
- EnterCriticalSection(&m_protect);
-
- // simply return the node to the free list
- CNode* pNode = (CNode*)p;
- pNode->pNext = m_pNodeFree;
- m_pNodeFree = pNode;
- LeaveCriticalSection(&m_protect);
- }
- }
-