Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

apcobj.c File Reference

#include "ki.h"

Go to the source code of this file.

Defines

#define ASSERT_APC(E)

Functions

VOID KeInitializeApc (IN PRKAPC Apc, IN PRKTHREAD Thread, IN KAPC_ENVIRONMENT Environment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL, IN KPROCESSOR_MODE ApcMode OPTIONAL, IN PVOID NormalContext OPTIONAL)
PLIST_ENTRY KeFlushQueueApc (IN PKTHREAD Thread, IN KPROCESSOR_MODE ApcMode)
BOOLEAN KeInsertQueueApc (IN PRKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY Increment)
BOOLEAN KeRemoveQueueApc (IN PKAPC Apc)


Define Documentation

#define ASSERT_APC  ) 
 

Value:

{ \ ASSERT((E)->Type == ApcObject); \ }

Definition at line 33 of file apcobj.c.

Referenced by KeInsertQueueApc(), and KeRemoveQueueApc().


Function Documentation

PLIST_ENTRY KeFlushQueueApc IN PKTHREAD  Thread,
IN KPROCESSOR_MODE  ApcMode
 

Definition at line 138 of file apcobj.c.

References ASSERT, DISPATCH_LEVEL, FALSE, _KAPC::Inserted, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), NULL, and PKAPC.

Referenced by PspExitThread().

