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.

364 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. inc\ppool.h
  5. Abstract:
  6. Structures and #defines for managing NDIS_BUFFER pools. This is
  7. merely a reformatted version of SteveC's l2tp\bpool.h
  8. Revision History:
  9. --*/
  10. #ifndef __BPOOL_H__
  11. #define __BPOOL_H__
  12. //-----------------------------------------------------------------------------
  13. // Data structures
  14. //-----------------------------------------------------------------------------
  15. //
  16. // Buffer pool control block. A buffer pool prevents fragmentation of the
  17. // non-paged memory pool by allocating the memory for a group of buffers in a
  18. // single contiguous block. At user's option, the buffer pool routines may
  19. // allocate a pool of NDIS_BUFFER buffer descriptors and associate each with
  20. // the memory buffers sliced from the contiguous block. This allows the
  21. // buffer to be reused while the virtual->physical memory mapping is performed
  22. // only once. All necessary pool growth and shrinkage is handled internally.
  23. //
  24. typedef struct _BUFFER_POOL
  25. {
  26. //
  27. // Size in bytes of an individual buffer in the pool.
  28. //
  29. ULONG ulBufferSize;
  30. //
  31. // The optimal number of buffers to allocate in each buffer block.
  32. //
  33. ULONG ulBuffersPerBlock;
  34. //
  35. // Maximum number of individual buffers that may be allocated in the
  36. // entire pool or 0 for unlimited.
  37. //
  38. ULONG ulMaxBuffers;
  39. //
  40. // Current number of individual buffers allocated in the entire pool.
  41. //
  42. ULONG ulCurBuffers;
  43. //
  44. // Garbage collection occurs after this many calls to FreeBufferToPool.
  45. //
  46. ULONG ulFreesPerCollection;
  47. //
  48. // Number of calls to FreeBufferToPool since a garbage collection.
  49. //
  50. ULONG ulFreesSinceCollection;
  51. //
  52. // Indicates an NDIS_BUFFER is to be associated with each individual
  53. // buffer in the pool.
  54. //
  55. BOOLEAN fAssociateNdisBuffer;
  56. //
  57. // True if we allocate a whole page of memory
  58. //
  59. BOOLEAN fAllocatePage;
  60. //
  61. // Memory identification tag for allocated blocks.
  62. //
  63. ULONG ulTag;
  64. //
  65. // Head of the double linked list of BUFFER_BLOCKs. Access to the list
  66. // is protected with 'lock' in this structure.
  67. //
  68. LIST_ENTRY leBlockHead;
  69. //
  70. // Head of the double linked list of free BUFFER_HEADs. Each BUFFER_HEAD
  71. // in the list is ready to go, i.e. it preceeds it's already allocated
  72. // memory buffer and, if appropriate, has an NDIS_BUFFER associated with
  73. // it.
  74. // Access to the list is protected by 'lock' in this structure.
  75. // Interlocked push/pop is not used because (a) the list of blocks and the
  76. // list of buffers must lock each other and (b) double links are necessary
  77. // for garbage collection.
  78. //
  79. LIST_ENTRY leFreeBufferHead;
  80. //
  81. // This lock protects this structure and both the list of blocks and the
  82. // list of buffers.
  83. //
  84. RT_LOCK rlLock;
  85. }BUFFER_POOL, *PBUFFER_POOL;
  86. //
  87. // Header of a single block of buffers from a buffer pool. The BUFFER_HEAD of
  88. // the first buffer immediately follows.
  89. //
  90. typedef struct _BUFFER_BLOCK
  91. {
  92. //
  93. // Link to the prev/next buffer block header in the buffer pool's list.
  94. //
  95. LIST_ENTRY leBlockLink;
  96. //
  97. // NDIS's handle of the pool of NDIS_BUFFER descriptors associated with
  98. // this block, or NULL if none. (Note: With the current NT implementation
  99. // of NDIS_BUFFER as MDL this is always NULL).
  100. //
  101. NDIS_HANDLE nhNdisPool;
  102. //
  103. // Back pointer to the buffer pool.
  104. //
  105. PBUFFER_POOL pPool;
  106. //
  107. // Number of individual buffers in this block on the free list.
  108. //
  109. ULONG ulFreeBuffers;
  110. }BUFFER_BLOCK, *PBUFFER_BLOCK;
  111. #define ALIGN8_BLOCK_SIZE (ALIGN_UP(sizeof(BUFFER_BLOCK), ULONGLONG))
  112. //
  113. // Header of an individual buffer. The buffer memory itself immediately
  114. // follows.
  115. //
  116. typedef struct _BUFFER_HEAD
  117. {
  118. //
  119. // Links to prev/next buffer header in the buffer pool's free list.
  120. //
  121. LIST_ENTRY leFreeBufferLink;
  122. #if LIST_DBG
  123. BOOLEAN bBusy;
  124. LIST_ENTRY leListLink;
  125. ULONG ulAllocFile;
  126. ULONG ulAllocLine;
  127. ULONG ulFreeFile;
  128. ULONG ulFreeLine;
  129. #endif
  130. //
  131. // Back link to owning buffer block header.
  132. //
  133. PBUFFER_BLOCK pBlock;
  134. //
  135. // NDIS buffer descriptor of this buffer. This is NULL unless the pool is
  136. // initialized with the 'fAssociateNdisBuffer' option.
  137. //
  138. PNDIS_BUFFER pNdisBuffer;
  139. }BUFFER_HEAD, *PBUFFER_HEAD;
  140. #define ALIGN8_HEAD_SIZE (ALIGN_UP(sizeof(BUFFER_HEAD), ULONGLONG))
  141. #if LIST_DBG
  142. #define NotOnList(p) \
  143. (((p)->leListLink.Flink == NULL) && ((p)->leListLink.Blink == NULL))
  144. #endif
  145. #define BUFFER_FROM_HEAD(p) (PBYTE)((ULONG_PTR)(p) + ALIGN8_HEAD_SIZE)
  146. #define HEAD_FROM_BUFFER(p) (PBUFFER_HEAD)((ULONG_PTR)(p) - ALIGN8_HEAD_SIZE)
  147. //-----------------------------------------------------------------------------
  148. // Interface prototypes and inline definitions
  149. //-----------------------------------------------------------------------------
  150. VOID
  151. InitBufferPool(
  152. OUT PBUFFER_POOL pPool,
  153. IN ULONG ulBufferSize,
  154. IN ULONG ulMaxBuffers,
  155. IN ULONG ulBuffersPerBlock,
  156. IN ULONG ulFreesPerCollection,
  157. IN BOOLEAN fAssociateNdisBuffer,
  158. IN ULONG ulTag
  159. );
  160. BOOLEAN
  161. FreeBufferPool(
  162. IN PBUFFER_POOL pPool
  163. );
  164. #if !LIST_DBG
  165. BOOLEAN
  166. GetBufferListFromPool(
  167. IN PBUFFER_POOL pPool,
  168. IN ULONG ulNumBuffersNeeded,
  169. OUT PLIST_ENTRY pleList
  170. );
  171. VOID
  172. FreeBufferListToPool(
  173. IN PBUFFER_POOL pPool,
  174. IN PLIST_ENTRY pleList
  175. );
  176. PBYTE
  177. GetBufferFromPool(
  178. IN PBUFFER_POOL pPool
  179. );
  180. VOID
  181. FreeBufferToPoolEx(
  182. IN PBUFFER_POOL pPool,
  183. IN PBYTE pbyBuffer,
  184. IN BOOLEAN fGarbageCollection
  185. );
  186. NTSTATUS
  187. GetBufferChainFromPool(
  188. IN PBUFFER_POOL pPool,
  189. IN OUT PNDIS_PACKET pnpPacket,
  190. IN ULONG ulBufferLength,
  191. OUT NDIS_BUFFER **ppnbFirstBuffer,
  192. OUT VOID **ppvFirstData
  193. );
  194. VOID
  195. FreeBufferChainToPool(
  196. IN PBUFFER_POOL pPool,
  197. IN PNDIS_PACKET pnpPacket
  198. );
  199. #else
  200. #define GetBufferListFromPool(a,b,c) GETLIST((a),(b),(c),__FILE_SIG__,__LINE__)
  201. BOOLEAN
  202. GETLIST(
  203. IN PBUFFER_POOL pPool,
  204. IN ULONG ulNumBuffersNeeded,
  205. OUT PLIST_ENTRY pleList,
  206. IN ULONG ulFileSig,
  207. IN ULONG ulLine
  208. );
  209. #define FreeBufferListToPool(a,b) FREELIST((a),(b),__FILE_SIG__,__LINE__)
  210. VOID
  211. FREELIST(
  212. IN PBUFFER_POOL pPool,
  213. IN PLIST_ENTRY pleList,
  214. IN ULONG ulFileSig,
  215. IN ULONG ulLine
  216. );
  217. #define GetBufferFromPool(a) GET((a),__FILE_SIG__,__LINE__)
  218. PBYTE
  219. GET(
  220. IN PBUFFER_POOL pPool,
  221. IN ULONG ulFileSig,
  222. IN ULONG ulLine
  223. );
  224. #define FreeBufferToPoolEx(a,b,c) FREE((a),(b),(c),__FILE_SIG__,__LINE__)
  225. VOID
  226. FREE(
  227. IN PBUFFER_POOL pPool,
  228. IN PBYTE pbyBuffer,
  229. IN BOOLEAN fGarbageCollection,
  230. IN ULONG ulFileSig,
  231. IN ULONG ulLine
  232. );
  233. #define GetBufferChainFromPool(a,b,c,d,e) GETCHAIN((a),(b),(c),(d),(e),__FILE_SIG__,__LINE__)
  234. NTSTATUS
  235. GETCHAIN(
  236. IN PBUFFER_POOL pPool,
  237. IN OUT PNDIS_PACKET pnpPacket,
  238. IN ULONG ulBufferLength,
  239. OUT NDIS_BUFFER **ppnbFirstBuffer,
  240. OUT VOID **ppvFirstData,
  241. IN ULONG ulFileSig,
  242. IN ULONG ulLine
  243. );
  244. #define FreeBufferChainToPool(a,b) FREECHAIN((a),(b),__FILE_SIG__,__LINE__)
  245. VOID
  246. FREECHAIN(
  247. IN PBUFFER_POOL pPool,
  248. IN PNDIS_PACKET pnpPacket,
  249. IN ULONG ulFileSig,
  250. IN ULONG ulLine
  251. );
  252. #endif
  253. #define FreeBufferToPool(p,b) FreeBufferToPoolEx((p),(b), TRUE)
  254. PNDIS_BUFFER
  255. GetNdisBufferFromBuffer(
  256. IN PBYTE pbyBuffer
  257. );
  258. ULONG
  259. BufferSizeFromBuffer(
  260. IN PBYTE pbyBuffer
  261. );
  262. PNDIS_BUFFER
  263. PoolHandleForNdisCopyBufferFromBuffer(
  264. IN PBYTE pbyBuffer
  265. );
  266. #endif // __BPOOL_H__