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.
204 lines
4.6 KiB
204 lines
4.6 KiB
/*++
|
|
|
|
Copyright (C) 1998-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
NEWNEW.H
|
|
|
|
Abstract:
|
|
|
|
CReuseMemoryManager
|
|
|
|
History:
|
|
|
|
--*/
|
|
|
|
#ifndef __WBEM_NEW_NEW__H_
|
|
#define __WBEM_NEW_NEW__H_
|
|
|
|
#include "esscpol.h"
|
|
#include <stack>
|
|
|
|
class ESSCLI_POLARITY CReuseMemoryManager
|
|
{
|
|
protected:
|
|
CCritSec m_cs;
|
|
CFlexQueue m_Available;
|
|
int m_nSize;
|
|
int m_nMaxQueued;
|
|
public:
|
|
CReuseMemoryManager(size_t nSize, size_t nMaxQueued = 0 )
|
|
: m_nSize(nSize)
|
|
{
|
|
m_nMaxQueued = nMaxQueued == 0 ? 256 : nMaxQueued;
|
|
}
|
|
|
|
~CReuseMemoryManager()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void* Allocate()
|
|
{
|
|
CInCritSec ics(&m_cs);
|
|
|
|
if(m_Available.GetQueueSize() == 0)
|
|
{
|
|
return new BYTE[m_nSize];
|
|
}
|
|
else
|
|
{
|
|
void* p = m_Available.Unqueue();
|
|
return p;
|
|
}
|
|
}
|
|
|
|
void Free(void* p)
|
|
{
|
|
CInCritSec ics(&m_cs);
|
|
|
|
if ( m_Available.GetQueueSize() < m_nMaxQueued )
|
|
{
|
|
m_Available.Enqueue(p);
|
|
}
|
|
else
|
|
{
|
|
delete [] (BYTE*)p;
|
|
}
|
|
}
|
|
|
|
void Clear()
|
|
{
|
|
CInCritSec ics(&m_cs);
|
|
|
|
while(m_Available.GetQueueSize())
|
|
{
|
|
delete [] (BYTE*)m_Available.Unqueue();
|
|
}
|
|
}
|
|
};
|
|
|
|
#define DWORD_ALIGNED(x) (((x) + 3) & ~3)
|
|
#define QWORD_ALIGNED(x) (((x) + 7) & ~7)
|
|
|
|
#ifdef _WIN64
|
|
#define DEF_ALIGNED QWORD_ALIGNED
|
|
#else
|
|
#define DEF_ALIGNED DWORD_ALIGNED
|
|
#endif
|
|
|
|
class ESSCLI_POLARITY CTempMemoryManager
|
|
{
|
|
protected:
|
|
CCritSec m_cs;
|
|
|
|
class CAllocation
|
|
{
|
|
private:
|
|
size_t m_dwAllocationSize;
|
|
size_t m_dwUsed;
|
|
size_t m_dwFirstFree;
|
|
|
|
static inline size_t GetHeaderSize() {return sizeof(CAllocation);}
|
|
inline byte* GetStart() {return ((byte*)this) + GetHeaderSize();}
|
|
inline byte* GetEnd() {return ((byte*)this) + m_dwAllocationSize;}
|
|
|
|
public:
|
|
size_t GetAllocationSize() {return m_dwAllocationSize;}
|
|
size_t GetUsedSize() {return m_dwUsed;}
|
|
static size_t GetMinAllocationSize(size_t dwBlock)
|
|
{return dwBlock + GetHeaderSize();}
|
|
|
|
void Init(size_t dwAllocationSize);
|
|
void* Alloc(size_t nBlockSize);
|
|
bool Contains(void* p);
|
|
bool Free(size_t nBlockSize);
|
|
void Destroy();
|
|
};
|
|
|
|
CPointerArray<CAllocation>* m_pAllocations;
|
|
DWORD m_dwTotalUsed;
|
|
DWORD m_dwTotalAllocated;
|
|
DWORD m_dwNumAllocations;
|
|
DWORD m_dwNumMisses;
|
|
|
|
protected:
|
|
inline size_t RoundUp(size_t nSize) {return DEF_ALIGNED(nSize);}
|
|
|
|
public:
|
|
CTempMemoryManager();
|
|
~CTempMemoryManager();
|
|
|
|
void* Allocate(size_t nBlockSize);
|
|
void Free(void* p, size_t nBlockSize);
|
|
void Clear();
|
|
};
|
|
|
|
#define MAX_ALLOCA_USE 100
|
|
|
|
template <class TArg>
|
|
class CTempArray
|
|
{
|
|
protected:
|
|
BYTE* m_a;
|
|
BOOL m_bStack;
|
|
int m_nByteSize;
|
|
|
|
TArg* GetArray() {return (TArg*)m_a;}
|
|
const TArg* GetArray() const {return (const TArg*)m_a;}
|
|
public:
|
|
inline CTempArray() : m_a(NULL), m_bStack(TRUE), m_nByteSize(0){}
|
|
|
|
inline ~CTempArray()
|
|
{
|
|
if(!m_bStack)
|
|
delete [] m_a;
|
|
}
|
|
|
|
operator TArg*() {return (TArg*)m_a;}
|
|
operator const TArg*() const {return (const TArg*)m_a;}
|
|
|
|
TArg& operator[](int nIndex) {return GetArray()[nIndex];}
|
|
const TArg& operator[](int nIndex) const {return GetArray()[nIndex];}
|
|
TArg& operator[](long lIndex) {return GetArray()[lIndex];}
|
|
const TArg& operator[](long lIndex) const {return GetArray()[lIndex];}
|
|
|
|
void SetMem(void* p) {m_a = (BYTE*)p;}
|
|
BOOL SetSize(int nSize)
|
|
{
|
|
m_nByteSize = nSize * sizeof(TArg);
|
|
if(m_nByteSize < MAX_ALLOCA_USE)
|
|
{
|
|
m_bStack = TRUE;
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
m_bStack = FALSE;
|
|
return FALSE;
|
|
}
|
|
}
|
|
int GetByteSize() {return m_nByteSize;}
|
|
BOOL IsNull() {return (m_a == NULL);}
|
|
};
|
|
|
|
|
|
// This macro initializes the CTempArray with a given size. First it "sets" the
|
|
// size into the array, which returns TRUE if _alloca can be used. If so, it
|
|
// uses alloca on the now-computed byte size of the array.
|
|
|
|
#define INIT_TEMP_ARRAY(ARRAY, SIZE) \
|
|
((ARRAY.SetMem( \
|
|
(ARRAY.SetSize(SIZE)) ? \
|
|
_alloca(ARRAY.GetByteSize()) : \
|
|
new BYTE[ARRAY.GetByteSize()] \
|
|
) \
|
|
), !ARRAY.IsNull()) \
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|