1 /* $Id: work.c,v 1.19 2004/08/15 16:39:01 chorns 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 ******************************************************************/
16 #include <internal/debug.h>
18 /* DEFINES *******************************************************************/
20 #define NUMBER_OF_WORKER_THREADS (5)
22 /* TYPES *********************************************************************/
24 typedef struct _WORK_QUEUE
27 * PURPOSE: Head of the list of waiting work items
32 * PURPOSE: Sychronize access to the work queue
37 * PURPOSE: Worker threads with nothing to do wait on this event
42 * PURPOSE: Thread associated with work queue
44 HANDLE Thread
[NUMBER_OF_WORKER_THREADS
];
45 } WORK_QUEUE
, *PWORK_QUEUE
;
47 /* GLOBALS *******************************************************************/
50 * PURPOSE: Queue of items waiting to be processed at normal priority
52 WORK_QUEUE EiNormalWorkQueue
;
54 WORK_QUEUE EiCriticalWorkQueue
;
56 WORK_QUEUE EiHyperCriticalWorkQueue
;
58 /* FUNCTIONS ****************************************************************/
60 //static NTSTATUS STDCALL
62 ExWorkerThreadEntryPoint(IN PVOID context
)
64 * FUNCTION: Entry point for a worker thread
66 * context = Parameters
68 * NOTE: To kill a worker thread you must queue an item whose callback
69 * calls PsTerminateSystemThread
72 PWORK_QUEUE queue
= (PWORK_QUEUE
)context
;
73 PWORK_QUEUE_ITEM item
;
78 current
= ExInterlockedRemoveHeadList(&queue
->Head
,
82 item
= CONTAINING_RECORD(current
,WORK_QUEUE_ITEM
,List
);
83 item
->WorkerRoutine(item
->Parameter
);
87 KeWaitForSingleObject((PVOID
)&queue
->Sem
,
92 DPRINT("Woke from wait\n");
97 static VOID
ExInitializeWorkQueue(PWORK_QUEUE WorkQueue
,
103 InitializeListHead(&WorkQueue
->Head
);
104 KeInitializeSpinLock(&WorkQueue
->Lock
);
105 KeInitializeSemaphore(&WorkQueue
->Sem
,
108 for (i
=0; i
<NUMBER_OF_WORKER_THREADS
; i
++)
110 PsCreateSystemThread(&WorkQueue
->Thread
[i
],
115 ExWorkerThreadEntryPoint
,
117 ObReferenceObjectByHandle(WorkQueue
->Thread
[i
],
123 KeSetPriorityThread(&Thread
->Tcb
,
125 ObDereferenceObject(Thread
);
130 ExInitializeWorkerThreads(VOID
)
132 ExInitializeWorkQueue(&EiNormalWorkQueue
,
134 ExInitializeWorkQueue(&EiCriticalWorkQueue
,
135 LOW_REALTIME_PRIORITY
);
136 ExInitializeWorkQueue(&EiHyperCriticalWorkQueue
,
144 ExQueueWorkItem (PWORK_QUEUE_ITEM WorkItem
,
145 WORK_QUEUE_TYPE QueueType
)
147 * FUNCTION: Inserts a work item in a queue for one of the system worker
150 * WorkItem = Item to insert
151 * QueueType = Queue to insert it in
154 assert(WorkItem
!=NULL
);
155 ASSERT_IRQL(DISPATCH_LEVEL
);
158 * Insert the item in the appropiate queue and wake up any thread
159 * waiting for something to do
163 case DelayedWorkQueue
:
164 ExInterlockedInsertTailList(&EiNormalWorkQueue
.Head
,
166 &EiNormalWorkQueue
.Lock
);
167 KeReleaseSemaphore(&EiNormalWorkQueue
.Sem
,
173 case CriticalWorkQueue
:
174 ExInterlockedInsertTailList(&EiCriticalWorkQueue
.Head
,
176 &EiCriticalWorkQueue
.Lock
);
177 KeReleaseSemaphore(&EiCriticalWorkQueue
.Sem
,
183 case HyperCriticalWorkQueue
:
184 ExInterlockedInsertTailList(&EiHyperCriticalWorkQueue
.Head
,
186 &EiHyperCriticalWorkQueue
.Lock
);
187 KeReleaseSemaphore(&EiHyperCriticalWorkQueue
.Sem
,
194 case MaximumWorkQueue
: