mirror of
https://github.com/reactos/reactos.git
synced 2025-06-05 01:10:26 +00:00
[NTOSKRNL] Implement ExfWaitForRundownProtectionReleaseCacheAware()
This commit is contained in:
parent
acdf74aa3b
commit
7e849470af
1 changed files with 63 additions and 3 deletions
|
@ -433,14 +433,74 @@ ExfReleaseRundownProtectionCacheAwareEx(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCac
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented NT5.2
|
* @implemented NT5.2
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ExfWaitForRundownProtectionReleaseCacheAware(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware)
|
ExfWaitForRundownProtectionReleaseCacheAware(IN PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware)
|
||||||
{
|
{
|
||||||
DBG_UNREFERENCED_PARAMETER(RunRefCacheAware);
|
PEX_RUNDOWN_REF RunRef;
|
||||||
UNIMPLEMENTED;
|
EX_RUNDOWN_WAIT_BLOCK WaitBlock;
|
||||||
|
PEX_RUNDOWN_WAIT_BLOCK WaitBlockPointer;
|
||||||
|
ULONG ProcCount, Current, Value, OldValue, TotalCount;
|
||||||
|
|
||||||
|
ProcCount = RunRefCacheAware->Number;
|
||||||
|
/* No proc, nothing to do */
|
||||||
|
if (ProcCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TotalCount = 0;
|
||||||
|
WaitBlock.Count = 0;
|
||||||
|
WaitBlockPointer = (PEX_RUNDOWN_WAIT_BLOCK)((ULONG_PTR)&WaitBlock |
|
||||||
|
EX_RUNDOWN_ACTIVE);
|
||||||
|
/* We will check all our runrefs */
|
||||||
|
for (Current = 0; Current < ProcCount; ++Current)
|
||||||
|
{
|
||||||
|
/* Get the runref for the proc */
|
||||||
|
RunRef = (PEX_RUNDOWN_REF)((ULONG_PTR)RunRefCacheAware->RunRefs +
|
||||||
|
RunRefCacheAware->RunRefSize *
|
||||||
|
(Current % RunRefCacheAware->Number));
|
||||||
|
|
||||||
|
/* Loop for setting the wait block */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Value = RunRef->Count;
|
||||||
|
ASSERT((Value & EX_RUNDOWN_ACTIVE) == 0);
|
||||||
|
|
||||||
|
/* Remove old value and set our waitblock instead */
|
||||||
|
OldValue = ExpChangeRundown(RunRef, WaitBlockPointer, Value);
|
||||||
|
if (OldValue == Value)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value = OldValue;
|
||||||
|
}
|
||||||
|
while (TRUE);
|
||||||
|
|
||||||
|
/* Count the deleted values */
|
||||||
|
TotalCount += Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity check: we didn't overflow */
|
||||||
|
ASSERT((LONG)TotalCount >= 0);
|
||||||
|
if (TotalCount != 0)
|
||||||
|
{
|
||||||
|
/* Init the waitblock event */
|
||||||
|
KeInitializeEvent(&WaitBlock.WakeEvent,
|
||||||
|
SynchronizationEvent,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
/* Do we have to wait? If so, go ahead! */
|
||||||
|
if (InterlockedExchangeAddSizeT(&WaitBlock.Count,
|
||||||
|
(LONG)TotalCount >> EX_RUNDOWN_COUNT_SHIFT) ==
|
||||||
|
-(LONG)(TotalCount >> EX_RUNDOWN_COUNT_SHIFT))
|
||||||
|
{
|
||||||
|
KeWaitForSingleObject(&WaitBlock.WakeEvent, Executive, KernelMode, FALSE, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue