1 /* $Id: work.c,v 1.17 2003/07/17 16:57:38 silverblade Exp $
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
65 ExWorkerThreadEntryPoint(IN PVOID context
)
67 * FUNCTION: Entry point for a worker thread
69 * context = Parameters
71 * NOTE: To kill a worker thread you must queue an item whose callback
72 * calls PsTerminateSystemThread
75 PWORK_QUEUE queue
= (PWORK_QUEUE
)context
;
76 PWORK_QUEUE_ITEM item
;
81 current
= ExInterlockedRemoveHeadList(&queue
->Head
,
85 item
= CONTAINING_RECORD(current
,WORK_QUEUE_ITEM
,List
);
86 item
->WorkerRoutine(item
->Parameter
);
90 KeWaitForSingleObject((PVOID
)&queue
->Sem
,
95 DPRINT("Woke from wait\n");
100 static VOID
ExInitializeWorkQueue(PWORK_QUEUE WorkQueue
,
106 InitializeListHead(&WorkQueue
->Head
);
107 KeInitializeSpinLock(&WorkQueue
->Lock
);
108 KeInitializeSemaphore(&WorkQueue
->Sem
,
111 for (i
=0; i
<NUMBER_OF_WORKER_THREADS
; i
++)
113 PsCreateSystemThread(&WorkQueue
->Thread
[i
],
118 ExWorkerThreadEntryPoint
,
120 ObReferenceObjectByHandle(WorkQueue
->Thread
[i
],
126 KeSetPriorityThread(&Thread
->Tcb
,
128 ObDereferenceObject(Thread
);
132 VOID
ExInitializeWorkerThreads(VOID
)
134 ExInitializeWorkQueue(&EiNormalWorkQueue
,
136 ExInitializeWorkQueue(&EiCriticalWorkQueue
,
137 LOW_REALTIME_PRIORITY
);
138 ExInitializeWorkQueue(&EiHyperCriticalWorkQueue
,
146 ExQueueWorkItem (PWORK_QUEUE_ITEM WorkItem
,
147 WORK_QUEUE_TYPE QueueType
)
149 * FUNCTION: Inserts a work item in a queue for one of the system worker
152 * WorkItem = Item to insert
153 * QueueType = Queue to insert it in
156 assert(WorkItem
!=NULL
);
157 ASSERT_IRQL(DISPATCH_LEVEL
);
160 * Insert the item in the appropiate queue and wake up any thread
161 * waiting for something to do
165 case DelayedWorkQueue
:
166 ExInterlockedInsertTailList(&EiNormalWorkQueue
.Head
,
168 &EiNormalWorkQueue
.Lock
);
169 KeReleaseSemaphore(&EiNormalWorkQueue
.Sem
,
175 case CriticalWorkQueue
:
176 ExInterlockedInsertTailList(&EiCriticalWorkQueue
.Head
,
178 &EiCriticalWorkQueue
.Lock
);
179 KeReleaseSemaphore(&EiCriticalWorkQueue
.Sem
,
185 case HyperCriticalWorkQueue
:
186 ExInterlockedInsertTailList(&EiHyperCriticalWorkQueue
.Head
,
188 &EiHyperCriticalWorkQueue
.Lock
);
189 KeReleaseSemaphore(&EiHyperCriticalWorkQueue
.Sem
,
196 case MaximumWorkQueue
: