ReactOS  0.4.14-dev-358-gbef841c
rundown.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Kernel
4  * FILE: ntoskrnl/ex/rundown.c
5  * PURPOSE: Rundown and Cache-Aware Rundown Protection
6  * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7  * Thomas Weidenmueller
8  * Pierre Schweitzer
9  */
10 
11 /* INCLUDES *****************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* FUNCTIONS *****************************************************************/
18 
19 /*++
20  * @name ExfAcquireRundownProtection
21  * @implemented NT5.1
22  *
23  * The ExfAcquireRundownProtection routine acquires rundown protection for
24  * the specified descriptor.
25  *
26  * @param RunRef
27  * Pointer to a rundown reference descriptor.
28  *
29  * @return TRUE if access to the protected structure was granted, FALSE otherwise.
30  *
31  * @remarks Callers of ExfAcquireRundownProtection can be running at any IRQL.
32  *
33  *--*/
34 BOOLEAN
37 {
38  ULONG_PTR Value = RunRef->Count, NewValue;
39 
40  /* Loop until successfully incremented the counter */
41  for (;;)
42  {
43  /* Make sure a rundown is not active */
44  if (Value & EX_RUNDOWN_ACTIVE) return FALSE;
45 
46  /* Add a reference */
47  NewValue = Value + EX_RUNDOWN_COUNT_INC;
48 
49  /* Change the value */
50  NewValue = ExpChangeRundown(RunRef, NewValue, Value);
51  if (NewValue == Value) return TRUE;
52 
53  /* Update it */
54  Value = NewValue;
55  }
56 }
57 
58 /*++
59  * @name ExfAcquireRundownProtectionEx
60  * @implemented NT5.2
61  *
62  * The ExfAcquireRundownProtectionEx routine acquires multiple rundown
63  * protection references for the specified descriptor.
64  *
65  * @param RunRef
66  * Pointer to a rundown reference descriptor.
67  *
68  * @param Count
69  * Number of times to reference the descriptor.
70  *
71  * @return TRUE if access to the protected structure was granted, FALSE otherwise.
72  *
73  * @remarks Callers of ExfAcquireRundownProtectionEx can be running at any IRQL.
74  *
75  *--*/
76 BOOLEAN
79  IN ULONG Count)
80 {
81  ULONG_PTR Value = RunRef->Count, NewValue;
82 
83  /* Loop until successfully incremented the counter */
84  for (;;)
85  {
86  /* Make sure a rundown is not active */
87  if (Value & EX_RUNDOWN_ACTIVE) return FALSE;
88 
89  /* Add references */
90  NewValue = Value + EX_RUNDOWN_COUNT_INC * Count;
91 
92  /* Change the value */
93  NewValue = ExpChangeRundown(RunRef, NewValue, Value);
94  if (NewValue == Value) return TRUE;
95 
96  /* Update the value */
97  Value = NewValue;
98  }
99 }
100 
101 /*++
102  * @name ExfInitializeRundownProtection
103  * @implemented NT5.1
104  *
105  * The ExfInitializeRundownProtection routine initializes a rundown
106  * protection descriptor.
107  *
108  * @param RunRef
109  * Pointer to a rundown reference descriptor.
110  *
111  * @return None.
112  *
113  * @remarks Callers of ExfInitializeRundownProtection can be running at any IRQL.
114  *
115  *--*/
116 VOID
117 FASTCALL
119 {
120  /* Set the count to zero */
121  RunRef->Count = 0;
122 }
123 
124 /*++
125  * @name ExfReInitializeRundownProtection
126  * @implemented NT5.1
127  *
128  * The ExfReInitializeRundownProtection routine re-initializes a rundown
129  * protection descriptor.
130  *
131  * @param RunRef
132  * Pointer to a rundown reference descriptor.
133  *
134  * @return None.
135  *
136  * @remarks Callers of ExfReInitializeRundownProtection can be running at any IRQL.
137  *
138  *--*/
139 VOID
140 FASTCALL
142 {
143  PAGED_CODE();
144 
145  /* Sanity check */
146  ASSERT((RunRef->Count & EX_RUNDOWN_ACTIVE) != 0);
147 
148  /* Reset the count */
149  ExpSetRundown(RunRef, 0);
150 }
151 
152 /*++
153  * @name ExfRundownCompleted
154  * @implemented NT5.1
155  *
156  * The ExfRundownCompleted routine completes the rundown of the specified
157  * descriptor by setting the active bit.
158  *
159  * @param RunRef
160  * Pointer to a rundown reference descriptor.
161  *
162  * @return None.
163  *
164  * @remarks Callers of ExfRundownCompleted must be running at IRQL <= APC_LEVEL.
165  *
166  *--*/
167 VOID
168 FASTCALL
170 {
171  PAGED_CODE();
172 
173  /* Sanity check */
174  ASSERT((RunRef->Count & EX_RUNDOWN_ACTIVE) != 0);
175 
176  /* Mark the counter as active */
178 }
179 
180 /*++
181  * @name ExfReleaseRundownProtection
182  * @implemented NT5.1
183  *
184  * The ExfReleaseRundownProtection routine releases the rundown protection
185  * reference for the specified descriptor.
186  *
187  * @param RunRef
188  * Pointer to a rundown reference descriptor.
189  *
190  * @return None.
191  *
192  * @remarks Callers of ExfReleaseRundownProtection can be running at any IRQL.
193  *
194  *--*/
195 VOID
196 FASTCALL
198 {
199  ULONG_PTR Value = RunRef->Count, NewValue;
200  PEX_RUNDOWN_WAIT_BLOCK WaitBlock;
201 
202  /* Loop until successfully incremented the counter */
203  for (;;)
204  {
205  /* Check if rundown is not active */
206  if (!(Value & EX_RUNDOWN_ACTIVE))
207  {
208  /* Sanity check */
210 
211  /* Get the new value */
212  NewValue = Value - EX_RUNDOWN_COUNT_INC;
213 
214  /* Change the value */
215  NewValue = ExpChangeRundown(RunRef, NewValue, Value);
216  if (NewValue == Value) break;
217 
218  /* Update value */
219  Value = NewValue;
220  }
221  else
222  {
223  /* Get the wait block */
225  ASSERT((WaitBlock->Count > 0) || (KeNumberProcessors > 1));
226 
227  /* Remove the one count */
228  if (!InterlockedDecrementSizeT(&WaitBlock->Count))
229  {
230  /* We're down to 0 now, so signal the event */
231  KeSetEvent(&WaitBlock->WakeEvent, IO_NO_INCREMENT, FALSE);
232  }
233 
234  /* We're all done */
235  break;
236  }
237  }
238 }
239 
240 /*++
241  * @name ExfReleaseRundownProtectionEx
242  * @implemented NT5.2
243  *
244  * The ExfReleaseRundownProtectionEx routine releases multiple rundown
245  * protection references for the specified descriptor.
246  *
247  * @param RunRef
248  * Pointer to a rundown reference descriptor.
249  *
250  * @param Count
251  * Number of times to dereference the descriptor.
252  *
253  * @return None.
254  *
255  * @remarks Callers of ExfAcquireRundownProtectionEx can be running at any IRQL.
256  *
257  *--*/
258 VOID
259 FASTCALL
261  IN ULONG Count)
262 {
263  ULONG_PTR Value = RunRef->Count, NewValue;
264  PEX_RUNDOWN_WAIT_BLOCK WaitBlock;
265 
266  /* Loop until successfully incremented the counter */
267  for (;;)
268  {
269  /* Check if rundown is not active */
270  if (!(Value & EX_RUNDOWN_ACTIVE))
271  {
272  /* Sanity check */
274  (KeNumberProcessors > 1));
275 
276  /* Get the new value */
277  NewValue = Value - EX_RUNDOWN_COUNT_INC * Count;
278 
279  /* Change the value */
280  NewValue = ExpChangeRundown(RunRef, NewValue, Value);
281  if (NewValue == Value) break;
282 
283  /* Update value */
284  Value = NewValue;
285  }
286  else
287  {
288  /* Get the wait block */
290  ASSERT((WaitBlock->Count >= Count) || (KeNumberProcessors > 1));
291 
292  /* Remove the counts */
293  if (InterlockedExchangeAddSizeT(&WaitBlock->Count,
294  -(LONG)Count) == (LONG)Count)
295  {
296  /* We're down to 0 now, so signal the event */
297  KeSetEvent(&WaitBlock->WakeEvent, IO_NO_INCREMENT, FALSE);
298  }
299 
300  /* We're all done */
301  break;
302  }
303  }
304 }
305 
306 /*++
307  * @name ExfWaitForRundownProtectionRelease
308  * @implemented NT5.1
309  *
310  * The ExfWaitForRundownProtectionRelease routine waits until the specified
311  * rundown descriptor has been released.
312  *
313  * @param RunRef
314  * Pointer to a rundown reference descriptor.
315  *
316  * @return None.
317  *
318  * @remarks Callers of ExfWaitForRundownProtectionRelease must be running
319  * at IRQL <= APC_LEVEL.
320  *
321  *--*/
322 VOID
323 FASTCALL
325 {
326  ULONG_PTR Value, Count, NewValue;
327  EX_RUNDOWN_WAIT_BLOCK WaitBlock;
328  PEX_RUNDOWN_WAIT_BLOCK WaitBlockPointer;
329  PKEVENT Event;
330  PAGED_CODE();
331 
332  /* Set the active bit */
334  if ((Value == 0) || (Value == EX_RUNDOWN_ACTIVE)) return;
335 
336  /* No event for now */
337  Event = NULL;
338  WaitBlockPointer = (PEX_RUNDOWN_WAIT_BLOCK)((ULONG_PTR)&WaitBlock |
340 
341  /* Start waitblock set loop */
342  for (;;)
343  {
344  /* Save the count */
346 
347  /* If the count is over one and we don't have en event yet, create it */
348  if ((Count) && !(Event))
349  {
350  /* Initialize the event */
351  KeInitializeEvent(&WaitBlock.WakeEvent,
353  FALSE);
354 
355  /* Set the pointer */
356  Event = &WaitBlock.WakeEvent;
357  }
358 
359  /* Set the count */
360  WaitBlock.Count = Count;
361 
362  /* Now set the pointer */
363  NewValue = ExpChangeRundown(RunRef, (ULONG_PTR)WaitBlockPointer, Value);
364  if (NewValue == Value) break;
365 
366  /* Loop again */
367  Value = NewValue;
368  ASSERT((Value & EX_RUNDOWN_ACTIVE) == 0);
369  }
370 
371  /* If the count was 0, we're done */
372  if (!Count) return;
373 
374  /* Wait for whoever needs to release to notify us */
376  ASSERT(WaitBlock.Count == 0);
377 }
378 
379 /*
380  * @implemented NT5.2
381  */
382 BOOLEAN
383 FASTCALL
385 {
386  PEX_RUNDOWN_REF RunRef;
387 
388  RunRef = ExGetRunRefForGivenProcessor(RunRefCacheAware, KeGetCurrentProcessorNumber());
389  return _ExAcquireRundownProtection(RunRef);
390 }
391 
392 /*
393  * @implemented NT5.2
394  */
395 BOOLEAN
396 FASTCALL
398  IN ULONG Count)
399 {
400  PEX_RUNDOWN_REF RunRef;
401 
402  RunRef = ExGetRunRefForGivenProcessor(RunRefCacheAware, KeGetCurrentProcessorNumber());
403  return ExfAcquireRundownProtectionEx(RunRef, Count);
404 }
405 
406 /*
407  * @implemented NT5.2
408  */
409 VOID
410 FASTCALL
412 {
413  PEX_RUNDOWN_REF RunRef;
414 
415  RunRef = ExGetRunRefForGivenProcessor(RunRefCacheAware, KeGetCurrentProcessorNumber());
417 }
418 
419 /*
420  * @implemented NT5.2
421  */
422 VOID
423 FASTCALL
425  IN ULONG Count)
426 {
427  PEX_RUNDOWN_REF RunRef;
428 
429  RunRef = ExGetRunRefForGivenProcessor(RunRefCacheAware, KeGetCurrentProcessorNumber());
431 }
432 
433 /*
434  * @implemented NT5.2
435  */
436 VOID
437 FASTCALL
439 {
440  PEX_RUNDOWN_REF RunRef;
441  EX_RUNDOWN_WAIT_BLOCK WaitBlock;
442  PEX_RUNDOWN_WAIT_BLOCK WaitBlockPointer;
443  ULONG_PTR ProcCount, Current, Value, OldValue, TotalCount;
444 
445  ProcCount = RunRefCacheAware->Number;
446  /* No proc, nothing to do */
447  if (ProcCount == 0)
448  {
449  return;
450  }
451 
452  TotalCount = 0;
453  WaitBlock.Count = 0;
454  WaitBlockPointer = (PEX_RUNDOWN_WAIT_BLOCK)((ULONG_PTR)&WaitBlock |
456  /* We will check all our runrefs */
457  for (Current = 0; Current < ProcCount; ++Current)
458  {
459  /* Get the runref for the proc */
460  RunRef = ExGetRunRefForGivenProcessor(RunRefCacheAware, Current);
461  /* Loop for setting the wait block */
462  do
463  {
464  Value = RunRef->Count;
465  ASSERT((Value & EX_RUNDOWN_ACTIVE) == 0);
466 
467  /* Remove old value and set our waitblock instead */
468  OldValue = ExpChangeRundown(RunRef, WaitBlockPointer, Value);
469  if (OldValue == Value)
470  {
471  break;
472  }
473 
474  Value = OldValue;
475  }
476  while (TRUE);
477 
478  /* Count the deleted values */
479  TotalCount += Value;
480  }
481 
482  /* Sanity check: we didn't overflow */
483  ASSERT((LONG_PTR)TotalCount >= 0);
484  if (TotalCount != 0)
485  {
486  /* Init the waitblock event */
487  KeInitializeEvent(&WaitBlock.WakeEvent,
489  FALSE);
490 
491  /* Do we have to wait? If so, go ahead! */
492  if (InterlockedExchangeAddSizeT(&WaitBlock.Count,
493  (LONG_PTR)TotalCount >> EX_RUNDOWN_COUNT_SHIFT) ==
494  -(LONG_PTR)(TotalCount >> EX_RUNDOWN_COUNT_SHIFT))
495  {
497  }
498  }
499 }
500 
501 /*
502  * @implemented NT5.2
503  */
504 VOID
505 FASTCALL
507 {
508  PEX_RUNDOWN_REF RunRef;
509  ULONG ProcCount, Current;
510 
511  ProcCount = RunRefCacheAware->Number;
512  /* No proc, nothing to do */
513  if (ProcCount == 0)
514  {
515  return;
516  }
517 
518  /* We will mark all our runrefs active */
519  for (Current = 0; Current < ProcCount; ++Current)
520  {
521  /* Get the runref for the proc */
522  RunRef = ExGetRunRefForGivenProcessor(RunRefCacheAware, Current);
523  ASSERT((RunRef->Count & EX_RUNDOWN_ACTIVE) != 0);
524 
526  }
527 }
528 
529 /*
530  * @implemented NT5.2
531  */
532 VOID
533 FASTCALL
535 {
536  PEX_RUNDOWN_REF RunRef;
537  ULONG ProcCount, Current;
538 
539  ProcCount = RunRefCacheAware->Number;
540  /* No proc, nothing to do */
541  if (ProcCount == 0)
542  {
543  return;
544  }
545 
546  /* We will mark all our runrefs inactive */
547  for (Current = 0; Current < ProcCount; ++Current)
548  {
549  /* Get the runref for the proc */
550  RunRef = ExGetRunRefForGivenProcessor(RunRefCacheAware, Current);
551  ASSERT((RunRef->Count & EX_RUNDOWN_ACTIVE) != 0);
552 
553  ExpSetRundown(RunRef, 0);
554  }
555 }
556 
557 /*
558  * @implemented NT5.2
559  */
561 NTAPI
563  IN ULONG Tag)
564 {
565  PEX_RUNDOWN_REF RunRef;
566  PVOID PoolToFree, RunRefs;
567  ULONG RunRefSize, Count, Align;
568  PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware;
569 
570  PAGED_CODE();
571 
572  /* Allocate the master structure */
573  RunRefCacheAware = ExAllocatePoolWithTag(PoolType, sizeof(EX_RUNDOWN_REF_CACHE_AWARE), Tag);
574  if (RunRefCacheAware == NULL)
575  {
576  return NULL;
577  }
578 
579  /* Compute the size of each runref */
580  RunRefCacheAware->Number = KeNumberProcessors;
581  if (KeNumberProcessors <= 1)
582  {
583  RunRefSize = sizeof(EX_RUNDOWN_REF);
584  }
585  else
586  {
588  RunRefSize = Align;
589  ASSERT((RunRefSize & (RunRefSize - 1)) == 0);
590  }
591 
592  /* It must at least hold a EX_RUNDOWN_REF structure */
593  ASSERT(sizeof(EX_RUNDOWN_REF) <= RunRefSize);
594  RunRefCacheAware->RunRefSize = RunRefSize;
595 
596  /* Allocate our runref pool */
597  PoolToFree = ExAllocatePoolWithTag(PoolType, RunRefSize * RunRefCacheAware->Number, Tag);
598  if (PoolToFree == NULL)
599  {
600  ExFreePoolWithTag(RunRefCacheAware, Tag);
601  return NULL;
602  }
603 
604  /* On SMP, check for alignment */
605  if (RunRefCacheAware->Number > 1 && (ULONG_PTR)PoolToFree & (Align - 1))
606  {
607  /* Not properly aligned, do it again! */
608  ExFreePoolWithTag(PoolToFree, Tag);
609 
610  /* Allocate a bigger buffer to be able to align properly */
611  PoolToFree = ExAllocatePoolWithTag(PoolType, RunRefSize * (RunRefCacheAware->Number + 1), Tag);
612  if (PoolToFree == NULL)
613  {
614  ExFreePoolWithTag(RunRefCacheAware, Tag);
615  return NULL;
616  }
617 
618  RunRefs = (PVOID)ALIGN_UP_BY(PoolToFree, Align);
619  }
620  else
621  {
622  RunRefs = PoolToFree;
623  }
624 
625  RunRefCacheAware->RunRefs = RunRefs;
626  RunRefCacheAware->PoolToFree = PoolToFree;
627 
628  /* And initialize runref */
629  if (RunRefCacheAware->Number != 0)
630  {
631  for (Count = 0; Count < RunRefCacheAware->Number; ++Count)
632  {
633  RunRef = ExGetRunRefForGivenProcessor(RunRefCacheAware, Count);
635  }
636  }
637 
638  return RunRefCacheAware;
639 }
640 
641 /*
642  * @implemented NT5.2
643  */
644 VOID
645 NTAPI
647 {
648  PAGED_CODE();
649 
650  /*
651  * This is to be called for RunRefCacheAware that were allocated with
652  * ExAllocateCacheAwareRundownProtection and not for user-allocated
653  * ones
654  */
655  ASSERT(RunRefCacheAware->PoolToFree != (PVOID)0xBADCA11);
656 
657  /* We don't know the tag that as used for allocation */
658  ExFreePoolWithTag(RunRefCacheAware->PoolToFree, 0);
659  ExFreePoolWithTag(RunRefCacheAware, 0);
660 }
661 
662 /*
663  * @implemented NT5.2
664  */
665 VOID
666 NTAPI
668  IN SIZE_T Size)
669 {
670  PVOID Pool;
671  PEX_RUNDOWN_REF RunRef;
672  ULONG Count, RunRefSize, Align;
673 
674  PAGED_CODE();
675 
676  /* Get the user allocate pool for runrefs */
677  Pool = (PVOID)((ULONG_PTR)RunRefCacheAware + sizeof(EX_RUNDOWN_REF_CACHE_AWARE));
678 
679  /* By default a runref is structure-sized */
680  RunRefSize = sizeof(EX_RUNDOWN_REF);
681 
682  /*
683  * If we just have enough room for a single runref, deduce were on a single
684  * processor machine
685  */
686  if (Size == sizeof(EX_RUNDOWN_REF_CACHE_AWARE) + sizeof(EX_RUNDOWN_REF))
687  {
688  Count = 1;
689  }
690  else
691  {
692  /* Get alignment constraint */
694 
695  /* How many runrefs given the alignment? */
696  RunRefSize = Align;
697  Count = ((Size - sizeof(EX_RUNDOWN_REF_CACHE_AWARE)) / Align) - 1;
698  Pool = (PVOID)ALIGN_UP_BY(Pool, Align);
699  }
700 
701  /* Initialize the structure */
702  RunRefCacheAware->RunRefs = Pool;
703  RunRefCacheAware->RunRefSize = RunRefSize;
704  RunRefCacheAware->Number = Count;
705 
706  /* There is no allocated pool! */
707  RunRefCacheAware->PoolToFree = (PVOID)0xBADCA11u;
708 
709  /* Initialize runref */
710  if (RunRefCacheAware->Number != 0)
711  {
712  for (Count = 0; Count < RunRefCacheAware->Number; ++Count)
713  {
714  RunRef = ExGetRunRefForGivenProcessor(RunRefCacheAware, Count);
716  }
717  }
718 }
719 
720 /*
721  * @implemented NT5.2
722  */
723 SIZE_T
724 NTAPI
726 {
727  SIZE_T Size;
728 
729  PAGED_CODE();
730 
731  /* Compute the needed size for runrefs */
732  if (KeNumberProcessors <= 1)
733  {
734  Size = sizeof(EX_RUNDOWN_REF);
735  }
736  else
737  {
738  /* We +1, to have enough room for alignment */
740  }
741 
742  /* Return total size (master structure and runrefs) */
743  return Size + sizeof(EX_RUNDOWN_REF_CACHE_AWARE);
744 }
745 
FORCEINLINE VOID _ExReleaseRundownProtection(IN PEX_RUNDOWN_REF RunRef)
Definition: ex.h:847
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define ExpSetRundown(x, y)
Definition: ex.h:160
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
volatile ULONG_PTR Count
Definition: extypes.h:181
_In_ SIZE_T RunRefSize
Definition: exfuncs.h:1103
PEX_RUNDOWN_REF RunRefs
Definition: extypes.h:433
FORCEINLINE VOID _ExInitializeRundownProtection(IN PEX_RUNDOWN_REF RunRef)
Definition: ex.h:890
struct _EX_RUNDOWN_REF EX_RUNDOWN_REF
#define EX_RUNDOWN_COUNT_SHIFT
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
VOID FASTCALL ExfWaitForRundownProtectionReleaseCacheAware(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware)
Definition: rundown.c:438
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FASTCALL
Definition: nt_native.h:50
#define EX_RUNDOWN_COUNT_INC
#define PAGED_CODE()
Definition: video.h:57
ULONG NTAPI KeGetRecommendedSharedDataAlignment(VOID)
Definition: cpu.c:471
VOID NTAPI ExFreeCacheAwareRundownProtection(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware)
Definition: rundown.c:646
VOID FASTCALL ExfReleaseRundownProtectionCacheAwareEx(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware, IN ULONG Count)
Definition: rundown.c:424
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:325
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
VOID FASTCALL ExfWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REF RunRef)
Definition: rundown.c:324
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
unsigned char BOOLEAN
VOID NTAPI ExInitializeRundownProtectionCacheAware(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware, IN SIZE_T Size)
Definition: rundown.c:667
smooth NULL
Definition: ftsmooth.c:416
VOID FASTCALL ExfInitializeRundownProtection(IN PEX_RUNDOWN_REF RunRef)
Definition: rundown.c:118
struct _EX_RUNDOWN_REF_CACHE_AWARE EX_RUNDOWN_REF_CACHE_AWARE
void * PVOID
Definition: retypes.h:9
INT POOL_TYPE
Definition: typedefs.h:76
FORCEINLINE BOOLEAN _ExAcquireRundownProtection(IN PEX_RUNDOWN_REF RunRef)
Definition: ex.h:806
SIZE_T NTAPI ExSizeOfRundownProtectionCacheAware(VOID)
Definition: rundown.c:725
#define ExpChangeRundown(x, y, z)
Definition: ex.h:158
Definition: bufpool.h:50
VOID FASTCALL ExfReleaseRundownProtectionEx(IN PEX_RUNDOWN_REF RunRef, IN ULONG Count)
Definition: rundown.c:260
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID FASTCALL ExfReInitializeRundownProtection(IN PEX_RUNDOWN_REF RunRef)
Definition: rundown.c:141
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
BOOLEAN FASTCALL ExfAcquireRundownProtectionCacheAwareEx(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware, IN ULONG Count)
Definition: rundown.c:397
PEX_RUNDOWN_REF_CACHE_AWARE NTAPI ExAllocateCacheAwareRundownProtection(IN POOL_TYPE PoolType, IN ULONG Tag)
Definition: rundown.c:562
VOID FASTCALL ExfReleaseRundownProtection(IN PEX_RUNDOWN_REF RunRef)
Definition: rundown.c:197
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
BOOLEAN FASTCALL ExfAcquireRundownProtection(IN PEX_RUNDOWN_REF RunRef)
Definition: rundown.c:36
ULONG_PTR SIZE_T
Definition: typedefs.h:78
FORCEINLINE PEX_RUNDOWN_REF ExGetRunRefForGivenProcessor(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware, IN ULONG ProcNumber)
Definition: ex.h:779
BOOLEAN FASTCALL ExfAcquireRundownProtectionEx(IN PEX_RUNDOWN_REF RunRef, IN ULONG Count)
Definition: rundown.c:78
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
VOID FASTCALL ExfRundownCompleted(IN PEX_RUNDOWN_REF RunRef)
Definition: rundown.c:169
IN ULONG IN ULONG Tag
Definition: evtlib.h:159
struct _EX_RUNDOWN_WAIT_BLOCK * PEX_RUNDOWN_WAIT_BLOCK
VOID FASTCALL ExfReInitializeRundownProtectionCacheAware(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware)
Definition: rundown.c:534
VOID FASTCALL ExfReleaseRundownProtectionCacheAware(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware)
Definition: rundown.c:411
VOID FASTCALL ExfRundownCompletedCacheAware(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware)
Definition: rundown.c:506
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define ALIGN_UP_BY(size, align)
#define InterlockedDecrementSizeT(a)
Definition: interlocked.h:153
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444
BOOLEAN FASTCALL ExfAcquireRundownProtectionCacheAware(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware)
Definition: rundown.c:384
#define EX_RUNDOWN_ACTIVE