Source code of Windows XP (NT5)
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.

439 lines
14 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /**********************************************************************/
  5. /*
  6. heap.hxx
  7. Expandable protected-mode heap classes: definition.
  8. These classes provide global "new" and "delete" operators which
  9. use the Windows LocalInit, et al., routines to manage
  10. as large a heap as is allocatable from GlobalAlloc.
  11. The class objects themselves are allocated from the local heap
  12. through LocalAlloc and LocalFree.
  13. FILE HISTORY:
  14. DavidHov 2-25-91 Created from CDD.
  15. Johnl 5-02-91 Added overloaded new prototype
  16. KeithMo 23-Oct-1991 Added forward references.
  17. beng 24-Dec-1991 Removed one-shot heaps to heapones.hxx
  18. */
  19. #if !defined(_HEAP_HXX_)
  20. // In-line "operator new" that takes a pointer (placement syntax).
  21. inline void * CDECL operator new ( size_t cb, void * p )
  22. {
  23. (void) cb;
  24. return p;
  25. }
  26. #define _HEAP_HXX_
  27. // Only really expand this file if !Win32
  28. #if !defined(WIN32)
  29. #include "base.hxx"
  30. #include "uiassert.hxx"
  31. #include "uibuffer.hxx"
  32. #ifndef _SIZE_T_DEFINED
  33. #include <stddef.h>
  34. #endif
  35. //
  36. // Forward references.
  37. //
  38. DLL_CLASS LOCAL_HEAP_OBJ;
  39. DLL_CLASS BASE_HEAP;
  40. DLL_CLASS SUB_HEAP;
  41. DLL_CLASS GIANT_HEAP;
  42. DLL_CLASS MEM_MASTER;
  43. /*************************************************************************
  44. NAME: LOCL_HEAP_OBJ
  45. SYNOPSIS: An abstract class used to derive objects which will
  46. be allocated on the local (DS-based) heap.
  47. INTERFACE: operator new() - new operator
  48. operator delete() - dleete operator
  49. QueryBlockSize() - return heap size
  50. PARENT: BASE
  51. NOTE:
  52. This class won't presently work from a DLL.
  53. HISTORY:
  54. DavidHov 2-25-91 Created
  55. **************************************************************************/
  56. DLL_CLASS LOCAL_HEAP_OBJ : public BASE
  57. {
  58. public:
  59. VOID * operator new ( size_t cb );
  60. VOID operator delete ( VOID * pbBlock );
  61. USHORT QueryBlockSize ( VOID * pbBlock );
  62. private:
  63. static long _cLocalFreeErrors;
  64. };
  65. /*************************************************************************
  66. NAME: BASE_HEAP
  67. SYNOPSIS: An abstract class used to derive heap objects.
  68. INTERFACE: BASE_HEAP() - constructor
  69. ~BASE_HEAP - destructor
  70. Alloc() - allocation
  71. Free() - Free.
  72. PARENT: LOCAL_HEAP_OBJ, BUFFER
  73. NOTE:
  74. This class won't presently work from a DLL.
  75. HISTORY:
  76. DavidHov 2-25-91 Created
  77. **************************************************************************/
  78. DLL_CLASS BASE_HEAP : public LOCAL_HEAP_OBJ,
  79. public BUFFER
  80. {
  81. public:
  82. USHORT QuerySel()
  83. { return HIWORD( QueryPtr() ); }
  84. BASE_HEAP(); // Allocates the smallest possible buffer
  85. BASE_HEAP( USHORT cbInitialAllocSize );
  86. ~BASE_HEAP();
  87. virtual BYTE * Alloc ( USHORT cbBytes, USHORT fsFlags = 0 ) = 0;
  88. virtual BOOL Free ( BYTE * pbBlock ) = 0;
  89. };
  90. /*************************************************************************
  91. NAME: SUB_HEAP
  92. SYNOPSIS: A single extension of a GIANT_HEAP, capable of allocating
  93. at most 64K of smaller items.
  94. INTERFACE: Indirect. Correct usage is only through MEM_MASTER and
  95. GIANT_HEAP.
  96. QueryOwner() - return the owner heap pointer.
  97. Alloc() - allocation
  98. Free() - free the memory
  99. CalcDeallocErrors() - return the count of deallocation errors
  100. PARENT: BASE_HEAP
  101. CAVEATS:
  102. This class and its subclasses, GIANT_HEAP and MEM_MASTER,
  103. use the SUB_HEAP operators "new" and "delete" to allocate
  104. their instances in the local heap through LocalAlloc
  105. and Local Free.
  106. NOTES:
  107. Again, usage is indirect. Intended use is only through
  108. the global replacement "new" and "delete" operators. In
  109. other words, if you link HEAPBIG.CXX into your program,
  110. you only have to call MEM_MASTER::Init or InitForDll.
  111. All SUB_HEAPs instances and the instances of its subclasses
  112. are linked onto a single circularly linked list maintained
  113. automatically by SUB_HEAP's constructors and destructors.
  114. This class won't presently work from a DLL.
  115. HISTORY:
  116. DavidHov 2-25-91 Created
  117. **************************************************************************/
  118. DLL_CLASS SUB_HEAP: public BASE_HEAP
  119. {
  120. friend class GIANT_HEAP;
  121. friend class MEM_MASTER;
  122. protected:
  123. SUB_HEAP * _pFwd, * _pBack;
  124. enum SHtype { SHt_Invalid, SHt_DS, SHt_Normal } _type;
  125. USHORT _cbLargestFailed; // Size of largest failed allocation
  126. USHORT _cBlksOut; // Count of blocks outstanding
  127. ULONG _lcDeallocErrors; // Deallocation errors
  128. inline USHORT QuerySel () // Return selector of buffer
  129. { return HIWORD( QueryPtr() ); }
  130. GIANT_HEAP * _pOwner; // Pointer to owning GIANT_HEAP
  131. // Can only be constructed by MEM_MASTER,
  132. // or as part of a GIANT_HEAP
  133. //
  134. SUB_HEAP(); // used by MEM_MASTER; SHt_DS
  135. SUB_HEAP( USHORT cbInitialAllocSize );
  136. // Normal constructor: SHt_Normal
  137. ~SUB_HEAP();
  138. VOID Init(); // Initialze private data
  139. VOID Link(); // Link onto circular list
  140. VOID Unlink(); // Remove from circular list
  141. USHORT QueryBlockSize( BYTE * pbBlock );
  142. // Return size of allocated block
  143. BOOL Walk () ; // Walk the heap-- Debugging.
  144. public:
  145. static MEM_MASTER * _pmmInstance; // Pointer to single instance
  146. // of MEM_MASTER
  147. // Returns pointer to owning GIANT_HEAP (which may be itself)
  148. // or NULL, implying that it's the DS heap (default GIANT_HEAP)
  149. virtual GIANT_HEAP * QueryOwner( );
  150. virtual BYTE * Alloc( USHORT cbBytes, USHORT fsFlags = 0 );
  151. virtual BOOL Free( BYTE * pbBlock );
  152. virtual ULONG CalcDeallocErrors();
  153. };
  154. /*************************************************************************
  155. NAME: GIANT_HEAP
  156. SYNOPSIS: Logically, a GIANT_HEAP is one or more SUB_HEAPs. Since
  157. there must be at least one SUB_HEAP, GIANT_HEAP inherits
  158. from SUB_HEAP. The distinction lies in the "_pOwner"
  159. variable, which points to itself for GIANT_HEAPs.
  160. INTERFACE: Normally indirect. Typical usage is only through
  161. MEM_MASTER, since most programs will only ever have one
  162. GIANT_HEAP. Additional GIANT_HEAPs can be allocated
  163. to create "boundaries" to distinguish large-scale areas
  164. of memory allocation. Reference MEM_MASTER's "focus"
  165. routines for more information.
  166. GIANT_HEAP() - constructor
  167. ~GIANT_HEAP() - destructor
  168. SetBehavior() - set allocation behavior
  169. SetDeleteOnEmpty() - set delete on empty
  170. SetExtendOnFull() - set extend on full
  171. SetResizeOnEmpty() - set resize on empty
  172. QueryExpandErrors() - number of failed expansion attempts
  173. Alloc() - allocation
  174. Free() - free
  175. CalcDeallocErrors() - number of deallocation errors
  176. QueryTotalBlocks() - total blocks
  177. PARENT: SUB_HEAP
  178. NOTES: Normal usage is indirect. Intended use is through
  179. the global replacement "new" and "delete" operators. In
  180. other words, if you link HEAPBIG.CXX into your program,
  181. you only have to call MEM_MASTER Init.
  182. See SUB_HEAP, NOTES.
  183. This class won't presently work from a DLL.
  184. CAVEATS: See SUB_HEAP, CAVEATS.
  185. HISTORY:
  186. DavidHov 2-25-91 Created
  187. **************************************************************************/
  188. #define GHbExtend (1<<0)
  189. #define GHbDelete (1<<1)
  190. #define GHbResize (1<<2)
  191. DLL_CLASS GIANT_HEAP : public SUB_HEAP
  192. {
  193. friend class MEM_MASTER;
  194. protected:
  195. // Default initial allocation for all subsequent SUB_HEAPs
  196. USHORT _cbInitAlloc;
  197. // Count number of times a new SUB_HEAP could not be created
  198. ULONG _cExpandErrors;
  199. // Allocation behavior control word
  200. USHORT _fsBehave;
  201. // Add a new SUB_HEAP and allocate from it.
  202. virtual BYTE * GrowAndAlloc( USHORT cbBytes, USHORT fsFlags = 0 );
  203. // parameterless initialization used by MEM_MASTER
  204. GIANT_HEAP();
  205. public:
  206. // Public constructor for additional GIANT_HEAPs
  207. GIANT_HEAP( USHORT cbInitialAllocation );
  208. ~GIANT_HEAP();
  209. BOOL SetBehavior( USHORT fFlag, BOOL fOnOff );
  210. BOOL SetDeleteOnEmpty ( BOOL fDelete )
  211. { return SetBehavior( GHbDelete, fDelete ); }
  212. BOOL SetExtendOnFull ( BOOL fExtend )
  213. { return SetBehavior( GHbExtend, fExtend ); }
  214. BOOL SetResizeOnEmpty ( BOOL fResize )
  215. { return SetBehavior( GHbResize, fResize ); }
  216. ULONG QueryExpandErrors()
  217. { return _cExpandErrors ; }
  218. // Return a pointer to the newest SUB_HEAP in the ensemble.
  219. SUB_HEAP * QueryLatest();
  220. virtual BYTE * Alloc( USHORT cbBytes, USHORT fsFlags = 0 );
  221. virtual BOOL Free( BYTE * pbBlock );
  222. virtual ULONG CalcDeallocErrors();
  223. virtual ULONG QueryTotalBlocks();
  224. };
  225. /*************************************************************************
  226. NAME: MEM_MASTER
  227. SYNOPSIS: MEM_MASTER serves primarily as the anchor for the linked
  228. list of SUB_HEAPS and the locus of the global "new"
  229. and "delete" operators. It also maintains a pointer to
  230. the current "focussed" GIANT_HEAP.
  231. As explained in HEAPBIG.CXX, before instantiation, the
  232. global "new" and "delete" operators simply use LocalAlloc
  233. and LocalFree. After instantiation of MEM_MASTER (via
  234. "Init"), MEM_MASTER is created as a GIANT_HEAP which
  235. covers the local, DS-relative heap. Instantiation also
  236. creates the first instance of a GIANT_HEAP, which implies
  237. that the first SUB_HEAP is also created.
  238. The effect is two-fold. First, a GIANT_HEAP is ready for
  239. use, and allocates memory obtained through GlobalAlloc.
  240. Second, the MEM_MASTER is still available as a GIANT_HEAP
  241. in case the uses wishes to temporarily allocate from the
  242. local heap.
  243. MEM_MASTER is the first instance both of a SUB_HEAP and a
  244. GIANT_HEAP. It can be distinguished from other HEAPs
  245. because:
  246. 1) it's a GIANT_HEAP, since _pOwner == this (self), and
  247. 2) this (self) == _pmmInstance, it's
  248. the one and only MEM_MASTER.
  249. INTERFACE: Call MEM_MASTER::Init(). This creates the sole, global
  250. instance of a MEM_MASTER, _pmmInstance. After
  251. Init(), all "new" and "delete" operations will automatically
  252. flow through _pmmInstance.
  253. Init() - initialize
  254. InitForDll() - initialize for DLL
  255. Term() - terminate
  256. Alloc() - allocate
  257. Free() - free
  258. QueryBlockSize() - size of the block
  259. SetFocus() - refocus on the subheap
  260. GetGiantFocus() - get giant focus
  261. QueryTotalHeaps() - Total heaps
  262. QueryTotalBlocks() - total blocks
  263. PARENT: GIANT_HEAP
  264. USES: SUB_HEAP
  265. CAVEATS:
  266. See SUB_HEAP, CAVEATS.
  267. Warning about InitForDll: Under Windows, memory allocated
  268. by a DLL is always "owned" by the active task which
  269. invoked the DLL. The InitForDll method is primarily
  270. intended for LANMAN.DRV, which is loaded by the Window's
  271. shell and not unloaded until Windows is terminated. Calling
  272. InitForDll preallocates several heaps and prevents
  273. further expansion. Thus, all the memory used will belong
  274. to the shell, which first loaded LANMAN.DRV. This technique
  275. WILL NOT WORK for normal DLL usage.
  276. NOTES:
  277. Normally, usage is indirect. Intended use is through
  278. the global replacement "new" and "delete" operators. In
  279. other words, if you link HEAPBIG.CXX into your program,
  280. you only have to call MEM_MASTER::Init.
  281. HISTORY:
  282. DavidHov 2-25-91 Created
  283. **************************************************************************/
  284. DLL_CLASS MEM_MASTER : public GIANT_HEAP
  285. {
  286. private:
  287. // This may point to a SUB_HEAP or a GIANT_HEAP
  288. SUB_HEAP * _pFocus;
  289. virtual BYTE * GrowAndAlloc( USHORT cbBytes, USHORT fsFlags = 0 );
  290. // De/constructor
  291. MEM_MASTER( USHORT cbInitAlloc );
  292. ~MEM_MASTER();
  293. public:
  294. static BOOL Init();
  295. static BOOL InitForDll ( INT cPreallocHeaps );
  296. static BOOL Term();
  297. // Primary methods used by global "new" and "delete".
  298. virtual BYTE * Alloc ( USHORT cbBytes, USHORT fsFlags = 0 );
  299. virtual BOOL Free ( BYTE * pbBlock );
  300. // Return the size of any previously allocated block.
  301. USHORT QueryBlockSize( BYTE * pbBlock );
  302. // Change the GIANT_HEAP in use.
  303. BOOL SetFocus( SUB_HEAP * pSubHeap );
  304. // Returns the focussed GIANT_HEAP or NULL
  305. GIANT_HEAP * GetGiantFocus();
  306. // Returns the focussed SUB_HEAP or NULL
  307. SUB_HEAP * GetSubFocus();
  308. USHORT QueryTotalHeaps();
  309. ULONG QueryTotalBlocks();
  310. // Check the health of the heap
  311. BOOL Walk () ;
  312. };
  313. #endif // !Win32
  314. #endif // _HEAP_HXX_