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

dpcobj.c File Reference

#include "ki.h"

Go to the source code of this file.

Defines

#define ASSERT_DPC(E)

Functions

VOID KeInitializeDpc (IN PRKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
BOOLEAN KeInsertQueueDpc (IN PRKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
BOOLEAN KeRemoveQueueDpc (IN PRKDPC Dpc)
VOID KeSetImportanceDpc (IN PRKDPC Dpc, IN KDPC_IMPORTANCE Importance)
VOID KeSetTargetProcessorDpc (IN PRKDPC Dpc, IN CCHAR Number)


Define Documentation

#define ASSERT_DPC  ) 
 

Value:

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

Definition at line 34 of file dpcobj.c.

Referenced by KeInsertQueueDpc(), and KeRemoveQueueDpc().


Function Documentation

VOID KeInitializeDpc IN PRKDPC  Dpc,
IN PKDEFERRED_ROUTINE  DeferredRoutine,
IN PVOID  DeferredContext
 

Definition at line 39 of file dpcobj.c.

References DpcObject, MediumImportance, NULL, PKDEFERRED_ROUTINE, and PRKDPC.

Referenced by CcInitializeCacheManager(), CmpWorker(), IoInitSystem(), IopErrorLogQueueRequest(), IovpInternalDeferredCompletion(), KdInitSystem(), KiInitializeKernel(), KiInitSystem(), MiInitializeSpecialPoolCriteria(), MmInitSystem(), NtCreateTimer(), and VdmpDelayInterrupt().

00047 : 00048 00049 This function initializes a kernel DPC object. The deferred routine 00050 and context parameter are stored in the DPC object. 00051 00052 Arguments: 00053 00054 Dpc - Supplies a pointer to a control object of type DPC. 00055 00056 DeferredRoutine - Supplies a pointer to a function that is called when 00057 the DPC object is removed from the current processor's DPC queue. 00058 00059 DeferredContext - Supplies a pointer to an arbitrary data structure which is 00060 to be passed to the function specified by the DeferredRoutine parameter. 00061 00062 Return Value: 00063 00064 None. 00065 00066 --*/ 00067 00068 { 00069 00070 // 00071 // Initialize standard control object header. 00072 // 00073 00074 Dpc->Type = DpcObject; 00075 Dpc->Number = 0; 00076 Dpc->Importance = MediumImportance; 00077 00078 // 00079 // Initialize deferred routine address and deferred context parameter. 00080 // 00081 00082 Dpc->DeferredRoutine = DeferredRoutine; 00083 Dpc->DeferredContext = DeferredContext; 00084 Dpc->Lock = NULL; 00085 return; 00086 }

BOOLEAN KeInsertQueueDpc IN PRKDPC  Dpc,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2
 

Definition at line 89 of file dpcobj.c.

References ASSERT_DPC, DISPATCH_LEVEL, FALSE, HIGH_LEVEL, HighImportance, Index, IPI_DPC, KeGetCurrentPrcb, KeLowerIrql(), KeRaiseIrql(), KiIpiSend(), KiProcessorBlock, KiRequestSoftwareInterrupt(), Lock, LowImportance, MAXIMUM_PROCESSORS, NULL, and TRUE.

Referenced by KdExitDebugger(), KeSetTimerEx(), KiCalibrateTimeAdjustment(), and KiTimerListExpire().

00097 : 00098 00099 This function inserts a DPC object into the DPC queue. If the DPC object 00100 is already in the DPC queue, then no operation is performed. Otherwise, 00101 the DPC object is inserted in the DPC queue and a dispatch interrupt is 00102 requested. 00103 00104 Arguments: 00105 00106 Dpc - Supplies a pointer to a control object of type DPC. 00107 00108 SystemArgument1, SystemArgument2 - Supply a set of two arguments that 00109 contain untyped data provided by the executive. 00110 00111 Return Value: 00112 00113 If the DPC object is already in a DPC queue, then a value of FALSE is 00114 returned. Otherwise a value of TRUE is returned. 00115 00116 --*/ 00117 00118 { 00119 00120 ULONG Index; 00121 PKSPIN_LOCK Lock; 00122 KIRQL OldIrql; 00123 PKPRCB Prcb; 00124 ULONG Processor; 00125 00126 ASSERT_DPC(Dpc); 00127 00128 // 00129 // Disable interrupts. 00130 // 00131 00132 KeRaiseIrql(HIGH_LEVEL, &OldIrql); 00133 00134 // 00135 // Acquire the DPC queue lock for the specified target processor. 00136 // 00137 00138 #if !defined(NT_UP) 00139 00140 if (Dpc->Number >= MAXIMUM_PROCESSORS) { 00141 Processor = Dpc->Number - MAXIMUM_PROCESSORS; 00142 Prcb = KiProcessorBlock[Processor]; 00143 00144 } else { 00145 Prcb = KeGetCurrentPrcb(); 00146 } 00147 00148 KiAcquireSpinLock(&Prcb->DpcLock); 00149 00150 #else 00151 00152 Prcb = KeGetCurrentPrcb(); 00153 00154 #endif 00155 00156 // 00157 // If the DPC object is not in a DPC queue, then store the system 00158 // arguments, insert the DPC object in the DPC queue, increment the 00159 // number of DPCs queued to the target processor, increment the DPC 00160 // queue depth, set the address of the DPC target DPC spinlock, and 00161 // request a dispatch interrupt if appropriate. 00162 // 00163 00164 if ((Lock = InterlockedCompareExchangePointer(&Dpc->Lock, &Prcb->DpcLock, NULL)) == NULL) { 00165 Prcb->DpcCount += 1; 00166 Prcb->DpcQueueDepth += 1; 00167 Dpc->SystemArgument1 = SystemArgument1; 00168 Dpc->SystemArgument2 = SystemArgument2; 00169 00170 // 00171 // If the DPC is of high importance, then insert the DPC at the 00172 // head of the DPC queue. Otherwise, insert the DPC at the end 00173 // of the DPC queue. 00174 // 00175 00176 if (Dpc->Importance == HighImportance) { 00177 InsertHeadList(&Prcb->DpcListHead, &Dpc->DpcListEntry); 00178 00179 } else { 00180 InsertTailList(&Prcb->DpcListHead, &Dpc->DpcListEntry); 00181 } 00182 // 00183 // A memory barrier is required here to synchronize with retire DPC 00184 // list, which clears DpcRoutineActive and DpcInterruptRequested 00185 // without owning the dispatcher lock. 00186 // 00187 00188 #if defined(_ALPHA_) && !defined(NT_UP) 00189 00190 __MB(); 00191 00192 #endif 00193 00194 // 00195 // If a DPC routine is not active on the target processor, then 00196 // request a dispatch interrupt if appropriate. 00197 // 00198 00199 if ((Prcb->DpcRoutineActive == FALSE) && 00200 (Prcb->DpcInterruptRequested == FALSE)) { 00201 00202 // 00203 // Request a dispatch interrupt on the current processor if 00204 // the DPC is not of low importance, the length of the DPC 00205 // queue has exceeded the maximum threshold, or if the DPC 00206 // request rate is below the minimum threshold. 00207 // 00208 00209 #if defined(NT_UP) 00210 00211 if ((Dpc->Importance != LowImportance) || 00212 (Prcb->DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) || 00213 (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) { 00214 Prcb->DpcInterruptRequested = TRUE; 00215 KiRequestSoftwareInterrupt(DISPATCH_LEVEL); 00216 } 00217 00218 // 00219 // If the DPC is being queued to another processor and the 00220 // DPC is of high importance, or the length of the other 00221 // processor's DPC queue has exceeded the maximum threshold, 00222 // then request a dispatch interrupt. 00223 // 00224 00225 #else 00226 00227 if (Prcb != KeGetCurrentPrcb()) { 00228 if (((Dpc->Importance == HighImportance) || 00229 (Prcb->DpcQueueDepth >= Prcb->MaximumDpcQueueDepth))) { 00230 Prcb->DpcInterruptRequested = TRUE; 00231 KiIpiSend((KAFFINITY)(1 << Processor), IPI_DPC); 00232 } 00233 00234 } else { 00235 00236 // 00237 // Request a dispatch interrupt on the current processor if 00238 // the DPC is not of low importance, the length of the DPC 00239 // queue has exceeded the maximum threshold, or if the DPC 00240 // request rate is below the minimum threshold. 00241 // 00242 00243 if ((Dpc->Importance != LowImportance) || 00244 (Prcb->DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) || 00245 (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) { 00246 Prcb->DpcInterruptRequested = TRUE; 00247 KiRequestSoftwareInterrupt(DISPATCH_LEVEL); 00248 } 00249 } 00250 00251 #endif 00252 00253 } 00254 } 00255 00256 // 00257 // Release the DPC lock, enable interrupts, and return whether the 00258 // DPC was queued or not. 00259 // 00260 00261 #if !defined(NT_UP) 00262 00263 KiReleaseSpinLock(&Prcb->DpcLock); 00264 00265 #endif 00266 00267 KeLowerIrql(OldIrql); 00268 return (Lock == NULL); 00269 }

BOOLEAN KeRemoveQueueDpc IN PRKDPC  Dpc  ) 
 

Definition at line 272 of file dpcobj.c.

References ASSERT_DPC, Lock, and NULL.

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

00278 : 00279 00280 This function removes a DPC object from the DPC queue. If the DPC object 00281 is not in the DPC queue, then no operation is performed. Otherwise, the 00282 DPC object is removed from the DPC queue and its inserted state is set 00283 FALSE. 00284 00285 Arguments: 00286 00287 Dpc - Supplies a pointer to a control object of type DPC. 00288 00289 Return Value: 00290 00291 If the DPC object is not in the DPC queue, then a value of FALSE is 00292 returned. Otherwise a value of TRUE is returned. 00293 00294 --*/ 00295 00296 { 00297 00298 PKSPIN_LOCK Lock; 00299 PKPRCB Prcb; 00300 00301 ASSERT_DPC(Dpc); 00302 00303 // 00304 // If the DPC object is in the DPC queue, then remove it from the queue 00305 // and set its inserted state to FALSE. 00306 // 00307 00308 _disable(); 00309 Lock = Dpc->Lock; 00310 if (Lock != NULL) { 00311 00312 // 00313 // Acquire the DPC lock of the target processor. 00314 // 00315 00316 #if !defined(NT_UP) 00317 00318 KiAcquireSpinLock(Lock); 00319 00320 #endif 00321 00322 // 00323 // If the specified DPC is still in the DPC queue, then remove 00324 // it. 00325 // 00326 // N.B. It is possible for specified DPC to be removed from the 00327 // specified DPC queue before the DPC lock is obtained. 00328 // 00329 // 00330 00331 if (Lock == Dpc->Lock) { 00332 Prcb = CONTAINING_RECORD(Lock, KPRCB, DpcLock); 00333 Prcb->DpcQueueDepth -= 1; 00334 RemoveEntryList(&Dpc->DpcListEntry); 00335 00336 #if defined(_ALPHA_) && !defined(NT_UP) 00337 00338 __MB(); 00339 00340 #endif 00341 00342 Dpc->Lock = NULL; 00343 } 00344 00345 // 00346 // Release the DPC lock of the target processor. 00347 // 00348 00349 #if !defined(NT_UP) 00350 00351 KiReleaseSpinLock(Lock); 00352 00353 #endif 00354 00355 } 00356 00357 // 00358 // Enable interrupts and return whether the DPC was removed from a DPC 00359 // queue. 00360 // 00361 00362 _enable(); 00363 return (Lock != NULL); 00364 }

VOID KeSetImportanceDpc IN PRKDPC  Dpc,
IN KDPC_IMPORTANCE  Importance
 

Definition at line 367 of file dpcobj.c.

References KDPC_IMPORTANCE.

00374 : 00375 00376 This function sets the importance of a DPC. 00377 00378 Arguments: 00379 00380 Dpc - Supplies a pointer to a control object of type DPC. 00381 00382 Number - Supplies the importance of the DPC. 00383 00384 Return Value: 00385 00386 None. 00387 00388 --*/ 00389 00390 { 00391 00392 // 00393 // Set the importance of the DPC. 00394 // 00395 00396 Dpc->Importance = (UCHAR)Importance; 00397 return; 00398 }

VOID KeSetTargetProcessorDpc IN PRKDPC  Dpc,
IN CCHAR  Number
 

Definition at line 401 of file dpcobj.c.

References MAXIMUM_PROCESSORS.

00408 : 00409 00410 This function sets the processor number to which the DPC is targeted. 00411 00412 Arguments: 00413 00414 Dpc - Supplies a pointer to a control object of type DPC. 00415 00416 Number - Supplies the target processor number. 00417 00418 Return Value: 00419 00420 None. 00421 00422 --*/ 00423 00424 { 00425 00426 // 00427 // Set target processor number. 00428 // 00429 // The target processor number if biased by the maximum number of 00430 // processors that are supported. 00431 // 00432 00433 Dpc->Number = MAXIMUM_PROCESSORS + Number; 00434 return; 00435 } }


Generated on Sat May 15 19:43:29 2004 for test by doxygen 1.3.7