00145 : 00146 00147 This function flushes the APC queue selected by the specified processor 00148 mode for the specified thread. An APC queue is flushed by removing the 00149 listhead from the list, scanning the APC entries in the list, setting 00150 their inserted variables to FALSE, and then returning the address of the 00151 doubly linked list as the function value. 00152 00153 Arguments: 00154 00155 Thread - Supplies a pointer to a dispatcher object of type thread. 00156 00157 ApcMode - Supplies the processor mode of the APC queue that is to 00158 be flushed. 00159 00160 Return Value: 00161 00162 The address of the first entry in the list of APC objects that were flushed 00163 from the specified APC queue. 00164 00165 --*/ 00166 00167 { 00168 00169 PKAPC Apc; 00170 PLIST_ENTRY FirstEntry; 00171 PLIST_ENTRY NextEntry; 00172 KIRQL OldIrql; 00173 00174 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00175 00176 // 00177 // Raise IRQL to dispatcher level, lock dispatcher database, and 00178 // lock the APC queue. 00179 // 00180 00181 KiLockDispatcherDatabase(&OldIrql); 00182 KiAcquireSpinLock(&Thread->ApcQueueLock); 00183 00184 // 00185 // Get address of first APC in the list and check if the list is 00186 // empty or contains entries that should be flushed. If entries 00187 // should be flushed, then scan the list of APC objects and set their 00188 // inserted state to FALSE. 00189 // 00190 00191 FirstEntry = Thread->ApcState.ApcListHead[ApcMode].Flink; 00192 if (FirstEntry == &Thread->ApcState.ApcListHead[ApcMode]) { 00193 FirstEntry = (PLIST_ENTRY)NULL; 00194 00195 } else { 00196 RemoveEntryList(&Thread->ApcState.ApcListHead[ApcMode]); 00197 NextEntry = FirstEntry; 00198 do { 00199 Apc = CONTAINING_RECORD(NextEntry, KAPC, ApcListEntry); 00200 Apc->Inserted = FALSE; 00201 NextEntry = NextEntry->Flink; 00202 } while (NextEntry != FirstEntry); 00203 } 00204 00205 // 00206 // Unlock the APC queue, unlock the dispatcher database, lower IRQL to 00207 // its previous value, and return address of first entry in list of APC 00208 // objects that were flushed. 00209 // 00210 00211 KiReleaseSpinLock(&Thread->ApcQueueLock); 00212 KiUnlockDispatcherDatabase(OldIrql); 00213 return FirstEntry; 00214 }

VOID KeInitializeApc IN PRKAPC  Apc,
IN PRKTHREAD  Thread,
IN KAPC_ENVIRONMENT  Environment,
IN PKKERNEL_ROUTINE  KernelRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine  OPTIONAL,
IN PKNORMAL_ROUTINE NormalRoutine  OPTIONAL,
IN KPROCESSOR_MODE ApcMode  OPTIONAL,
IN PVOID NormalContext  OPTIONAL
 

Definition at line 39 of file apcobj.c.

References ApcObject, ASSERT, CurrentApcEnvironment, FALSE, KAPC, KAPC_ENVIRONMENT, KernelMode, NIL, PKKERNEL_ROUTINE, PKNORMAL_ROUTINE, PKRUNDOWN_ROUTINE, and PRKAPC.

Referenced by IopCompleteRequest(), IoRaiseHardError(), IoRaiseInformationalHardError(), KeInitializeThread(), KeSetAutoAlignmentThread(), NtGetContextThread(), NtNotifyChangeMultipleKeys(), NtQueueApcThread(), NtSetContextThread(), NtSetTimer(), PspExitNormalApc(), PspTerminateThreadByPointer(), and PspUserThreadStartup().

00052 : 00053 00054 This function initializes a kernel APC object. The thread, kernel 00055 routine, and optionally a normal routine, processor mode, and normal 00056 context parameter are stored in the APC object. 00057 00058 Arguments: 00059 00060 Apc - Supplies a pointer to a control object of type APC. 00061 00062 Thread - Supplies a pointer to a dispatcher object of type thread. 00063 00064 Environment - Supplies the environment in which the APC will execute. 00065 Valid values for this parameter are: OriginalApcEnvironment, 00066 AttachedApcEnvironment, or CurrentApcEnvironment. 00067 00068 KernelRoutine - Supplies a pointer to a function that is to be 00069 executed at IRQL APC_LEVEL in kernel mode. 00070 00071 RundownRoutine - Supplies an optional pointer to a function that is to be 00072 called if the APC is in a thread's APC queue when the thread terminates. 00073 00074 NormalRoutine - Supplies an optional pointer to a function that is 00075 to be executed at IRQL 0 in the specified processor mode. If this 00076 parameter is not specified, then the ProcessorMode and NormalContext 00077 parameters are ignored. 00078 00079 ApcMode - Supplies the processor mode in which the function specified 00080 by the NormalRoutine parameter is to be executed. 00081 00082 NormalContext - Supplies a pointer to an arbitrary data structure which is 00083 to be passed to the function specified by the NormalRoutine parameter. 00084 00085 Return Value: 00086 00087 None. 00088 00089 --*/ 00090 00091 { 00092 00093 ASSERT(Environment <= CurrentApcEnvironment); 00094 00095 // 00096 // Initialize standard control object header. 00097 // 00098 00099 Apc->Type = ApcObject; 00100 Apc->Size = sizeof(KAPC); 00101 00102 // 00103 // Initialize the APC environment, thread address, kernel routine address, 00104 // rundown routine address, normal routine address, processor mode, and 00105 // normal context parameter. If the normal routine address is null, then 00106 // the processor mode is defaulted to KernelMode and the APC is a special 00107 // APC. Otherwise, the processor mode is taken from the argument list. 00108 // 00109 00110 if (Environment == CurrentApcEnvironment) { 00111 Apc->ApcStateIndex = Thread->ApcStateIndex; 00112 00113 } else { 00114 00115 ASSERT(Environment <= Thread->ApcStateIndex); 00116 00117 Apc->ApcStateIndex = (CCHAR)Environment; 00118 } 00119 00120 Apc->Thread = Thread; 00121 Apc->KernelRoutine = KernelRoutine; 00122 Apc->RundownRoutine = RundownRoutine; 00123 Apc->NormalRoutine = NormalRoutine; 00124 if (ARGUMENT_PRESENT(NormalRoutine)) { 00125 Apc->ApcMode = ApcMode; 00126 Apc->NormalContext = NormalContext; 00127 00128 } else { 00129 Apc->ApcMode = KernelMode; 00130 Apc->NormalContext = NIL; 00131 } 00132 00133 Apc->Inserted = FALSE; 00134 return; 00135 }

BOOLEAN KeInsertQueueApc IN PRKAPC  Apc,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2,
IN KPRIORITY  Increment
 

Definition at line 217 of file apcobj.c.

References _KTHREAD::ApcQueueable, ASSERT, ASSERT_APC, DISPATCH_LEVEL, FALSE, Increment, KiInsertQueueApc(), KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by CmpPostNotify(), ExpTimerDpcRoutine(), IopCompleteRequest(), IoRaiseHardError(), IoRaiseInformationalHardError(), KeSetAutoAlignmentThread(), NtGetContextThread(), NtQueueApcThread(), NtSetContextThread(), PspExitNormalApc(), PspTerminateThreadByPointer(), and PspUserThreadStartup().

00226 : 00227 00228 This function inserts an APC object into the APC queue specifed by the 00229 thread and processor mode fields of the APC object. If the APC object 00230 is already in an APC queue or APC queuing is disabled, then no operation 00231 is performed. Otherwise the APC object is inserted in the specified queue 00232 and appropriate scheduling decisions are made. 00233 00234 Arguments: 00235 00236 Apc - Supplies a pointer to a control object of type APC. 00237 00238 SystemArgument1, SystemArgument2 - Supply a set of two arguments that 00239 contain untyped data provided by the executive. 00240 00241 Increment - Supplies the priority increment that is to be applied if 00242 queuing the APC causes a thread wait to be satisfied. 00243 00244 Return Value: 00245 00246 If the APC object is already in an APC queue or APC queuing is disabled, 00247 then a value of FALSE is returned. Otherwise a value of TRUE is returned. 00248 00249 --*/ 00250 00251 { 00252 00253 BOOLEAN Inserted; 00254 KIRQL OldIrql; 00255 PRKTHREAD Thread; 00256 00257 ASSERT_APC(Apc); 00258 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00259 00260 // 00261 // Raise IRQL to dispatcher level and lock dispatcher database. 00262 // 00263 00264 KiLockDispatcherDatabase(&OldIrql); 00265 00266 // 00267 // If APC queuing is disabled, then set inserted to FALSE. Else save 00268 // system parameter values in APC object, and attempt to queue APC. 00269 // 00270 00271 Thread = Apc->Thread; 00272 if (Thread->ApcQueueable == FALSE) { 00273 Inserted = FALSE; 00274 00275 } else { 00276 Apc->SystemArgument1 = SystemArgument1; 00277 Apc->SystemArgument2 = SystemArgument2; 00278 Inserted = KiInsertQueueApc(Apc, Increment); 00279 } 00280 00281 // 00282 // Unlock the dispatcher database, lower IRQL to its previous value, 00283 // and return whether APC object was inserted in APC queue. 00284 // 00285 00286 KiUnlockDispatcherDatabase(OldIrql); 00287 return Inserted; 00288 }

BOOLEAN KeRemoveQueueApc IN PKAPC  Apc  ) 
 

Definition at line 291 of file apcobj.c.

References _KAPC_STATE::ApcListHead, _KTHREAD::ApcQueueLock, _KTHREAD::ApcStatePointer, ASSERT, ASSERT_APC, DISPATCH_LEVEL, FALSE, _KAPC_STATE::KernelApcPending, KernelMode, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), PKAPC_STATE, and _KAPC_STATE::UserApcPending.

