119 lines
2.4 KiB
C++
119 lines
2.4 KiB
C++
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Specialized allocators.
|
||
|
//
|
||
|
// Copyright (C) Microsoft Corporation, 2001.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include "pch.hpp"
|
||
|
|
||
|
#ifdef NT_NATIVE
|
||
|
#include "ntnative.h"
|
||
|
#endif
|
||
|
|
||
|
#include "cmnutil.hpp"
|
||
|
#include "alloc.hpp"
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
// FixedSizeStackAllocator.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
FixedSizeStackAllocator::FixedSizeStackAllocator(ULONG ChunkSize,
|
||
|
ULONG ChunksPerBlock,
|
||
|
BOOL KeepLastBlock)
|
||
|
{
|
||
|
C_ASSERT((sizeof(FixedSizeStackBlock) & 7) == 0);
|
||
|
|
||
|
if (ChunkSize == 0)
|
||
|
{
|
||
|
ChunkSize = sizeof(ULONG64);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ChunkSize = (ChunkSize + 7) & ~7;
|
||
|
}
|
||
|
if (ChunksPerBlock == 0)
|
||
|
{
|
||
|
ChunksPerBlock = 32;
|
||
|
}
|
||
|
|
||
|
m_ChunkSize = ChunkSize;
|
||
|
m_KeepLastBlock = KeepLastBlock;
|
||
|
m_BlockSize = ChunkSize * ChunksPerBlock + sizeof(FixedSizeStackBlock);
|
||
|
m_NumAllocs = 0;
|
||
|
m_Blocks = NULL;
|
||
|
}
|
||
|
|
||
|
FixedSizeStackAllocator::~FixedSizeStackAllocator(void)
|
||
|
{
|
||
|
m_KeepLastBlock = FALSE;
|
||
|
FreeAll();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
FixedSizeStackAllocator::FreeAll(void)
|
||
|
{
|
||
|
FixedSizeStackBlock* Block;
|
||
|
|
||
|
while (m_Blocks)
|
||
|
{
|
||
|
Block = m_Blocks;
|
||
|
if (!Block->Next && m_KeepLastBlock)
|
||
|
{
|
||
|
Block->MemLimit = (PUCHAR)(Block + 1);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
m_Blocks = m_Blocks->Next;
|
||
|
RawFree(Block);
|
||
|
}
|
||
|
|
||
|
m_NumAllocs = 0;
|
||
|
}
|
||
|
|
||
|
void*
|
||
|
FixedSizeStackAllocator::RawAlloc(ULONG Bytes)
|
||
|
{
|
||
|
return malloc(Bytes);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
FixedSizeStackAllocator::RawFree(void* Mem)
|
||
|
{
|
||
|
free(Mem);
|
||
|
}
|
||
|
|
||
|
FixedSizeStackBlock*
|
||
|
FixedSizeStackAllocator::AllocBlock(void)
|
||
|
{
|
||
|
FixedSizeStackBlock* Block = (FixedSizeStackBlock*)RawAlloc(m_BlockSize);
|
||
|
if (!Block)
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
Block->Next = m_Blocks;
|
||
|
Block->MemLimit = (PUCHAR)(Block + 1);
|
||
|
m_Blocks = Block;
|
||
|
return Block;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
FixedSizeStackAllocator::FreeBlock(void)
|
||
|
{
|
||
|
FixedSizeStackBlock* Block = m_Blocks;
|
||
|
if (!Block->Next && m_KeepLastBlock)
|
||
|
{
|
||
|
// Sometimes it's desirable to keep the last block
|
||
|
// around to avoid forcing an alloc the next time
|
||
|
// the allocator is used.
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_Blocks = Block->Next;
|
||
|
RawFree(Block);
|
||
|
}
|