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.

336 lines
6.6 KiB

  1. /*++
  2. Copyright (c) 1998-2002 Microsoft Corporation
  3. Module Name:
  4. thrdpoolp.h
  5. Abstract:
  6. This module contains private declarations for the thread pool package.
  7. Author:
  8. Keith Moore (KeithMo) 10-Jun-1998
  9. Revision History:
  10. Chun Ye (ChunYe) Spring 2001
  11. George V. Reilly (GeorgeRe) Summer 2001
  12. --*/
  13. #ifndef _THRDPOOLP_H_
  14. #define _THRDPOOLP_H_
  15. //
  16. // CODEWORK: Build a new kind of tracelog for threadpool. Reftrace is
  17. // inadequate.
  18. //
  19. // Special threads
  20. enum {
  21. WaitThreadPool,
  22. HighPriorityThreadPool,
  23. MaxThreadPools // must be last
  24. };
  25. //
  26. // Various states that a thread pool worker thread can be in
  27. //
  28. typedef enum {
  29. ThreadPoolCreated = 1,
  30. ThreadPoolInit,
  31. ThreadPoolFlush,
  32. ThreadPoolSearchOther,
  33. ThreadPoolBlock,
  34. ThreadPoolReverseList,
  35. ThreadPoolExecute,
  36. ThreadPoolException,
  37. ThreadPoolTerminated,
  38. } UL_THREAD_POOL_STATE;
  39. typedef struct _UL_THREAD_POOL *PUL_THREAD_POOL;
  40. //
  41. // Thread tracker object. One of these objects is created for each
  42. // thread in the pool. These are useful for (among other things)
  43. // debugging.
  44. //
  45. typedef struct _UL_THREAD_TRACKER
  46. {
  47. //
  48. // Links onto the per-thread-pool list.
  49. //
  50. LIST_ENTRY ThreadListEntry;
  51. //
  52. // Back pointer to owning threadpool
  53. //
  54. PUL_THREAD_POOL pThreadPool;
  55. //
  56. // The thread.
  57. //
  58. PETHREAD pThread;
  59. //
  60. // The thread handle returned from PsCreateSystemThread.
  61. //
  62. HANDLE ThreadHandle;
  63. //
  64. // List of worker items currently being processed in inner loop
  65. // and length of that list
  66. //
  67. SLIST_ENTRY CurrentListHead;
  68. ULONG ListLength;
  69. //
  70. // Current state of the thread
  71. //
  72. UL_THREAD_POOL_STATE State;
  73. //
  74. // Current workitem and current workroutine
  75. //
  76. PUL_WORK_ROUTINE pWorkRoutine;
  77. PUL_WORK_ITEM pWorkItem;
  78. //
  79. // Statistics
  80. // Average queue length (at time of flush) = SumQueueLength / QueueFlushes
  81. //
  82. ULONGLONG Executions;
  83. ULONGLONG SumQueueLengths;
  84. ULONG QueueFlushes;
  85. ULONG MaxQueueLength;
  86. } UL_THREAD_TRACKER, *PUL_THREAD_TRACKER;
  87. //
  88. // The thread pool object.
  89. //
  90. typedef struct _UL_THREAD_POOL
  91. {
  92. //
  93. // List of unprocessed worker items on this thread pool.
  94. //
  95. SLIST_HEADER WorkQueueSList;
  96. //
  97. // An event used to wakeup the thread from blocking state.
  98. //
  99. KEVENT WorkQueueEvent;
  100. //
  101. // List of threads.
  102. //
  103. LIST_ENTRY ThreadListHead;
  104. //
  105. // Pointer to the special thread designated as the IRP thread. The
  106. // IRP thread is the first pool thread created and the last one to
  107. // die. It is also the target for all asynchronous IRPs.
  108. //
  109. PETHREAD pIrpThread;
  110. //
  111. // A very infrequently used spinlock.
  112. //
  113. UL_SPIN_LOCK ThreadSpinLock;
  114. //
  115. // The number of threads we created for this pool.
  116. //
  117. UCHAR ThreadCount;
  118. //
  119. // Flag used to indicate that this pool has been successfully
  120. // initialized.
  121. //
  122. BOOLEAN Initialized;
  123. //
  124. // Target CPU for this pool. The worker threads use this to set
  125. // their hard affinity.
  126. //
  127. UCHAR ThreadCpu;
  128. //
  129. // Regular worker threads can pull workitems from
  130. // other regular queues on other processors.
  131. //
  132. BOOLEAN LookOnOtherQueues;
  133. } UL_THREAD_POOL, *PUL_THREAD_POOL;
  134. //
  135. // Necessary to ensure our array of UL_THREAD_POOL structures is
  136. // cache aligned.
  137. //
  138. typedef union _UL_ALIGNED_THREAD_POOL
  139. {
  140. UL_THREAD_POOL ThreadPool;
  141. UCHAR CacheAlignment[(sizeof(UL_THREAD_POOL) + UL_CACHE_LINE - 1)
  142. & ~(UL_CACHE_LINE - 1)];
  143. } UL_ALIGNED_THREAD_POOL;
  144. //
  145. // Inline function to validate that a UL_WORK_ITEM has been properly
  146. // initialized. Bugcheck if it's not.
  147. //
  148. __inline
  149. VOID
  150. UlpValidateWorkItem(
  151. IN PUL_WORK_ITEM pWorkItem,
  152. IN PCSTR pFileName,
  153. IN USHORT LineNumber
  154. )
  155. {
  156. if (! UlIsInitializedWorkItem(pWorkItem))
  157. {
  158. ASSERT(! "Uninitialized workitem");
  159. //
  160. // If the workitem was not properly zeroed, then chances are that
  161. // it's already on a work queue. If we were to requeue the work item,
  162. // it would corrupt the work queue. Better to fail hard now, while
  163. // there's some hope of figuring out what went wrong, than let it
  164. // crash mysteriously later.
  165. //
  166. UlBugCheckEx(
  167. HTTP_SYS_BUGCHECK_WORKITEM,
  168. (ULONG_PTR) pWorkItem,
  169. (ULONG_PTR) pFileName,
  170. (ULONG_PTR) LineNumber
  171. );
  172. }
  173. } // UlpValidateWorkItem
  174. //
  175. // Inline function to queue a preinitialized UL_WORK_ITEM.
  176. //
  177. __inline
  178. VOID
  179. QUEUE_UL_WORK_ITEM(
  180. PUL_THREAD_POOL pThreadPool,
  181. IN PUL_WORK_ITEM pWorkItem
  182. )
  183. {
  184. if (NULL == InterlockedPushEntrySList(
  185. &pThreadPool->WorkQueueSList,
  186. &pWorkItem->QueueListEntry
  187. ))
  188. {
  189. //
  190. // If the work queue was empty when we added this item,
  191. // set the event to wake the thread up
  192. //
  193. KeSetEvent(
  194. &pThreadPool->WorkQueueEvent,
  195. 0,
  196. FALSE
  197. );
  198. }
  199. }
  200. //
  201. // Private prototypes.
  202. //
  203. NTSTATUS
  204. UlpCreatePoolThread(
  205. IN PUL_THREAD_POOL pThreadPool
  206. );
  207. VOID
  208. UlpThreadPoolWorker(
  209. IN PVOID Context
  210. );
  211. VOID
  212. UlpInitThreadTracker(
  213. IN PUL_THREAD_POOL pThreadPool,
  214. IN PETHREAD pThread,
  215. IN PUL_THREAD_TRACKER pThreadTracker
  216. );
  217. VOID
  218. UlpDestroyThreadTracker(
  219. IN PUL_THREAD_TRACKER pThreadTracker
  220. );
  221. PUL_THREAD_TRACKER
  222. UlpPopThreadTracker(
  223. IN PUL_THREAD_POOL pThreadPool
  224. );
  225. VOID
  226. UlpKillThreadWorker(
  227. IN PUL_WORK_ITEM pWorkItem
  228. );
  229. //
  230. // Private globals.
  231. //
  232. extern DECLSPEC_ALIGN(UL_CACHE_LINE)
  233. UL_ALIGNED_THREAD_POOL g_UlThreadPool[];
  234. #define CURRENT_THREAD_POOL() \
  235. &g_UlThreadPool[KeGetCurrentProcessorNumber()].ThreadPool
  236. #define CURRENT_SYNC_THREAD_POOL() \
  237. &g_UlThreadPool[g_UlNumberOfProcessors + KeGetCurrentProcessorNumber()].ThreadPool
  238. #define WAIT_THREAD_POOL() \
  239. &g_UlThreadPool[(g_UlNumberOfProcessors * 2) + WaitThreadPool].ThreadPool
  240. #define HIGH_PRIORITY_THREAD_POOL() \
  241. &g_UlThreadPool[(g_UlNumberOfProcessors * 2) + HighPriorityThreadPool].ThreadPool
  242. extern PUL_WORK_ITEM g_pKillerWorkItems;
  243. #endif // _THRDPOOLP_H_