2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ke/dpc.c
5 * PURPOSE: Handle DPCs (Delayed Procedure Calls)
6 * PROGRAMMER: David Welch (welch@mcmail.com)
12 * NOTE: See also the higher level support routines in ntoskrnl/io/dpc.c
15 /* INCLUDES ***************************************************************/
17 #include <ddk/ntddk.h>
20 #include <internal/debug.h>
22 /* TYPES *******************************************************************/
24 /* GLOBALS ******************************************************************/
26 static LIST_ENTRY DpcQueueHead
={NULL
,NULL
};
27 static KSPIN_LOCK DpcQueueLock
={0,};
29 /* FUNCTIONS ****************************************************************/
31 VOID
KeInitializeDpc(PKDPC Dpc
, PKDEFERRED_ROUTINE DeferredRoutine
,
32 PVOID DeferredContext
)
34 * FUNCTION: Initalizes a DPC
36 * Dpc = Caller supplied DPC to be initialized
37 * DeferredRoutine = Associated DPC callback
38 * DeferredContext = Parameter to be passed to the callback
39 * NOTE: Callers must be running at IRQL PASSIVE_LEVEL
43 Dpc
->DeferredRoutine
=DeferredRoutine
;
44 Dpc
->DeferredContext
=DeferredContext
;
48 void KeDrainDpcQueue(void)
50 * FUNCTION: Called to execute queued dpcs
53 PLIST_ENTRY current_entry
;
57 KeAcquireSpinLockAtDpcLevel(&DpcQueueLock
);
58 current_entry
= RemoveHeadList(&DpcQueueHead
);
59 current
= CONTAINING_RECORD(current_entry
,KDPC
,DpcListEntry
);
60 while (current_entry
!=(&DpcQueueHead
))
63 current
->DeferredRoutine(current
,current
->DeferredContext
,
64 current
->SystemArgument1
,
65 current
->SystemArgument2
);
67 current_entry
= RemoveHeadList(&DpcQueueHead
);
68 current
= CONTAINING_RECORD(¤t_entry
,KDPC
,DpcListEntry
);
70 KeReleaseSpinLockFromDpcLevel(&DpcQueueLock
);
71 // DPRINT("Finished KeDrainDpcQueue()\n",0);
74 BOOLEAN
KeRemoveQueueDpc(PKDPC Dpc
)
76 * FUNCTION: Removes DPC object from the system dpc queue
79 * RETURNS: TRUE if the DPC was in the queue
87 RemoveEntryList(&Dpc
->DpcListEntry
);
92 BOOLEAN
KeInsertQueueDpc(PKDPC dpc
, PVOID SystemArgument1
,
93 PVOID SystemArgument2
)
95 * FUNCTION: Queues a DPC for execution when the IRQL of a processor
96 * drops below DISPATCH_LEVEL
98 * Dpc = Initalizes DPC
99 * SystemArguments[1-2] = Undocumented
100 * RETURNS: TRUE if the DPC object wasn't already in the queue
104 DPRINT("KeInsertQueueDpc()\n",0);
105 assert(KeGetCurrentIrql()>=DISPATCH_LEVEL
);
108 dpc
->Importance
=Medium
;
109 dpc
->SystemArgument1
=SystemArgument1
;
110 dpc
->SystemArgument2
=SystemArgument2
;
115 KeAcquireSpinLockAtDpcLevel(&DpcQueueLock
);
116 InsertHeadList(&DpcQueueHead
,&dpc
->DpcListEntry
);
117 KeReleaseSpinLockFromDpcLevel(&DpcQueueLock
);
119 DPRINT("DpcQueueHead.Flink %x\n",DpcQueueHead
.Flink
);
120 DPRINT("Leaving KeInsertQueueDpc()\n",0);
126 * FUNCTION: Initialize DPC handling
129 InitializeListHead(&DpcQueueHead
);