3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: mkernel/kernel/work.c
6 * PURPOSE: Manage system work queues
7 * PROGRAMMER: David Welch (welch@mcmail.com)
12 /* INCLUDES ******************************************************************/
14 #include <ddk/ntddk.h>
16 #include <internal/ps.h>
19 #include <internal/debug.h>
21 /* DEFINES *******************************************************************/
23 #define NUMBER_OF_WORKER_THREADS (5)
25 /* TYPES *********************************************************************/
27 typedef struct _WORK_QUEUE
30 * PURPOSE: Head of the list of waiting work items
35 * PURPOSE: Sychronize access to the work queue
40 * PURPOSE: Worker threads with nothing to do wait on this event
45 * PURPOSE: Thread associated with work queue
47 HANDLE Thread[NUMBER_OF_WORKER_THREADS];
48 } WORK_QUEUE, *PWORK_QUEUE;
50 /* GLOBALS *******************************************************************/
53 * PURPOSE: Queue of items waiting to be processed at normal priority
55 WORK_QUEUE EiNormalWorkQueue;
57 WORK_QUEUE EiCriticalWorkQueue;
59 WORK_QUEUE EiHyperCriticalWorkQueue;
61 /* FUNCTIONS ****************************************************************/
63 static NTSTATUS STDCALL
64 ExWorkerThreadEntryPoint(PVOID context)
66 * FUNCTION: Entry point for a worker thread
68 * context = Parameters
70 * NOTE: To kill a worker thread you must queue an item whose callback
71 * calls PsTerminateSystemThread
74 PWORK_QUEUE queue = (PWORK_QUEUE)context;
75 PWORK_QUEUE_ITEM item;
80 current = ExInterlockedRemoveHeadList(&queue->Head,
84 item = CONTAINING_RECORD(current,WORK_QUEUE_ITEM,Entry);
85 item->Routine(item->Context);
89 KeWaitForSingleObject((PVOID)&queue->Sem,
94 DPRINT("Woke from wait\n");
99 static VOID ExInitializeWorkQueue(PWORK_QUEUE WorkQueue,
105 InitializeListHead(&WorkQueue->Head);
106 KeInitializeSpinLock(&WorkQueue->Lock);
107 KeInitializeSemaphore(&WorkQueue->Sem,
110 for (i=0; i<NUMBER_OF_WORKER_THREADS; i++)
112 PsCreateSystemThread(&WorkQueue->Thread[i],
117 ExWorkerThreadEntryPoint,
119 ObReferenceObjectByHandle(WorkQueue->Thread[i],
125 KeSetPriorityThread(&Thread->Tcb,
127 ObDereferenceObject(Thread);
131 VOID ExInitializeWorkerThreads(VOID)
133 ExInitializeWorkQueue(&EiNormalWorkQueue,
135 ExInitializeWorkQueue(&EiCriticalWorkQueue,
136 LOW_REALTIME_PRIORITY);
137 ExInitializeWorkQueue(&EiHyperCriticalWorkQueue,
142 ExQueueWorkItem (PWORK_QUEUE_ITEM WorkItem,
143 WORK_QUEUE_TYPE QueueType)
145 * FUNCTION: Inserts a work item in a queue for one of the system worker
148 * WorkItem = Item to insert
149 * QueueType = Queue to insert it in
152 assert(WorkItem!=NULL);
153 ASSERT_IRQL(DISPATCH_LEVEL);
156 * Insert the item in the appropiate queue and wake up any thread
157 * waiting for something to do
161 case DelayedWorkQueue:
162 ExInterlockedInsertTailList(&EiNormalWorkQueue.Head,
164 &EiNormalWorkQueue.Lock);
165 KeReleaseSemaphore(&EiNormalWorkQueue.Sem,
171 case CriticalWorkQueue:
172 ExInterlockedInsertTailList(&EiCriticalWorkQueue.Head,
174 &EiCriticalWorkQueue.Lock);
175 KeReleaseSemaphore(&EiCriticalWorkQueue.Sem,
181 case HyperCriticalWorkQueue:
182 ExInterlockedInsertTailList(&EiHyperCriticalWorkQueue.Head,
184 &EiHyperCriticalWorkQueue.Lock);
185 KeReleaseSemaphore(&EiHyperCriticalWorkQueue.Sem,