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.
 
 
 
 
 
 

109 lines
3.2 KiB

/**************************************************************************\
*
* Copyright (c) 1998 Microsoft Corporation
*
* Module Name:
*
* Dynamic array implementation of StackBuffer class
*
* Abstract:
*
* This class provides a simple allocation scheme for a fixed size buffer.
*
* First case. Reserve of 128 bytes on the stack.
* Second case. Lookaside buffer, size equal to first usage of it.
* Third case. Allocate size on heap.
*
* This is much less flexible than the DynamicArray class, the break up of
* cost is basically as follows:
*
* First case. 1 assignment + 2 compare (no allocation)
* Second case. 1 assignment + 5 compare + 2 InterlockExchange's (pot. alloc)
* Third case. 1 assignment + 4 compare + GpMalloc + GpFree
*
* The cost is cheap for case one. For case two, Lock + Unlock is small
* and fast whereas case three is O(size of heap) in time. There is also
* the benefit of less fragmentation from fewer allocations.
*
* If you are considering using this code elsewhere, please contact Andrew
* Godfrey or Eric VandenBerg. It is important this class be used properly
* to ensure the performance benefit isn't adversely effected.
*
* The initialization and clean up of lookaside buffer is done in
* InitializeGdiplus() and UninitializeGdiplus().
*
* We provide the source here so it can be inlined easily.
*
\**************************************************************************/
#define INIT_SIZE 128 // 16 pairs of GpPoint types
class StackBuffer
{
private:
BYTE buffer[INIT_SIZE];
BYTE* allocBuffer;
public:
StackBuffer()
{
}
BYTE* GetBuffer(INT size)
{
if (size < 0)
{
return (allocBuffer = NULL);
}
else if (size<INIT_SIZE)
{
allocBuffer = NULL;
return &buffer[0];
}
else if (size>Globals::LookAsideBufferSize)
{
return (allocBuffer = (BYTE*)GpMalloc(size));
}
else
{
if ((CompareExchangeLong_Ptr(&Globals::LookAsideCount, 1, 0) == 0)
&& Globals::LookAsideCount == 1)
{
if (Globals::LookAsideBuffer == NULL)
{
Globals::LookAsideBufferSize = size + 128;
Globals::LookAsideBuffer = (BYTE*)GpMalloc(Globals::LookAsideBufferSize);
}
return (allocBuffer = Globals::LookAsideBuffer);
// we have exclusive access to lookaside
}
else
{
return (allocBuffer = (BYTE*)GpMalloc(size));
}
}
}
~StackBuffer()
{
if (allocBuffer != NULL)
{
if (allocBuffer == Globals::LookAsideBuffer)
{
ASSERT(Globals::LookAsideCount == 1); // should be true
CompareExchangeLong_Ptr(&Globals::LookAsideCount, 0, 1);
}
else
{
GpFree(allocBuffer);
}
}
}
};