ReactOS  0.4.15-dev-1187-g119f102
clntirp.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (C) Microsoft Corporation, 1991 - 1999
4 
5 Module Name:
6 
7  clntirp.c
8 
9 Abstract:
10 
11  Client IRP queuing routines for CLASSPNP
12 
13 Environment:
14 
15  kernel mode only
16 
17 Notes:
18 
19 
20 Revision History:
21 
22 --*/
23 
24 #include "classp.h"
25 #include "debug.h"
26 
27 
28 #ifdef DEBUG_USE_WPP
29 #include "clntirp.tmh"
30 #endif
31 
32 VOID
35  );
36 
37 VOID
40  );
41 
42 KDEFERRED_ROUTINE ClasspIdleTimerDpc;
43 
44 VOID
47  BOOLEAN PostToDpc
48  );
49 
50 
51 PIRP
54  );
55 
56 
57 /*++
58 
59 EnqueueDeferredClientIrp
60 
61 Routine Description:
62 
63  Insert the deferred irp into the list.
64 
65  Note: we currently do not support Cancel for storage irps.
66 
67 Arguments:
68 
69  Fdo - Pointer to the device object
70  Irp - Pointer to the I/O request packet
71 
72 Return Value:
73 
74  None
75 
76 --*/
77 VOID
79  PDEVICE_OBJECT Fdo,
80  PIRP Irp
81  )
82 {
84  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
85  KIRQL oldIrql;
86 
87 
88  KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
89  InsertTailList(&fdoData->DeferredClientIrpList, &Irp->Tail.Overlay.ListEntry);
90 
91 
92  KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
93 }
94 
95 /*++
96 
97 DequeueDeferredClientIrp
98 
99 Routine Description:
100 
101  Remove the deferred irp from the list.
102 
103 Arguments:
104 
105  Fdo - Pointer to the device object
106 
107 Return Value:
108 
109  Pointer to removed IRP
110 
111 --*/
112 PIRP
114  PDEVICE_OBJECT Fdo
115  )
116 {
117  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
118  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
119  PIRP irp;
120 
121  //
122  // The DeferredClientIrpList is almost always empty.
123  // We don't want to grab the spinlock every time we check it (which is on every xfer completion)
124  // so check once first before we grab the spinlock.
125  //
126  if (IsListEmpty(&fdoData->DeferredClientIrpList)){
127  irp = NULL;
128  }
129  else {
130  PLIST_ENTRY listEntry;
131  KIRQL oldIrql;
132 
133  KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
134  if (IsListEmpty(&fdoData->DeferredClientIrpList)){
135  listEntry = NULL;
136  }
137  else {
138  listEntry = RemoveHeadList(&fdoData->DeferredClientIrpList);
139  }
140  KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
141 
142  if (listEntry == NULL) {
143  irp = NULL;
144  }
145  else {
146  irp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);
147  NT_ASSERT(irp->Type == IO_TYPE_IRP);
148 
149 
150  InitializeListHead(&irp->Tail.Overlay.ListEntry);
151  }
152  }
153 
154  return irp;
155 }
156 
157 /*++
158 
159 ClasspInitializeIdleTimer
160 
161 Routine Description:
162 
163  Initialize the idle timer for the given device.
164 
165 Arguments:
166 
167  FdoExtension - Pointer to the device extension
168 
169 Return Value:
170 
171  None
172 
173 --*/
174 VOID
177  )
178 {
179  PCLASS_PRIVATE_FDO_DATA fdoData = FdoExtension->PrivateFdoData;
180  ULONG idleInterval = CLASS_IDLE_INTERVAL;
181  ULONG idlePrioritySupported = TRUE;
182  ULONG activeIdleIoMax = 1;
183 
184  ClassGetDeviceParameter(FdoExtension,
187  &idlePrioritySupported);
188 
189 
190  if (idlePrioritySupported == FALSE) {
191  //
192  // User has set the registry to disable idle priority for this disk.
193  // No need to initialize any further.
194  // Always ensure that none of the other fields used for idle priority
195  // io are ever used without checking if it is supported.
196  //
197  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspInitializeIdleTimer: Idle priority not supported for disk %p\n", FdoExtension));
198  fdoData->IdlePrioritySupported = FALSE;
199  fdoData->IdleIoCount = 0;
200  fdoData->ActiveIoCount = 0;
201  return;
202  }
203 
204  ClassGetDeviceParameter(FdoExtension,
207  &idleInterval);
208 
209  if ((idleInterval < CLASS_IDLE_INTERVAL_MIN) || (idleInterval > USHORT_MAX)) {
210  //
211  // If the interval is too low or too high, reset it to the default value.
212  //
213  idleInterval = CLASS_IDLE_INTERVAL;
214  }
215 
216  fdoData->IdlePrioritySupported = TRUE;
218  KeInitializeTimer(&fdoData->IdleTimer);
220  InitializeListHead(&fdoData->IdleIrpList);
221  fdoData->IdleTimerStarted = FALSE;
223  fdoData->IdleInterval = (USHORT)(idleInterval);
224  fdoData->IdleIoCount = 0;
225  fdoData->ActiveIoCount = 0;
226  fdoData->ActiveIdleIoCount = 0;
227 
228  ClassGetDeviceParameter(FdoExtension,
231  &activeIdleIoMax);
232 
233  activeIdleIoMax = max(activeIdleIoMax, 1);
234  activeIdleIoMax = min(activeIdleIoMax, USHORT_MAX);
235 
236  fdoData->IdleActiveIoMax = (USHORT)activeIdleIoMax;
237 
238  return;
239 }
240 
241 /*++
242 
243 ClasspStartIdleTimer
244 
245 Routine Description:
246 
247  Start the idle timer if not already running. Reset the
248  timer counters before starting the timer. Use the IdleInterval
249  in the private fdo data to setup the timer.
250 
251 Arguments:
252 
253  FdoData - Pointer to the private fdo data
254 
255 Return Value:
256 
257  None
258 
259 --*/
260 VOID
263  )
264 {
265  LARGE_INTEGER dueTime;
266  LONG mstotimer;
267  LONG timerStarted;
268 
269  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspStartIdleTimer: Start idle timer\n"));
270 
271  timerStarted = InterlockedCompareExchange(&FdoData->IdleTimerStarted, 1, 0);
272 
273  if (!timerStarted) {
274 
275  //
276  // Reset the anti-starvation start time.
277  //
278  FdoData->AntiStarvationStartTime = ClasspGetCurrentTime();
279 
280  //
281  // convert milliseconds to a relative 100ns
282  //
283  mstotimer = (-10) * 1000;
284 
285  //
286  // multiply the period
287  //
288  dueTime.QuadPart = Int32x32To64(FdoData->IdleInterval, mstotimer);
289 
290  KeSetTimerEx(&FdoData->IdleTimer,
291  dueTime,
292  FdoData->IdleInterval,
293  &FdoData->IdleDpc);
294  }
295  return;
296 }
297 
298 /*++
299 
300 ClasspStopIdleTimer
301 
302 Routine Description:
303 
304  Stop the idle timer if running. Also reset the timer counters.
305 
306 Arguments:
307 
308  FdoData - Pointer to the private fdo data
309 
310 Return Value:
311 
312  None
313 
314 --*/
315 VOID
318  )
319 {
320  LONG timerStarted;
321 
322  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspStopIdleTimer: Stop idle timer\n"));
323 
324  timerStarted = InterlockedCompareExchange(&FdoData->IdleTimerStarted, 0, 1);
325 
326  if (timerStarted) {
327  (VOID)KeCancelTimer(&FdoData->IdleTimer);
328  }
329  return;
330 }
331 
332 /*++
333 
334 ClasspGetIdleTime
335 
336 Routine Description:
337 
338  This routine returns how long it has been since the last non-idle request
339  completed by checking the actual time.
340 
341 Arguments:
342 
343  FdoData - Pointer to the private fdo data
344 
345 Return Value:
346 
347  The idle interval in ms.
348 
349 --*/
350 ULONGLONG
352  IN PCLASS_PRIVATE_FDO_DATA FdoData,
353  IN LARGE_INTEGER CurrentTime
354  )
355 {
356  ULONGLONG idleTime;
358 
359  //
360  // Get the time difference between current time and last I/O
361  // complete time.
362  //
363 
364  status = RtlULongLongSub((ULONGLONG)CurrentTime.QuadPart,
365  (ULONGLONG)FdoData->LastNonIdleIoTime.QuadPart,
366  &idleTime);
367 
368  if (NT_SUCCESS(status)) {
369  //
370  // Convert the time to milliseconds.
371  //
372  idleTime = ClasspTimeDiffToMs(idleTime);
373  } else {
374  //
375  // Failed to get time difference, assume enough time passed.
376  //
377  idleTime = FdoData->IdleInterval;
378  }
379 
380  return idleTime;
381 }
382 
383 /*++
384 
385 ClasspIdleDurationSufficient
386 
387 Routine Description:
388 
389  This routine computes whether enough idle duration has elapsed since the
390  completion of the last non-idle request.
391 
392 Arguments:
393 
394  FdoData - Pointer to the private fdo data
395 
396  CurrentTimeIn - If CurrentTimeIn is non-NULL
397  - contents are set to NULL if the time is not updated.
398  - time is updated otherwise
399 
400 Return Value:
401 
402  TRUE if sufficient idle duration has elapsed to issue the next idle request.
403 
404 --*/
405 LOGICAL
407  IN PCLASS_PRIVATE_FDO_DATA FdoData,
408  OUT LARGE_INTEGER** CurrentTimeIn
409  )
410 {
411  ULONGLONG idleInterval;
412  LARGE_INTEGER CurrentTime;
413 
414  //
415  // If there are any outstanding non-idle requests, then there has been no
416  // idle time.
417  //
418  if (FdoData->ActiveIoCount > 0) {
419  if (CurrentTimeIn != NULL) {
420  *CurrentTimeIn = NULL;
421  }
422  return FALSE;
423  }
424 
425  //
426  // Check whether an idle request should be issued now or on the next timer
427  // expiration.
428  //
429 
430  CurrentTime = ClasspGetCurrentTime();
431  idleInterval = ClasspGetIdleTime(FdoData, CurrentTime);
432 
433  if (CurrentTimeIn != NULL) {
434  **CurrentTimeIn = CurrentTime;
435  }
436 
437  if (idleInterval >= FdoData->IdleInterval) {
438  return TRUE;
439  }
440 
441  return FALSE;
442 }
443 
444 /*++
445 
446 ClasspIdleTimerDpc
447 
448 Routine Description:
449 
450  Timer dpc function. This function will be called once every
451  IdleInterval. An idle request will be queued if sufficient idle time
452  has elapsed since the last non-idle request.
453 
454 Arguments:
455 
456  Dpc - Pointer to DPC object
457  Context - Pointer to the fdo device extension
458  SystemArgument1 - Not used
459  SystemArgument2 - Not used
460 
461 Return Value:
462 
463  None
464 
465 --*/
466 VOID
467 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
469  IN PKDPC Dpc,
470  IN PVOID Context,
473  )
474 {
475  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Context;
476  PCLASS_PRIVATE_FDO_DATA fdoData;
477  ULONGLONG idleTime;
479  LARGE_INTEGER currentTime;
480  LARGE_INTEGER* pCurrentTime;
481 
485 
486  if (fdoExtension == NULL) {
487  NT_ASSERT(fdoExtension != NULL);
488  return;
489  }
490 
491  fdoData = fdoExtension->PrivateFdoData;
492 
493  if (fdoData->ActiveIoCount <= 0) {
494 
495  //
496  // If there are max active idle requests, do not issue another one here.
497  //
498  if (fdoData->ActiveIdleIoCount >= fdoData->IdleActiveIoMax) {
499  return;
500  }
501 
502  //
503  // Check whether enough idle time has passed since the last non-idle
504  // request has completed.
505  //
506 
507  pCurrentTime = &currentTime;
508  if (ClasspIdleDurationSufficient(fdoData, &pCurrentTime)) {
509  //
510  // We are going to issue an idle request so reset the anti-starvation
511  // timer counter.
512  // If we are here (Idle duration is sufficient), pCurrentTime is
513  // expected to be set.
514  //
515  NT_ASSERT(pCurrentTime != NULL);
516  fdoData->AntiStarvationStartTime = *pCurrentTime;
517  ClasspServiceIdleRequest(fdoExtension, FALSE);
518  }
519  return;
520  }
521 
522  //
523  // Get the time difference between current time and last I/O
524  // complete time.
525  //
526 
527  currentTime = ClasspGetCurrentTime();
528  status = RtlULongLongSub((ULONGLONG)currentTime.QuadPart,
530  &idleTime);
531 
532  if (NT_SUCCESS(status)) {
533  //
534  // Convert the time to milliseconds.
535  //
536  idleTime = ClasspTimeDiffToMs(idleTime);
537  } else {
538  //
539  // Failed to get time difference, assume enough time passed.
540  //
541  idleTime = fdoData->StarvationDuration;
542  }
543 
544  //
545  // If the timer is running then there must be at least one idle priority I/O pending
546  //
547  if (idleTime >= fdoData->StarvationDuration) {
548  fdoData->AntiStarvationStartTime = currentTime;
549  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspIdleTimerDpc: Starvation timer. Send one idle request\n"));
550  ClasspServiceIdleRequest(fdoExtension, FALSE);
551  }
552  return;
553 }
554 
555 /*++
556 
557 ClasspEnqueueIdleRequest
558 
559 Routine Description:
560 
561  This function will insert the idle request into the list.
562  If the inserted reqeust is the first request then it will
563  start the timer.
564 
565 Arguments:
566 
567  DeviceObject - Pointer to device object
568  Irp - Pointer to the idle I/O request packet
569 
570 Return Value:
571 
572  NT status code.
573 
574 --*/
575 NTSTATUS
578  PIRP Irp
579  )
580 {
581  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
582  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
583  KIRQL oldIrql;
584  BOOLEAN issueRequest = TRUE;
585  LARGE_INTEGER currentTime;
586  LARGE_INTEGER* pCurrentTime;
587 
588  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspEnqueueIdleRequest: Queue idle request %p\n", Irp));
589 
591 
592  //
593  // Reset issueRequest if the idle duration is not sufficient.
594  //
595  pCurrentTime = &currentTime;
596  if (ClasspIdleDurationSufficient(fdoData, &pCurrentTime) == FALSE) {
597  issueRequest = FALSE;
598  }
599 
600  //
601  // If there are already max active idle requests in the port driver, then
602  // queue this idle request.
603  //
604  if (fdoData->ActiveIdleIoCount >= fdoData->IdleActiveIoMax) {
605  issueRequest = FALSE;
606  }
607 
608 
609  KeAcquireSpinLock(&fdoData->IdleListLock, &oldIrql);
610  if (IsListEmpty(&fdoData->IdleIrpList)) {
611  NT_ASSERT(fdoData->IdleIoCount == 0);
612  }
613  InsertTailList(&fdoData->IdleIrpList, &Irp->Tail.Overlay.ListEntry);
614 
615 
616  fdoData->IdleIoCount++;
617  if (!fdoData->IdleTimerStarted) {
618  ClasspStartIdleTimer(fdoData);
619  }
620 
621  if (fdoData->IdleIoCount != 1) {
622  issueRequest = FALSE;
623  }
624 
625 
626  KeReleaseSpinLock(&fdoData->IdleListLock, oldIrql);
627 
628  if (issueRequest) {
629  ClasspServiceIdleRequest(fdoExtension, FALSE);
630  }
631 
632  return STATUS_PENDING;
633 }
634 
635 /*++
636 
637 ClasspDequeueIdleRequest
638 
639 Routine Description:
640 
641  This function will remove the next idle request from the list.
642  If there are no requests in the queue, then it will return NULL.
643 
644 Arguments:
645 
646  FdoExtension - Pointer to the functional device extension
647 
648 Return Value:
649 
650  Pointer to removed IRP
651 
652 --*/
653 PIRP
656  )
657 {
658  PCLASS_PRIVATE_FDO_DATA fdoData = FdoExtension->PrivateFdoData;
659  PLIST_ENTRY listEntry = NULL;
660  PIRP irp = NULL;
661  KIRQL oldIrql;
662 
663  KeAcquireSpinLock(&fdoData->IdleListLock, &oldIrql);
664 
665  if (fdoData->IdleIoCount > 0) {
666  listEntry = RemoveHeadList(&fdoData->IdleIrpList);
667  //
668  // Make sure we actaully removed a request from the list
669  //
670  NT_ASSERT(listEntry != &fdoData->IdleIrpList);
671  //
672  // Decrement the idle I/O count.
673  //
674  fdoData->IdleIoCount--;
675  //
676  // Stop the timer on last request
677  //
678  if (fdoData->IdleIoCount == 0) {
679  ClasspStopIdleTimer(fdoData);
680  }
681  irp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);
682  NT_ASSERT(irp->Type == IO_TYPE_IRP);
683 
684 
685  InitializeListHead(&irp->Tail.Overlay.ListEntry);
686  }
687 
688  KeReleaseSpinLock(&fdoData->IdleListLock, oldIrql);
689 
690 
691  return irp;
692 }
693 
694 /*++
695 
696 ClasspCompleteIdleRequest
697 
698 Routine Description:
699 
700  This function will be called every time an idle request is completed.
701  This will call ClasspServiceIdleRequest to process any other pending idle requests.
702 
703 Arguments:
704 
705  FdoExtension - Pointer to the device extension
706 
707 Return Value:
708 
709  None
710 
711 --*/
712 VOID
715  )
716 {
717  PCLASS_PRIVATE_FDO_DATA fdoData = FdoExtension->PrivateFdoData;
718 
719  //
720  // Issue the next idle request if there are any left in the queue, there are
721  // no non-idle requests outstanding, there are less than max idle requests
722  // outstanding, and it has been long enough since the completion of the last
723  // non-idle request.
724  //
725  if ((fdoData->IdleIoCount > 0) &&
726  (fdoData->ActiveIdleIoCount < fdoData->IdleActiveIoMax) &&
727  (fdoData->ActiveIoCount <= 0) &&
728  (ClasspIdleDurationSufficient(fdoData, NULL))) {
729  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspCompleteIdleRequest: Service next idle reqeusts\n"));
731  }
732 
733  return;
734 }
735 
736 /*++
737 
738 ClasspServiceIdleRequest
739 
740 Routine Description:
741 
742  Remove the next pending idle request from the queue and process it.
743  If a request was removed then it will be processed otherwise it will
744  just return.
745 
746 Arguments:
747 
748  FdoExtension - Pointer to the device extension
749  PostToDpc - Flag to pass to ServiceTransferRequest to indicate if request must be posted to a DPC
750 
751 Return Value:
752 
753  None
754 
755 --*/
756 VOID
759  BOOLEAN PostToDpc
760  )
761 {
762  PIRP irp;
763 
765  if (irp != NULL) {
766  ServiceTransferRequest(FdoExtension->DeviceObject, irp, PostToDpc);
767  }
768  return;
769 }
770 
#define CLASS_STARVATION_INTERVAL
Definition: classp.h:1200
#define IN
Definition: typedefs.h:39
#define max(a, b)
Definition: svc.c:63
#define USHORT_MAX
Definition: intsafe.h:145
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
VOID EnqueueDeferredClientIrp(PDEVICE_OBJECT Fdo, PIRP Irp)
Definition: clntirp.c:78
LONG NTSTATUS
Definition: precomp.h:26
KSPIN_LOCK SpinLock
Definition: classp.h:795
#define InterlockedCompareExchange
Definition: interlocked.h:104
BOOLEAN NTAPI KeSetTimerEx(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:294
#define InsertTailList(ListHead, Entry)
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define CLASS_IDLE_INTERVAL_MIN
Definition: classp.h:1198
NTSTATUS ClasspEnqueueIdleRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: clntirp.c:576
VOID ClasspStopIdleTimer(PCLASS_PRIVATE_FDO_DATA FdoData)
Definition: clntirp.c:316
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define CLASSP_REG_SUBKEY_NAME
Definition: cdromp.h:120
#define FALSE
Definition: types.h:117
PIRP ClasspDequeueIdleRequest(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: clntirp.c:654
long LONG
Definition: pedump.c:60
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
LIST_ENTRY IdleIrpList
Definition: classp.h:882
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
__inline ULONGLONG ClasspTimeDiffToMs(ULONGLONG TimeDiff)
Definition: classp.h:1297
LIST_ENTRY DeferredClientIrpList
Definition: classp.h:777
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:511
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
#define CLASSP_REG_IDLE_INTERVAL_NAME
Definition: classp.h:119
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
uint64_t ULONGLONG
Definition: typedefs.h:67
ULONGLONG ClasspGetIdleTime(IN PCLASS_PRIVATE_FDO_DATA FdoData, IN LARGE_INTEGER CurrentTime)
Definition: clntirp.c:351
USHORT StarvationDuration
Definition: classp.h:915
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
__inline LARGE_INTEGER ClasspGetCurrentTime(VOID)
Definition: classp.h:1280
VOID ClasspInitializeIdleTimer(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: clntirp.c:175
#define IO_TYPE_IRP
BOOLEAN IdlePrioritySupported
Definition: classp.h:808
Definition: ketypes.h:687
#define VOID
Definition: acefi.h:82
LOGICAL ClasspIdleDurationSufficient(IN PCLASS_PRIVATE_FDO_DATA FdoData, OUT LARGE_INTEGER **CurrentTimeIn)
Definition: clntirp.c:406
Definition: typedefs.h:119
NTSTATUS ServiceTransferRequest(PDEVICE_OBJECT Fdo, PIRP Irp, BOOLEAN PostToDpc)
Definition: class.c:3341
VOID ClasspStartIdleTimer(IN PCLASS_PRIVATE_FDO_DATA FdoData)
Definition: clntirp.c:261
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
unsigned short USHORT
Definition: pedump.c:61
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
KDEFERRED_ROUTINE ClasspIdleTimerDpc
Definition: clntirp.c:42
VOID ClasspCompleteIdleRequest(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: clntirp.c:713
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define min(a, b)
Definition: monoChain.cc:55
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define OUT
Definition: typedefs.h:40
struct tagContext Context
Definition: acpixf.h:1034
PIRP DequeueDeferredClientIrp(PDEVICE_OBJECT Fdo)
Definition: clntirp.c:113
unsigned int ULONG
Definition: retypes.h:1
LARGE_INTEGER AntiStarvationStartTime
Definition: classp.h:930
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
KSPIN_LOCK IdleListLock
Definition: classp.h:877
IoMarkIrpPending(Irp)
static SERVICE_STATUS status
Definition: service.c:31
VOID ClasspServiceIdleRequest(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN PostToDpc)
Definition: clntirp.c:757
#define CLASS_IDLE_INTERVAL
Definition: classp.h:1199
#define Int32x32To64(a, b)
#define CLASSP_REG_IDLE_PRIORITY_SUPPORTED
Definition: classp.h:121
#define CLASSP_REG_IDLE_ACTIVE_MAX
Definition: classp.h:120
LONGLONG QuadPart
Definition: typedefs.h:114
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97