Referenced by CmNotifyRunDown(), ExTimerRundown(), NtCancelTimer(), and NtSetTimer().

00297 : 00298 00299 This function removes an APC object from an APC queue. If the APC object 00300 is not in an APC queue, then no operation is performed. Otherwise the 00301 APC object is removed from its current queue and its inserted state is 00302 set FALSE. 00303 00304 Arguments: 00305 00306 Apc - Supplies a pointer to a control object of type APC. 00307 00308 Return Value: 00309 00310 If the APC object is not in an APC queue, then a value of FALSE is returned. 00311 Otherwise a value of TRUE is returned. 00312 00313 --*/ 00314 00315 { 00316 00317 PKAPC_STATE ApcState; 00318 BOOLEAN Inserted; 00319 KIRQL OldIrql; 00320 PRKTHREAD Thread; 00321 00322 ASSERT_APC(Apc); 00323 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00324 00325 // 00326 // Raise IRQL to dispatcher level, lock dispatcher database, and 00327 // lock the APC queue. 00328 // 00329 00330 Thread = Apc->Thread; 00331 KiLockDispatcherDatabase(&OldIrql); 00332 KiAcquireSpinLock(&Thread->ApcQueueLock); 00333 00334 // 00335 // If the APC object is in an APC queue, then remove it from the queue 00336 // and set its inserted state to FALSE. If the queue becomes empty, set 00337 // the APC pending state to FALSE. 00338 // 00339 00340 Inserted = Apc->Inserted; 00341 if (Inserted != FALSE) { 00342 Apc->Inserted = FALSE; 00343 ApcState = Thread->ApcStatePointer[Apc->ApcStateIndex]; 00344 RemoveEntryList(&Apc->ApcListEntry); 00345 if (IsListEmpty(&ApcState->ApcListHead[Apc->ApcMode]) != FALSE) { 00346 if (Apc->ApcMode == KernelMode) { 00347 ApcState->KernelApcPending = FALSE; 00348 00349 } else { 00350 ApcState->UserApcPending = FALSE; 00351 } 00352 } 00353 } 00354 00355 // 00356 // Unlock the APC queue, unlock the dispatcher database, lower IRQL to 00357 // its previous value, and return whether an APC object was removed from 00358 // the APC queue. 00359 // 00360 00361 KiReleaseSpinLock(&Thread->ApcQueueLock); 00362 KiUnlockDispatcherDatabase(OldIrql); 00363 return Inserted; 00364 } }


Generated on Sat May 15 19:42:52 2004 for test by doxygen 1.3.7