2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: mkernel/kernel/work.c
5 * PURPOSE: Manage system work queues
6 * PROGRAMMER: David Welch (welch@mcmail.com)
11 /* INCLUDES ******************************************************************/
13 #include <ddk/ntddk.h>
15 #include <internal/ps.h>
17 #include <internal/debug.h>
19 /* DEFINES *******************************************************************/
21 #define NUMBER_OF_WORKER_THREADS (5)
23 /* TYPES *********************************************************************/
25 typedef struct _WORK_QUEUE
28 * PURPOSE: Head of the list of waiting work items
33 * PURPOSE: Sychronize access to the access
38 * PURPOSE: Worker threads with nothing to do wait on this event
43 * PURPOSE: Thread associated with work queue
45 HANDLE Thread
[NUMBER_OF_WORKER_THREADS
];
46 } WORK_QUEUE
, *PWORK_QUEUE
;
48 /* GLOBALS *******************************************************************/
51 * PURPOSE: Queue of items waiting to be processed at normal priority
53 WORK_QUEUE EiNormalWorkQueue
;
55 WORK_QUEUE EiCriticalWorkQueue
;
57 WORK_QUEUE EiHyperCriticalWorkQueue
;
59 /* FUNCTIONS ****************************************************************/
61 static NTSTATUS
ExWorkerThreadEntryPoint(PVOID context
)
63 * FUNCTION: Entry point for a worker thread
65 * context = Parameters
67 * NOTE: To kill a worker thread you must queue an item whose callback
68 * calls PsTerminateSystemThread
71 PWORK_QUEUE queue
= (PWORK_QUEUE
)context
;
72 PWORK_QUEUE_ITEM item
;
77 current
= ExInterlockedRemoveHeadList(&queue
->Head
,
81 item
= CONTAINING_RECORD(current
,WORK_QUEUE_ITEM
,Entry
);
82 item
->Routine(item
->Context
);
86 KeWaitForSingleObject((PVOID
)&queue
->Sem
,
95 static VOID
ExInitializeWorkQueue(PWORK_QUEUE WorkQueue
,
101 InitializeListHead(&WorkQueue
->Head
);
102 KeInitializeSpinLock(&WorkQueue
->Lock
);
103 KeInitializeSemaphore(&WorkQueue
->Sem
,
106 for (i
=0; i
<NUMBER_OF_WORKER_THREADS
; i
++)
108 PsCreateSystemThread(&WorkQueue
->Thread
[i
],
113 ExWorkerThreadEntryPoint
,
115 ObReferenceObjectByHandle(WorkQueue
->Thread
[i
],
121 KeSetPriorityThread(&Thread
->Tcb
,
123 ObDereferenceObject(Thread
);
127 VOID
ExInitializeWorkerThreads(VOID
)
129 ExInitializeWorkQueue(&EiNormalWorkQueue
,
131 ExInitializeWorkQueue(&EiCriticalWorkQueue
,
132 LOW_REALTIME_PRIORITY
);
133 ExInitializeWorkQueue(&EiHyperCriticalWorkQueue
,
137 VOID
ExInitializeWorkItem(PWORK_QUEUE_ITEM Item
,
138 PWORKER_THREAD_ROUTINE Routine
,
141 * FUNCTION: Initializes a work item to be processed by one of the system
144 * Item = Pointer to the item to be initialized
145 * Routine = Routine to be called by the worker thread
146 * Context = Parameter to be passed to the callback
149 ASSERT_IRQL(DISPATCH_LEVEL
);
151 Item
->Routine
= Routine
;
152 Item
->Context
= Context
;
153 Item
->Entry
.Flink
= NULL
;
154 Item
->Entry
.Blink
= NULL
;
157 VOID
ExQueueWorkItem(PWORK_QUEUE_ITEM WorkItem
,
158 WORK_QUEUE_TYPE QueueType
)
160 * FUNCTION: Inserts a work item in a queue for one of the system worker
163 * WorkItem = Item to insert
164 * QueueType = Queue to insert it in
167 assert(WorkItem
!=NULL
);
168 ASSERT_IRQL(DISPATCH_LEVEL
);
171 * Insert the item in the appropiate queue and wake up any thread
172 * waiting for something to do
176 case DelayedWorkQueue
:
177 ExInterlockedInsertTailList(&EiNormalWorkQueue
.Head
,
179 &EiNormalWorkQueue
.Lock
);
180 KeReleaseSemaphore(&EiNormalWorkQueue
.Sem
,
186 case CriticalWorkQueue
:
187 ExInterlockedInsertTailList(&EiCriticalWorkQueue
.Head
,
189 &EiCriticalWorkQueue
.Lock
);
190 KeReleaseSemaphore(&EiCriticalWorkQueue
.Sem
,
196 case HyperCriticalWorkQueue
:
197 ExInterlockedInsertTailList(&EiHyperCriticalWorkQueue
.Head
,
199 &EiHyperCriticalWorkQueue
.Lock
);
200 KeReleaseSemaphore(&EiHyperCriticalWorkQueue
.Sem
,