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.

242 lines
7.0 KiB

  1. /*++
  2. Copyright (c) 1998-2002 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. //
  14. // Pointer to a thread pool worker function.
  15. //
  16. typedef union _UL_WORK_ITEM *PUL_WORK_ITEM;
  17. typedef
  18. VOID
  19. (*PUL_WORK_ROUTINE)(
  20. IN PUL_WORK_ITEM pWorkItem
  21. );
  22. //
  23. // A work item. A work item may only appear on the work queue once.
  24. //
  25. typedef union _UL_WORK_ITEM
  26. {
  27. DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) ULONGLONG Alignment;
  28. struct
  29. {
  30. SLIST_ENTRY QueueListEntry; // Next pointer
  31. PUL_WORK_ROUTINE pWorkRoutine; // Callback routine
  32. };
  33. } UL_WORK_ITEM, *PUL_WORK_ITEM;
  34. //
  35. // We have to be sure that the DriverContext (PVOID [4]) in the IRP is
  36. // big enough to hold both the process pointer and a UL_WORK_ITEM.
  37. //
  38. C_ASSERT(FIELD_OFFSET(UL_WORK_ITEM, pWorkRoutine)
  39. <= (4 - 2) * sizeof(PVOID));
  40. //
  41. // Public functions.
  42. //
  43. NTSTATUS
  44. UlInitializeThreadPool(
  45. IN USHORT ThreadsPerCpu
  46. );
  47. VOID
  48. UlTerminateThreadPool(
  49. VOID
  50. );
  51. //
  52. // One-time initialization of a UL_WORK_ITEM. Note that UlpThreadPoolWorker
  53. // will reinitialize the workitem just before calling pWorkRoutine(), so
  54. // this only needs to be done when the UL_WORK_ITEM (or enclosing struct)
  55. // is first created. We need this so that we can check that a workitem is
  56. // not being queued when it is already on the queue---a catastrophic error.
  57. //
  58. #if DBG
  59. // Use non-zero values to ensure that item is properly initialized
  60. // and not just zero by coincidence
  61. # define WORK_ITEM_INIT_LIST_ENTRY ((PSLIST_ENTRY) 0xda7a)
  62. # define WORK_ITEM_INIT_ROUTINE ((PUL_WORK_ROUTINE) 0xc0de)
  63. #else
  64. // Use zero for efficiency
  65. # define WORK_ITEM_INIT_LIST_ENTRY NULL
  66. # define WORK_ITEM_INIT_ROUTINE NULL
  67. #endif
  68. __inline
  69. VOID
  70. UlInitializeWorkItem(
  71. IN PUL_WORK_ITEM pWorkItem)
  72. {
  73. pWorkItem->QueueListEntry.Next = WORK_ITEM_INIT_LIST_ENTRY;
  74. pWorkItem->pWorkRoutine = WORK_ITEM_INIT_ROUTINE;
  75. }
  76. __inline
  77. BOOLEAN
  78. UlIsInitializedWorkItem(
  79. IN PUL_WORK_ITEM pWorkItem)
  80. {
  81. return (BOOLEAN)(WORK_ITEM_INIT_LIST_ENTRY == pWorkItem->QueueListEntry.Next
  82. && WORK_ITEM_INIT_ROUTINE == pWorkItem->pWorkRoutine);
  83. }
  84. VOID
  85. UlQueueWorkItem(
  86. IN PUL_WORK_ITEM pWorkItem,
  87. IN PUL_WORK_ROUTINE pWorkRoutine,
  88. IN PCSTR pFileName,
  89. IN USHORT LineNumber
  90. );
  91. #define UL_QUEUE_WORK_ITEM( pWorkItem, pWorkRoutine ) \
  92. UlQueueWorkItem( \
  93. pWorkItem, \
  94. pWorkRoutine, \
  95. __FILE__, (USHORT) __LINE__ \
  96. )
  97. //
  98. // Store a WORK_ITEM inside IRP::Tail.Overlay.DriverContext (array of 4 PVOIDs)
  99. // Ensure that it's correctly aligned for the platform
  100. //
  101. #ifdef _WIN64
  102. // DriverContext[1] is 16-byte aligned
  103. C_ASSERT(((1 * sizeof(PVOID) + FIELD_OFFSET(IRP, Tail.Overlay.DriverContext))
  104. & (MEMORY_ALLOCATION_ALIGNMENT - 1)
  105. ) == 0);
  106. #define UL_PROCESS_FROM_IRP( _irp ) \
  107. (*(PEPROCESS*)&((_irp)->Tail.Overlay.DriverContext[0]))
  108. #define UL_MDL_FROM_IRP( _irp ) \
  109. (*(PMDL*)&((_irp)->Tail.Overlay.DriverContext[0]))
  110. #define UL_WORK_ITEM_FROM_IRP( _irp ) \
  111. (PUL_WORK_ITEM)&((_irp)->Tail.Overlay.DriverContext[1])
  112. #define UL_WORK_ITEM_TO_IRP( _workItem ) \
  113. CONTAINING_RECORD( (_workItem), IRP, Tail.Overlay.DriverContext[1])
  114. #else // !_WIN64
  115. // DriverContext[0] is 8-byte aligned
  116. C_ASSERT(((0 * sizeof(PVOID) + FIELD_OFFSET(IRP, Tail.Overlay.DriverContext))
  117. & (MEMORY_ALLOCATION_ALIGNMENT - 1)
  118. ) == 0);
  119. #define UL_PROCESS_FROM_IRP( _irp ) \
  120. (*(PEPROCESS*)&((_irp)->Tail.Overlay.DriverContext[3]))
  121. #define UL_MDL_FROM_IRP( _irp ) \
  122. (*(PMDL*)&((_irp)->Tail.Overlay.DriverContext[3]))
  123. #define UL_WORK_ITEM_FROM_IRP( _irp ) \
  124. (PUL_WORK_ITEM)&((_irp)->Tail.Overlay.DriverContext[0])
  125. #define UL_WORK_ITEM_TO_IRP( _workItem ) \
  126. CONTAINING_RECORD( (_workItem), IRP, Tail.Overlay.DriverContext[0])
  127. #endif // !_WIN64
  128. VOID
  129. UlQueueSyncItem(
  130. IN PUL_WORK_ITEM pWorkItem,
  131. IN PUL_WORK_ROUTINE pWorkRoutine,
  132. IN PCSTR pFileName,
  133. IN USHORT LineNumber
  134. );
  135. #define UL_QUEUE_SYNC_ITEM( pWorkItem, pWorkRoutine ) \
  136. UlQueueSyncItem( \
  137. pWorkItem, \
  138. pWorkRoutine, \
  139. __FILE__, __LINE__ \
  140. )
  141. VOID
  142. UlQueueWaitItem(
  143. IN PUL_WORK_ITEM pWorkItem,
  144. IN PUL_WORK_ROUTINE pWorkRoutine,
  145. IN PCSTR pFileName,
  146. IN USHORT LineNumber
  147. );
  148. #define UL_QUEUE_WAIT_ITEM( pWorkItem, pWorkRoutine ) \
  149. UlQueueWaitItem( \
  150. pWorkItem, \
  151. pWorkRoutine, \
  152. __FILE__, __LINE__ \
  153. )
  154. VOID
  155. UlQueueHighPriorityItem(
  156. IN PUL_WORK_ITEM pWorkItem,
  157. IN PUL_WORK_ROUTINE pWorkRoutine,
  158. IN PCSTR pFileName,
  159. IN USHORT LineNumber
  160. );
  161. #define UL_QUEUE_HIGH_PRIORITY_ITEM( pWorkItem, pWorkRoutine ) \
  162. UlQueueHighPriorityItem( \
  163. pWorkItem, \
  164. pWorkRoutine, \
  165. __FILE__, __LINE__ \
  166. )
  167. VOID
  168. UlCallPassive(
  169. IN PUL_WORK_ITEM pWorkItem,
  170. IN PUL_WORK_ROUTINE pWorkRoutine,
  171. IN PCSTR pFileName,
  172. IN USHORT LineNumber
  173. );
  174. #define UL_CALL_PASSIVE( pWorkItem, pWorkRoutine ) \
  175. UlCallPassive( \
  176. pWorkItem, \
  177. pWorkRoutine, \
  178. __FILE__, __LINE__ \
  179. )
  180. PETHREAD
  181. UlQueryIrpThread(
  182. VOID
  183. );
  184. #endif // _THRDPOOL_H_