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.
270 lines
9.1 KiB
270 lines
9.1 KiB
/***************************************************************************\
|
|
*
|
|
* File: SimpleHelp.h
|
|
*
|
|
* Description:
|
|
* SimpleHeap.h defines the heap operations used throughout DirectUser. See
|
|
* below for a description of the different heaps.
|
|
*
|
|
*
|
|
* History:
|
|
* 11/26/1999: JStall: Created
|
|
*
|
|
* Copyright (C) 2000 by Microsoft Corporation. All rights reserved.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
|
|
#if !defined(BASE__SimpleHeap_h__INCLUDED)
|
|
#define BASE__SimpleHeap_h__INCLUDED
|
|
|
|
#ifdef _X86_
|
|
#define USE_ROCKALL 1 // Use RockAll Research heap
|
|
#endif
|
|
|
|
#define USE_DYNAMICTLS 1 // Use Dynamic TLS using TlsAlloc()
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* Common memory management
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
//
|
|
// DirectUser supports multiple heaps used in different situations:
|
|
// - Default: Heap shared by all threads within a common Context
|
|
// - Context: Explicit heap for a (potentially different) Context- used cross-Context
|
|
// - Process: Shared heap available by all Context's within the process.
|
|
//
|
|
// NOTE: It is VERY important that the Alloc() and Free() calls are properly
|
|
// matched so that the memory is properly freed from the correct heap. If this
|
|
// is not done, the memory will not be freed and will result in memory leaks
|
|
// or potential process faults.
|
|
//
|
|
|
|
#if DBG
|
|
#define DBG_HEAP_PARAMS , const char * pszFileName, int idxLineNum
|
|
#define DBG_HEAP_USE do { pszFileName; idxLineNum; } while (0);
|
|
#else
|
|
#define DBG_HEAP_PARAMS
|
|
#define DBG_HEAP_USE
|
|
#endif
|
|
|
|
class DUserHeap
|
|
{
|
|
// Construction
|
|
public:
|
|
DUserHeap();
|
|
virtual ~DUserHeap() { }
|
|
|
|
enum EHeap
|
|
{
|
|
idProcessHeap = 0,
|
|
idNtHeap = 1,
|
|
#ifdef _DEBUG
|
|
idCrtDbgHeap = 2,
|
|
#endif
|
|
#if USE_ROCKALL
|
|
idRockAllHeap = 3,
|
|
#endif
|
|
};
|
|
|
|
// Operations
|
|
public:
|
|
virtual void * Alloc(SIZE_T cbSize, bool fZero DBG_HEAP_PARAMS) PURE;
|
|
virtual void * Realloc(void * pvMem, SIZE_T cbNewSize DBG_HEAP_PARAMS) PURE;
|
|
virtual void MultiAlloc(int * pnActual, void * prgAlloc[], int cItems, SIZE_T cbSize DBG_HEAP_PARAMS) PURE;
|
|
|
|
virtual void Free(void * pvMem) PURE;
|
|
virtual void MultiFree(int cItems, void * prgAlloc[], SIZE_T cbSize) PURE;
|
|
|
|
public:
|
|
void Lock();
|
|
BOOL Unlock();
|
|
|
|
// Data:
|
|
protected:
|
|
long m_cRef;
|
|
};
|
|
|
|
|
|
HRESULT CreateProcessHeap();
|
|
void DestroyProcessHeap();
|
|
HRESULT CreateContextHeap(DUserHeap * pLinkHeap, BOOL fThreadSafe, DUserHeap::EHeap id, DUserHeap ** ppNewHeap);
|
|
void DestroyContextHeap(DUserHeap * pHeapDestroy);
|
|
void ForceSetContextHeap(DUserHeap * pHeapThread);
|
|
|
|
|
|
extern DUserHeap * g_pheapProcess;
|
|
extern DWORD g_tlsHeap;
|
|
|
|
#define pProcessHeap g_pheapProcess
|
|
#define pContextHeap (reinterpret_cast<DUserHeap *> (TlsGetValue(g_tlsHeap)))
|
|
|
|
|
|
#if DBG
|
|
|
|
#define ClientAlloc(a) pContextHeap->Alloc(a, true, __FILE__, __LINE__)
|
|
#define ClientAlloc_(a,b) pContextHeap->Alloc(a, b, __FILE__, __LINE__)
|
|
#define ClientFree(a) pContextHeap->Free(a)
|
|
#define ClientRealloc(a,b) pContextHeap->Realloc(a, b, __FILE__, __LINE__)
|
|
#define ClientMultiAlloc(a,b,c,d) pContextHeap->MultiAlloc(a, b, c, d, __FILE__, __LINE__)
|
|
#define ClientMultiFree(a,b,c) pContextHeap->MultiFree(a,b,c)
|
|
|
|
#define ContextAlloc(p, a) p->Alloc(a, true, __FILE__, __LINE__)
|
|
#define ContextAlloc_(p, a, b) p->Alloc(a, b, __FILE__, __LINE__)
|
|
#define ContextFree(p, a) p->Free(a)
|
|
#define ContextRealloc(p, a, b) p->Realloc(a, b, __FILE__, __LINE__)
|
|
#define ContextMultiAlloc(p,a,b,c,d) p->MultiAlloc(a, b, c, d, __FILE__, __LINE__)
|
|
#define ContextMultiFree(p,a, b, c) p->MultiFree(a,b,c)
|
|
|
|
#define ProcessAlloc(a) pProcessHeap->Alloc(a, true, __FILE__, __LINE__)
|
|
#define ProcessAlloc_(a, b) pProcessHeap->Alloc(a, b, __FILE__, __LINE__)
|
|
#define ProcessFree(a) pProcessHeap->Free(a)
|
|
#define ProcessRealloc(a, b) pProcessHeap->Realloc(a, b, __FILE__, __LINE__)
|
|
#define ProcessMultiAlloc(a,b,c,d) pProcessHeap->MultiAlloc(a, b, c, d, __FILE__, __LINE__)
|
|
#define ProcessMultiFree(a, b, c) pProcessHeap->MultiFree(a,b,c)
|
|
|
|
void DumpData(void * pMem, int nLength);
|
|
|
|
|
|
#else // DBG
|
|
|
|
|
|
#define ClientAlloc(a) pContextHeap->Alloc(a, true)
|
|
#define ClientAlloc_(a,b) pContextHeap->Alloc(a, b)
|
|
#define ClientFree(a) pContextHeap->Free(a)
|
|
#define ClientRealloc(a,b) pContextHeap->Realloc(a, b)
|
|
#define ClientMultiAlloc(a,b,c,d) pContextHeap->MultiAlloc(a, b, c, d)
|
|
#define ClientMultiFree(a,b,c) pContextHeap->MultiFree(a,b,c)
|
|
|
|
#define ContextAlloc(p, a) p->Alloc(a, true)
|
|
#define ContextAlloc_(p, a, b) p->Alloc(a, b)
|
|
#define ContextFree(p, a) p->Free(a)
|
|
#define ContextRealloc(p, a, b) p->Realloc(a, b)
|
|
#define ContextMultiAlloc(p,a,b,c,d) p->MultiAlloc(a, b, c, d)
|
|
#define ContextMultiFree(p,a, b, c) p->MultiFree(a,b,c)
|
|
|
|
#define ProcessAlloc(a) pProcessHeap->Alloc(a, true)
|
|
#define ProcessAlloc_(a, b) pProcessHeap->Alloc(a, b)
|
|
#define ProcessFree(a) pProcessHeap->Free(a)
|
|
#define ProcessRealloc(a, b) pProcessHeap->Realloc(a, b)
|
|
#define ProcessMultiAlloc(a,b,c,d) pProcessHeap->MultiAlloc(a, b, c, d)
|
|
#define ProcessMultiFree(a, b, c) pProcessHeap->MultiFree(a,b,c)
|
|
|
|
|
|
#endif // DBG
|
|
|
|
|
|
/***************************************************************************\
|
|
*****************************************************************************
|
|
*
|
|
* operator new overloading
|
|
*
|
|
*****************************************************************************
|
|
\***************************************************************************/
|
|
|
|
#ifndef _INC_NEW
|
|
#include <new.h>
|
|
#endif
|
|
|
|
#if DBG
|
|
|
|
//
|
|
// Use this instead of the usual placement new syntax to avoid conflicts when
|
|
// 'new' is re-defined to provide memory leak tracking (below)
|
|
|
|
#define placement_new(pv, Class) PlacementNewImpl0<Class>(pv)
|
|
#define placement_new1(pv, Class, p1) PlacementNewImpl1<Class>(pv, p1)
|
|
#define placement_copynew(pv, Class, src) PlacementCopyNewImpl0<Class>(pv, src)
|
|
#define placement_delete(pv, Class) (((Class *)(pv))->~Class())
|
|
|
|
#ifdef new
|
|
#undef new
|
|
#endif
|
|
|
|
template <class T>
|
|
inline T *
|
|
PlacementNewImpl0(void *pv)
|
|
{
|
|
return new(pv) T;
|
|
};
|
|
|
|
template <class T, class Param1>
|
|
inline T *
|
|
PlacementNewImpl1(void *pv, Param1 p1)
|
|
{
|
|
return new(pv) T(p1);
|
|
};
|
|
|
|
template <class T>
|
|
inline T *
|
|
PlacementCopyNewImpl0(void *pv, const T & t)
|
|
{
|
|
return new(pv) T(t);
|
|
};
|
|
|
|
#else // DBG
|
|
|
|
#define DEBUG_NEW new
|
|
#define placement_new(pv, Class) new(pv) Class
|
|
#define placement_new1(pv, Class, p1) new(pv) Class(p1)
|
|
#define placement_copynew(pv, Class, src) new(pv) Class(src)
|
|
#define placement_delete(pv, Class) (((Class *)(pv))->~Class())
|
|
|
|
#endif // DBG
|
|
|
|
|
|
inline void * __cdecl operator new(size_t nSize)
|
|
{
|
|
void * pv = ClientAlloc(nSize);
|
|
return pv;
|
|
}
|
|
|
|
inline void __cdecl operator delete(void * pvMem)
|
|
{
|
|
ClientFree(pvMem);
|
|
}
|
|
|
|
#if DBG
|
|
template <class type> inline type * DoProcessNewDbg(const char * pszFileName, int idxLineNum);
|
|
template <class type> inline type * DoClientNewDbg(const char * pszFileName, int idxLineNum);
|
|
template <class type> inline type * DoContextNewDbg(DUserHeap * pHeap, const char * pszFileName, int idxLineNum);
|
|
#else
|
|
template <class type> inline type * DoProcessNew();
|
|
template <class type> inline type * DoClientNew();
|
|
template <class type> inline type * DoContextNew(DUserHeap * pHeap);
|
|
#endif
|
|
template <class type> inline void DoProcessDelete(type * pMem);
|
|
template <class type> inline void DoClientDelete(type * pMem);
|
|
template <class type> inline void DoContextDelete(DUserHeap * pHeap, type * pMem);
|
|
|
|
#if DBG
|
|
#define ProcessNew(t) DoProcessNewDbg<t>(__FILE__, __LINE__)
|
|
#define ClientNew(t) DoClientNewDbg<t>(__FILE__, __LINE__)
|
|
#define ContextNew(t,p) DoContextNewDbg<t>(p, __FILE__, __LINE__)
|
|
#else
|
|
#define ProcessNew(t) DoProcessNew<t>()
|
|
#define ClientNew(t) DoClientNew<t>()
|
|
#define ContextNew(t,p) DoContextNew<t>(p)
|
|
#endif
|
|
#define ProcessDelete(t,p) DoProcessDelete<t>(p)
|
|
#define ClientDelete(t,p) DoClientDelete<t>(p)
|
|
#define ContextDelete(t,h,p) DoContextDelete<t>(p)
|
|
|
|
|
|
|
|
//
|
|
// To allocate memory on the stack that is aligned on an 8-byte boundary
|
|
// we need to allocate an extra 4 bytes. All stack allocations are on
|
|
// 4 byte boundaries.
|
|
//
|
|
|
|
#define STACK_ALIGN8_ALLOC(cb) \
|
|
((void *) ((((UINT_PTR) _alloca(cb + 4)) + 7) & ~0x07))
|
|
|
|
#include "SimpleHeap.inl"
|
|
|
|
#endif // BASE__SimpleHeap_h__INCLUDED
|