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.

272 lines
5.4 KiB

  1. /*++
  2. Copyright (c) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. thrdpool.h
  5. Abstract:
  6. This module contains public declarations for the thread pool package.
  7. Author:
  8. Keith Moore (keithmo) 10-Jun-1998
  9. Revision History:
  10. --*/
  11. #ifndef _THRDPOOL_H_
  12. #define _THRDPOOL_H_
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. //
  17. // Thread tracker object. One of these objects is created for each
  18. // thread in the pool. These are useful for (among other things)
  19. // debugging.
  20. //
  21. typedef struct _UL_THREAD_TRACKER
  22. {
  23. //
  24. // Links onto the per-thread-pool list.
  25. //
  26. LIST_ENTRY ThreadListEntry;
  27. //
  28. // The thread.
  29. //
  30. PETHREAD pThread;
  31. } UL_THREAD_TRACKER, *PUL_THREAD_TRACKER;
  32. //
  33. // The thread pool object.
  34. //
  35. typedef struct _UL_THREAD_POOL
  36. {
  37. //
  38. // List of worker items on this thread pool.
  39. //
  40. SLIST_HEADER WorkQueueSList;
  41. //
  42. // An event used to wakeup the thread from blocking state.
  43. //
  44. KEVENT WorkQueueEvent;
  45. //
  46. // List of threads.
  47. //
  48. LIST_ENTRY ThreadListHead;
  49. //
  50. // Pointer to the special thread designated as the IRP thread. The
  51. // IRP thread is the first pool thread created and the last one to
  52. // die. It is also the target for all asynchronous IRPs.
  53. //
  54. PETHREAD pIrpThread;
  55. //
  56. // A very infrequently used spinlock.
  57. //
  58. UL_SPIN_LOCK ThreadSpinLock;
  59. //
  60. // The thread handle returned from PsCreateSystemThread.
  61. //
  62. HANDLE ThreadHandle;
  63. //
  64. // The number of threads we created for this pool.
  65. //
  66. UCHAR ThreadCount;
  67. //
  68. // Flag used to indicate that this pool has been successfully
  69. // initialized.
  70. //
  71. BOOLEAN Initialized;
  72. //
  73. // Target CPU for this pool. The worker threads use this to set
  74. // their hard affinity.
  75. //
  76. UCHAR ThreadCpu;
  77. } UL_THREAD_POOL, *PUL_THREAD_POOL;
  78. //
  79. // Necessary to ensure our array of UL_THREAD_POOL structures is
  80. // cache aligned.
  81. //
  82. typedef union _UL_ALIGNED_THREAD_POOL
  83. {
  84. UL_THREAD_POOL ThreadPool;
  85. UCHAR CacheAlignment[(sizeof(UL_THREAD_POOL) + UL_CACHE_LINE - 1) & ~(UL_CACHE_LINE - 1)];
  86. } UL_ALIGNED_THREAD_POOL;
  87. //
  88. // Pointer to a thread pool worker function.
  89. //
  90. typedef union _UL_WORK_ITEM *PUL_WORK_ITEM;
  91. typedef
  92. VOID
  93. (*PUL_WORK_ROUTINE)(
  94. IN PUL_WORK_ITEM pWorkItem
  95. );
  96. //
  97. // A work item. A work item may only appear on the work queue once.
  98. //
  99. typedef union _UL_WORK_ITEM
  100. {
  101. DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) ULONGLONG Alignment;
  102. struct
  103. {
  104. SINGLE_LIST_ENTRY QueueListEntry;
  105. PUL_WORK_ROUTINE pWorkRoutine;
  106. };
  107. } UL_WORK_ITEM, *PUL_WORK_ITEM;
  108. //
  109. //
  110. // Macro to queue a preinitialized UL_WORK_ITEM.
  111. //
  112. __inline
  113. VOID
  114. FASTCALL
  115. QUEUE_UL_WORK_ITEM(
  116. PUL_THREAD_POOL pThreadPool,
  117. IN PUL_WORK_ITEM pWorkItem
  118. )
  119. {
  120. if (NULL == InterlockedPushEntrySList(
  121. &pThreadPool->WorkQueueSList,
  122. &pWorkItem->QueueListEntry
  123. ))
  124. {
  125. KeSetEvent(
  126. &pThreadPool->WorkQueueEvent,
  127. 0,
  128. FALSE
  129. );
  130. }
  131. }
  132. // Public functions.
  133. //
  134. NTSTATUS
  135. UlInitializeThreadPool(
  136. IN USHORT ThreadsPerCpu
  137. );
  138. VOID
  139. UlTerminateThreadPool(
  140. VOID
  141. );
  142. VOID
  143. UlQueueWorkItem(
  144. IN PUL_WORK_ITEM pWorkItem,
  145. IN PUL_WORK_ROUTINE pWorkRoutine
  146. REFERENCE_DEBUG_FORMAL_PARAMS
  147. );
  148. #define UL_QUEUE_WORK_ITEM( pWorkItem, pWorkRoutine ) \
  149. UlQueueWorkItem( \
  150. pWorkItem, \
  151. pWorkRoutine \
  152. REFERENCE_DEBUG_ACTUAL_PARAMS \
  153. )
  154. #ifdef _WIN64
  155. #define UL_WORK_ITEM_FROM_IRP( _irp ) \
  156. (PUL_WORK_ITEM)&((_irp)->Tail.Overlay.DriverContext[1])
  157. #define UL_WORK_ITEM_TO_IRP( _workItem ) \
  158. CONTAINING_RECORD( (_workItem), IRP, Tail.Overlay.DriverContext[1])
  159. #else
  160. #define UL_WORK_ITEM_FROM_IRP( _irp ) \
  161. (PUL_WORK_ITEM)&((_irp)->Tail.Overlay.DriverContext[0])
  162. #define UL_WORK_ITEM_TO_IRP( _workItem ) \
  163. CONTAINING_RECORD( (_workItem), IRP, Tail.Overlay.DriverContext[0])
  164. #endif
  165. VOID
  166. UlQueueBlockingItem(
  167. IN PUL_WORK_ITEM pWorkItem,
  168. IN PUL_WORK_ROUTINE pWorkRoutine
  169. REFERENCE_DEBUG_FORMAL_PARAMS
  170. );
  171. #define UL_QUEUE_BLOCKING_ITEM( pWorkItem, pWorkRoutine ) \
  172. UlQueueBlockingItem( \
  173. pWorkItem, \
  174. pWorkRoutine \
  175. REFERENCE_DEBUG_ACTUAL_PARAMS \
  176. )
  177. VOID
  178. UlCallPassive(
  179. IN PUL_WORK_ITEM pWorkItem,
  180. IN PUL_WORK_ROUTINE pWorkRoutine
  181. REFERENCE_DEBUG_FORMAL_PARAMS
  182. );
  183. #define UL_CALL_PASSIVE( pWorkItem, pWorkRoutine ) \
  184. UlCallPassive( \
  185. pWorkItem, \
  186. pWorkRoutine \
  187. REFERENCE_DEBUG_ACTUAL_PARAMS \
  188. )
  189. PETHREAD
  190. UlQueryIrpThread(
  191. VOID
  192. );
  193. #ifdef __cplusplus
  194. }; // extern "C"
  195. #endif
  196. #endif // _THRDPOOL_H_