3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/work.c
6 * PURPOSE: Manage system work queues
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES ******************************************************************/
15 #include <internal/debug.h>
17 /* DEFINES *******************************************************************/
19 #define NUMBER_OF_WORKER_THREADS (5)
21 /* TYPES *********************************************************************/
23 /* GLOBALS *******************************************************************/
26 * PURPOSE: Queue of items waiting to be processed at normal priority
28 KQUEUE EiNormalWorkQueue
;
30 KQUEUE EiCriticalWorkQueue
;
32 KQUEUE EiHyperCriticalWorkQueue
;
34 /* FUNCTIONS ****************************************************************/
36 //static NTSTATUS STDCALL
38 ExWorkerThreadEntryPoint(IN PVOID context
)
40 * FUNCTION: Entry point for a worker thread
42 * context = Parameters
44 * NOTE: To kill a worker thread you must queue an item whose callback
45 * calls PsTerminateSystemThread
49 PWORK_QUEUE_ITEM item
;
54 current
= KeRemoveQueue( (PKQUEUE
)context
, KernelMode
, NULL
);
56 /* can't happend since we do a KernelMode wait (and we're a system thread) */
57 ASSERT((NTSTATUS
)current
!= STATUS_USER_APC
);
59 /* this should never happend either, since we wait with NULL timeout,
60 * but there's a slight possibility that STATUS_TIMEOUT is returned
61 * at queue rundown in NT (unlikely) -Gunnar
63 ASSERT((NTSTATUS
)current
!= STATUS_TIMEOUT
);
65 /* based on INVALID_WORK_QUEUE_ITEM bugcheck desc. */
66 if (current
->Flink
== NULL
|| current
->Blink
== NULL
)
68 KeBugCheck(INVALID_WORK_QUEUE_ITEM
);
71 /* "reinitialize" item (same as done in ExInitializeWorkItem) */
72 current
->Flink
= NULL
;
74 item
= CONTAINING_RECORD( current
, WORK_QUEUE_ITEM
, List
);
75 item
->WorkerRoutine(item
->Parameter
);
77 if (KeGetCurrentIrql() != PASSIVE_LEVEL
)
79 KeBugCheck(IRQL_NOT_LESS_OR_EQUAL
);
85 static VOID
ExInitializeWorkQueue(PKQUEUE WorkQueue
,
93 for (i
=0; i
<NUMBER_OF_WORKER_THREADS
; i
++)
96 PsCreateSystemThread(&hThread
,
101 ExWorkerThreadEntryPoint
,
103 ObReferenceObjectByHandle(hThread
,
109 KeSetPriorityThread(&Thread
->Tcb
,
111 ObDereferenceObject(Thread
);
117 ExInitializeWorkerThreads(VOID
)
119 KeInitializeQueue( &EiNormalWorkQueue
, NUMBER_OF_WORKER_THREADS
);
120 KeInitializeQueue( &EiCriticalWorkQueue
, NUMBER_OF_WORKER_THREADS
);
121 KeInitializeQueue( &EiHyperCriticalWorkQueue
, NUMBER_OF_WORKER_THREADS
);
123 ExInitializeWorkQueue(&EiNormalWorkQueue
,
125 ExInitializeWorkQueue(&EiCriticalWorkQueue
,
126 LOW_REALTIME_PRIORITY
);
127 ExInitializeWorkQueue(&EiHyperCriticalWorkQueue
,
135 ExQueueWorkItem (PWORK_QUEUE_ITEM WorkItem
,
136 WORK_QUEUE_TYPE QueueType
)
138 * FUNCTION: Inserts a work item in a queue for one of the system worker
141 * WorkItem = Item to insert
142 * QueueType = Queue to insert it in
145 ASSERT(WorkItem
!=NULL
);
146 ASSERT_IRQL(DISPATCH_LEVEL
);
147 ASSERT(WorkItem
->List
.Flink
== NULL
);
149 * Insert the item in the appropiate queue and wake up any thread
150 * waiting for something to do
154 case DelayedWorkQueue
:
161 case CriticalWorkQueue
:
163 &EiCriticalWorkQueue
,
168 case HyperCriticalWorkQueue
:
170 &EiHyperCriticalWorkQueue
,