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.

270 lines
9.1 KiB

  1. /***************************************************************************\
  2. *
  3. * File: SimpleHelp.h
  4. *
  5. * Description:
  6. * SimpleHeap.h defines the heap operations used throughout DirectUser. See
  7. * below for a description of the different heaps.
  8. *
  9. *
  10. * History:
  11. * 11/26/1999: JStall: Created
  12. *
  13. * Copyright (C) 2000 by Microsoft Corporation. All rights reserved.
  14. *
  15. \***************************************************************************/
  16. #if !defined(BASE__SimpleHeap_h__INCLUDED)
  17. #define BASE__SimpleHeap_h__INCLUDED
  18. #ifdef _X86_
  19. #define USE_ROCKALL 1 // Use RockAll Research heap
  20. #endif
  21. #define USE_DYNAMICTLS 1 // Use Dynamic TLS using TlsAlloc()
  22. /***************************************************************************\
  23. *****************************************************************************
  24. *
  25. * Common memory management
  26. *
  27. *****************************************************************************
  28. \***************************************************************************/
  29. //
  30. // DirectUser supports multiple heaps used in different situations:
  31. // - Default: Heap shared by all threads within a common Context
  32. // - Context: Explicit heap for a (potentially different) Context- used cross-Context
  33. // - Process: Shared heap available by all Context's within the process.
  34. //
  35. // NOTE: It is VERY important that the Alloc() and Free() calls are properly
  36. // matched so that the memory is properly freed from the correct heap. If this
  37. // is not done, the memory will not be freed and will result in memory leaks
  38. // or potential process faults.
  39. //
  40. #if DBG
  41. #define DBG_HEAP_PARAMS , const char * pszFileName, int idxLineNum
  42. #define DBG_HEAP_USE do { pszFileName; idxLineNum; } while (0);
  43. #else
  44. #define DBG_HEAP_PARAMS
  45. #define DBG_HEAP_USE
  46. #endif
  47. class DUserHeap
  48. {
  49. // Construction
  50. public:
  51. DUserHeap();
  52. virtual ~DUserHeap() { }
  53. enum EHeap
  54. {
  55. idProcessHeap = 0,
  56. idNtHeap = 1,
  57. #ifdef _DEBUG
  58. idCrtDbgHeap = 2,
  59. #endif
  60. #if USE_ROCKALL
  61. idRockAllHeap = 3,
  62. #endif
  63. };
  64. // Operations
  65. public:
  66. virtual void * Alloc(SIZE_T cbSize, bool fZero DBG_HEAP_PARAMS) PURE;
  67. virtual void * Realloc(void * pvMem, SIZE_T cbNewSize DBG_HEAP_PARAMS) PURE;
  68. virtual void MultiAlloc(int * pnActual, void * prgAlloc[], int cItems, SIZE_T cbSize DBG_HEAP_PARAMS) PURE;
  69. virtual void Free(void * pvMem) PURE;
  70. virtual void MultiFree(int cItems, void * prgAlloc[], SIZE_T cbSize) PURE;
  71. public:
  72. void Lock();
  73. BOOL Unlock();
  74. // Data:
  75. protected:
  76. long m_cRef;
  77. };
  78. HRESULT CreateProcessHeap();
  79. void DestroyProcessHeap();
  80. HRESULT CreateContextHeap(DUserHeap * pLinkHeap, BOOL fThreadSafe, DUserHeap::EHeap id, DUserHeap ** ppNewHeap);
  81. void DestroyContextHeap(DUserHeap * pHeapDestroy);
  82. void ForceSetContextHeap(DUserHeap * pHeapThread);
  83. extern DUserHeap * g_pheapProcess;
  84. extern DWORD g_tlsHeap;
  85. #define pProcessHeap g_pheapProcess
  86. #define pContextHeap (reinterpret_cast<DUserHeap *> (TlsGetValue(g_tlsHeap)))
  87. #if DBG
  88. #define ClientAlloc(a) pContextHeap->Alloc(a, true, __FILE__, __LINE__)
  89. #define ClientAlloc_(a,b) pContextHeap->Alloc(a, b, __FILE__, __LINE__)
  90. #define ClientFree(a) pContextHeap->Free(a)
  91. #define ClientRealloc(a,b) pContextHeap->Realloc(a, b, __FILE__, __LINE__)
  92. #define ClientMultiAlloc(a,b,c,d) pContextHeap->MultiAlloc(a, b, c, d, __FILE__, __LINE__)
  93. #define ClientMultiFree(a,b,c) pContextHeap->MultiFree(a,b,c)
  94. #define ContextAlloc(p, a) p->Alloc(a, true, __FILE__, __LINE__)
  95. #define ContextAlloc_(p, a, b) p->Alloc(a, b, __FILE__, __LINE__)
  96. #define ContextFree(p, a) p->Free(a)
  97. #define ContextRealloc(p, a, b) p->Realloc(a, b, __FILE__, __LINE__)
  98. #define ContextMultiAlloc(p,a,b,c,d) p->MultiAlloc(a, b, c, d, __FILE__, __LINE__)
  99. #define ContextMultiFree(p,a, b, c) p->MultiFree(a,b,c)
  100. #define ProcessAlloc(a) pProcessHeap->Alloc(a, true, __FILE__, __LINE__)
  101. #define ProcessAlloc_(a, b) pProcessHeap->Alloc(a, b, __FILE__, __LINE__)
  102. #define ProcessFree(a) pProcessHeap->Free(a)
  103. #define ProcessRealloc(a, b) pProcessHeap->Realloc(a, b, __FILE__, __LINE__)
  104. #define ProcessMultiAlloc(a,b,c,d) pProcessHeap->MultiAlloc(a, b, c, d, __FILE__, __LINE__)
  105. #define ProcessMultiFree(a, b, c) pProcessHeap->MultiFree(a,b,c)
  106. void DumpData(void * pMem, int nLength);
  107. #else // DBG
  108. #define ClientAlloc(a) pContextHeap->Alloc(a, true)
  109. #define ClientAlloc_(a,b) pContextHeap->Alloc(a, b)
  110. #define ClientFree(a) pContextHeap->Free(a)
  111. #define ClientRealloc(a,b) pContextHeap->Realloc(a, b)
  112. #define ClientMultiAlloc(a,b,c,d) pContextHeap->MultiAlloc(a, b, c, d)
  113. #define ClientMultiFree(a,b,c) pContextHeap->MultiFree(a,b,c)
  114. #define ContextAlloc(p, a) p->Alloc(a, true)
  115. #define ContextAlloc_(p, a, b) p->Alloc(a, b)
  116. #define ContextFree(p, a) p->Free(a)
  117. #define ContextRealloc(p, a, b) p->Realloc(a, b)
  118. #define ContextMultiAlloc(p,a,b,c,d) p->MultiAlloc(a, b, c, d)
  119. #define ContextMultiFree(p,a, b, c) p->MultiFree(a,b,c)
  120. #define ProcessAlloc(a) pProcessHeap->Alloc(a, true)
  121. #define ProcessAlloc_(a, b) pProcessHeap->Alloc(a, b)
  122. #define ProcessFree(a) pProcessHeap->Free(a)
  123. #define ProcessRealloc(a, b) pProcessHeap->Realloc(a, b)
  124. #define ProcessMultiAlloc(a,b,c,d) pProcessHeap->MultiAlloc(a, b, c, d)
  125. #define ProcessMultiFree(a, b, c) pProcessHeap->MultiFree(a,b,c)
  126. #endif // DBG
  127. /***************************************************************************\
  128. *****************************************************************************
  129. *
  130. * operator new overloading
  131. *
  132. *****************************************************************************
  133. \***************************************************************************/
  134. #ifndef _INC_NEW
  135. #include <new.h>
  136. #endif
  137. #if DBG
  138. //
  139. // Use this instead of the usual placement new syntax to avoid conflicts when
  140. // 'new' is re-defined to provide memory leak tracking (below)
  141. #define placement_new(pv, Class) PlacementNewImpl0<Class>(pv)
  142. #define placement_new1(pv, Class, p1) PlacementNewImpl1<Class>(pv, p1)
  143. #define placement_copynew(pv, Class, src) PlacementCopyNewImpl0<Class>(pv, src)
  144. #define placement_delete(pv, Class) (((Class *)(pv))->~Class())
  145. #ifdef new
  146. #undef new
  147. #endif
  148. template <class T>
  149. inline T *
  150. PlacementNewImpl0(void *pv)
  151. {
  152. return new(pv) T;
  153. };
  154. template <class T, class Param1>
  155. inline T *
  156. PlacementNewImpl1(void *pv, Param1 p1)
  157. {
  158. return new(pv) T(p1);
  159. };
  160. template <class T>
  161. inline T *
  162. PlacementCopyNewImpl0(void *pv, const T & t)
  163. {
  164. return new(pv) T(t);
  165. };
  166. #else // DBG
  167. #define DEBUG_NEW new
  168. #define placement_new(pv, Class) new(pv) Class
  169. #define placement_new1(pv, Class, p1) new(pv) Class(p1)
  170. #define placement_copynew(pv, Class, src) new(pv) Class(src)
  171. #define placement_delete(pv, Class) (((Class *)(pv))->~Class())
  172. #endif // DBG
  173. inline void * __cdecl operator new(size_t nSize)
  174. {
  175. void * pv = ClientAlloc(nSize);
  176. return pv;
  177. }
  178. inline void __cdecl operator delete(void * pvMem)
  179. {
  180. ClientFree(pvMem);
  181. }
  182. #if DBG
  183. template <class type> inline type * DoProcessNewDbg(const char * pszFileName, int idxLineNum);
  184. template <class type> inline type * DoClientNewDbg(const char * pszFileName, int idxLineNum);
  185. template <class type> inline type * DoContextNewDbg(DUserHeap * pHeap, const char * pszFileName, int idxLineNum);
  186. #else
  187. template <class type> inline type * DoProcessNew();
  188. template <class type> inline type * DoClientNew();
  189. template <class type> inline type * DoContextNew(DUserHeap * pHeap);
  190. #endif
  191. template <class type> inline void DoProcessDelete(type * pMem);
  192. template <class type> inline void DoClientDelete(type * pMem);
  193. template <class type> inline void DoContextDelete(DUserHeap * pHeap, type * pMem);
  194. #if DBG
  195. #define ProcessNew(t) DoProcessNewDbg<t>(__FILE__, __LINE__)
  196. #define ClientNew(t) DoClientNewDbg<t>(__FILE__, __LINE__)
  197. #define ContextNew(t,p) DoContextNewDbg<t>(p, __FILE__, __LINE__)
  198. #else
  199. #define ProcessNew(t) DoProcessNew<t>()
  200. #define ClientNew(t) DoClientNew<t>()
  201. #define ContextNew(t,p) DoContextNew<t>(p)
  202. #endif
  203. #define ProcessDelete(t,p) DoProcessDelete<t>(p)
  204. #define ClientDelete(t,p) DoClientDelete<t>(p)
  205. #define ContextDelete(t,h,p) DoContextDelete<t>(p)
  206. //
  207. // To allocate memory on the stack that is aligned on an 8-byte boundary
  208. // we need to allocate an extra 4 bytes. All stack allocations are on
  209. // 4 byte boundaries.
  210. //
  211. #define STACK_ALIGN8_ALLOC(cb) \
  212. ((void *) ((((UINT_PTR) _alloca(cb + 4)) + 7) & ~0x07))
  213. #include "SimpleHeap.inl"
  214. #endif // BASE__SimpleHeap_h__INCLUDED