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.

331 lines
8.0 KiB

  1. /*++ BUILD Version: 0001 // Increment this if a change has global effects
  2. Copyright (c) 1989-1995 Microsoft Corporation
  3. Module Name:
  4. pool.h
  5. Abstract:
  6. Private executive data structures and prototypes for pool management.
  7. There are a number of different pool types:
  8. 1. NonPaged.
  9. 2. Paged.
  10. 3. Session (always paged, but virtualized per TS session).
  11. Author:
  12. Lou Perazzoli (loup) 23-Feb-1989
  13. Landy Wang (landyw) 02-June-1997
  14. Revision History:
  15. --*/
  16. #ifndef _POOL_
  17. #define _POOL_
  18. #if !DBG
  19. #define NO_POOL_CHECKS 1
  20. #endif
  21. #define POOL_CACHE_SUPPORTED 0
  22. #define POOL_CACHE_ALIGN 0
  23. #define NUMBER_OF_POOLS 2
  24. #if defined(NT_UP)
  25. #define NUMBER_OF_PAGED_POOLS 2
  26. #else
  27. #define NUMBER_OF_PAGED_POOLS 4
  28. #endif
  29. #define BASE_POOL_TYPE_MASK 1
  30. #define MUST_SUCCEED_POOL_TYPE_MASK 2
  31. #define CACHE_ALIGNED_POOL_TYPE_MASK 4
  32. #define SESSION_POOL_MASK 32
  33. #define POOL_VERIFIER_MASK 64
  34. #define POOL_DRIVER_MASK 128 // Note this cannot encode into a header.
  35. //
  36. // WARNING: POOL_QUOTA_MASK is overloaded by POOL_QUOTA_FAIL_INSTEAD_OF_RAISE
  37. // which is exported from ex.h.
  38. //
  39. // WARNING: POOL_RAISE_IF_ALLOCATION_FAILURE is exported from ex.h with a
  40. // value of 16.
  41. //
  42. // These definitions are used to control the raising of an exception as the
  43. // result of quota and allocation failures.
  44. //
  45. #define POOL_QUOTA_MASK 8
  46. #define POOL_TYPE_MASK (3)
  47. //
  48. // Size of a pool page.
  49. //
  50. // This must be greater than or equal to the page size.
  51. //
  52. #define POOL_PAGE_SIZE PAGE_SIZE
  53. //
  54. // The page size must be a multiple of the smallest pool block size.
  55. //
  56. // Define the block size.
  57. //
  58. #if (PAGE_SIZE == 0x4000)
  59. #define POOL_BLOCK_SHIFT 5
  60. #elif (PAGE_SIZE == 0x2000)
  61. #define POOL_BLOCK_SHIFT 4
  62. #else
  63. #if defined (_WIN64)
  64. #define POOL_BLOCK_SHIFT 4
  65. #else
  66. #define POOL_BLOCK_SHIFT 3
  67. #endif
  68. #endif
  69. #define POOL_LIST_HEADS (POOL_PAGE_SIZE / (1 << POOL_BLOCK_SHIFT))
  70. #define PAGE_ALIGNED(p) (!(((ULONG_PTR)p) & (POOL_PAGE_SIZE - 1)))
  71. //
  72. // Define page end macro.
  73. //
  74. #define PAGE_END(Address) (((ULONG_PTR)(Address) & (PAGE_SIZE - 1)) == 0)
  75. //
  76. // Define pool descriptor structure.
  77. //
  78. typedef struct _POOL_DESCRIPTOR {
  79. POOL_TYPE PoolType;
  80. ULONG PoolIndex;
  81. ULONG RunningAllocs;
  82. ULONG RunningDeAllocs;
  83. ULONG TotalPages;
  84. ULONG TotalBigPages;
  85. ULONG Threshold;
  86. PVOID LockAddress;
  87. PVOID PendingFrees;
  88. LONG PendingFreeDepth;
  89. SIZE_T TotalBytes;
  90. SIZE_T Spare0;
  91. LIST_ENTRY ListHeads[POOL_LIST_HEADS];
  92. } POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
  93. //
  94. // Caveat Programmer:
  95. //
  96. // The pool header must be QWORD (8 byte) aligned in size. If it
  97. // is not, the pool allocation code will trash the allocated
  98. // buffer.
  99. //
  100. //
  101. //
  102. // The layout of the pool header is:
  103. //
  104. // 31 23 16 15 7 0
  105. // +----------------------------------------------------------+
  106. // | Current Size | PoolType+1 | Pool Index |Previous Size |
  107. // +----------------------------------------------------------+
  108. // | ProcessBilled (NULL if not allocated with quota) |
  109. // +----------------------------------------------------------+
  110. // | Zero or more longwords of pad such that the pool header |
  111. // | is on a cache line boundary and the pool body is also |
  112. // | on a cache line boundary. |
  113. // +----------------------------------------------------------+
  114. //
  115. // PoolBody:
  116. //
  117. // +----------------------------------------------------------+
  118. // | Used by allocator, or when free FLINK into sized list |
  119. // +----------------------------------------------------------+
  120. // | Used by allocator, or when free BLINK into sized list |
  121. // +----------------------------------------------------------+
  122. // ... rest of pool block...
  123. //
  124. //
  125. // N.B. The size fields of the pool header are expressed in units of the
  126. // smallest pool block size.
  127. //
  128. typedef struct _POOL_HEADER {
  129. union {
  130. struct {
  131. USHORT PreviousSize : 9;
  132. USHORT PoolIndex : 7;
  133. USHORT BlockSize : 9;
  134. USHORT PoolType : 7;
  135. };
  136. ULONG Ulong1; // used for InterlockedCompareExchange required by Alpha
  137. };
  138. #if defined (_WIN64)
  139. ULONG PoolTag;
  140. #endif
  141. union {
  142. #if defined (_WIN64)
  143. EPROCESS *ProcessBilled;
  144. #else
  145. ULONG PoolTag;
  146. #endif
  147. struct {
  148. USHORT AllocatorBackTraceIndex;
  149. USHORT PoolTagHash;
  150. };
  151. };
  152. } POOL_HEADER, *PPOOL_HEADER;
  153. //
  154. // Define size of pool block overhead.
  155. //
  156. #define POOL_OVERHEAD ((LONG)sizeof(POOL_HEADER))
  157. //
  158. // Define size of pool block overhead when the block is on a freelist.
  159. //
  160. #define POOL_FREE_BLOCK_OVERHEAD (POOL_OVERHEAD + sizeof (LIST_ENTRY))
  161. //
  162. // Define dummy type so computation of pointers is simplified.
  163. //
  164. typedef struct _POOL_BLOCK {
  165. UCHAR Fill[1 << POOL_BLOCK_SHIFT];
  166. } POOL_BLOCK, *PPOOL_BLOCK;
  167. //
  168. // Define size of smallest pool block.
  169. //
  170. #define POOL_SMALLEST_BLOCK (sizeof(POOL_BLOCK))
  171. //
  172. // Define pool tracking information.
  173. //
  174. #define POOL_BACKTRACEINDEX_PRESENT 0x8000
  175. #if POOL_CACHE_SUPPORTED
  176. #define POOL_BUDDY_MAX PoolBuddyMax
  177. #else
  178. #define POOL_BUDDY_MAX \
  179. (POOL_PAGE_SIZE - (POOL_OVERHEAD + POOL_SMALLEST_BLOCK ))
  180. #endif
  181. //
  182. // Pool support routines are not for general consumption.
  183. // These are only used by the memory manager.
  184. //
  185. VOID
  186. ExInitializePoolDescriptor (
  187. IN PPOOL_DESCRIPTOR PoolDescriptor,
  188. IN POOL_TYPE PoolType,
  189. IN ULONG PoolIndex,
  190. IN ULONG Threshold,
  191. IN PVOID PoolLock
  192. );
  193. VOID
  194. ExDrainPoolLookasideList (
  195. IN PPAGED_LOOKASIDE_LIST Lookaside
  196. );
  197. VOID
  198. ExDeferredFreePool (
  199. IN PPOOL_DESCRIPTOR PoolDesc
  200. );
  201. PVOID
  202. ExCreatePoolTagTable (
  203. IN ULONG NewProcessorNumber,
  204. IN UCHAR NodeNumber
  205. );
  206. VOID
  207. ExDeletePoolTagTable (
  208. IN ULONG NewProcessorNumber
  209. );
  210. #define EX_CHECK_POOL_FREES_FOR_ACTIVE_TIMERS 0x1
  211. #define EX_CHECK_POOL_FREES_FOR_ACTIVE_WORKERS 0x2
  212. #define EX_CHECK_POOL_FREES_FOR_ACTIVE_RESOURCES 0x4
  213. #define EX_KERNEL_VERIFIER_ENABLED 0x8
  214. #define EX_VERIFIER_DEADLOCK_DETECTION_ENABLED 0x10
  215. #define EX_SPECIAL_POOL_ENABLED 0x20
  216. #define EX_PRINT_POOL_FAILURES 0x40
  217. #define EX_STOP_ON_POOL_FAILURES 0x80
  218. #define EX_SEPARATE_HOT_PAGES_DURING_BOOT 0x100
  219. #define EX_DELAY_POOL_FREES 0x200
  220. VOID
  221. ExSetPoolFlags (
  222. IN ULONG PoolFlag
  223. );
  224. //++
  225. //SIZE_T
  226. //EX_REAL_POOL_USAGE (
  227. // IN SIZE_T SizeInBytes
  228. // );
  229. //
  230. // Routine Description:
  231. //
  232. // This routine determines the real pool cost of the supplied allocation.
  233. //
  234. // Arguments
  235. //
  236. // SizeInBytes - Supplies the allocation size in bytes.
  237. //
  238. // Return Value:
  239. //
  240. // TRUE if unused segment trimming should be initiated, FALSE if not.
  241. //
  242. //--
  243. #define EX_REAL_POOL_USAGE(SizeInBytes) \
  244. (((SizeInBytes) > POOL_BUDDY_MAX) ? \
  245. (ROUND_TO_PAGES(SizeInBytes)) : \
  246. (((SizeInBytes) + POOL_OVERHEAD + (POOL_SMALLEST_BLOCK - 1)) & ~(POOL_SMALLEST_BLOCK - 1)))
  247. typedef struct _POOL_TRACKER_TABLE {
  248. ULONG Key;
  249. ULONG NonPagedAllocs;
  250. ULONG NonPagedFrees;
  251. SIZE_T NonPagedBytes;
  252. ULONG PagedAllocs;
  253. ULONG PagedFrees;
  254. SIZE_T PagedBytes;
  255. } POOL_TRACKER_TABLE, *PPOOL_TRACKER_TABLE;
  256. //
  257. // N.B. The last entry of the pool tracker table is used for all overflow
  258. // table entries.
  259. //
  260. extern PPOOL_TRACKER_TABLE PoolTrackTable;
  261. typedef struct _POOL_TRACKER_BIG_PAGES {
  262. PVOID Va;
  263. ULONG Key;
  264. ULONG NumberOfPages;
  265. PVOID QuotaObject;
  266. } POOL_TRACKER_BIG_PAGES, *PPOOL_TRACKER_BIG_PAGES;
  267. #endif