https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7e36e76d5dd651001685570ff21229d770caea32

commit 7e36e76d5dd651001685570ff21229d770caea32
Author:     Pierre Schweitzer <[email protected]>
AuthorDate: Sat Nov 17 15:25:26 2018 +0100
Commit:     Pierre Schweitzer <[email protected]>
CommitDate: Sat Nov 17 16:44:35 2018 +0100

    [NTOSKRNL] Implement ExfAcquireRundownProtectionCacheAware(), 
ExfReleaseRundownProtectionCacheAware()
---
 ntoskrnl/ex/rundown.c | 53 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 46 insertions(+), 7 deletions(-)

diff --git a/ntoskrnl/ex/rundown.c b/ntoskrnl/ex/rundown.c
index ee1dbadb2b..94a2696286 100644
--- a/ntoskrnl/ex/rundown.c
+++ b/ntoskrnl/ex/rundown.c
@@ -378,15 +378,35 @@ ExfWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REF 
RunRef)
 /* FIXME: STUBS **************************************************************/
 
 /*
- * @unimplemented NT5.2
+ * @implemented NT5.2
  */
 BOOLEAN
 FASTCALL
 ExfAcquireRundownProtectionCacheAware(IN PEX_RUNDOWN_REF_CACHE_AWARE 
RunRefCacheAware)
 {
-    DBG_UNREFERENCED_PARAMETER(RunRefCacheAware);
-    UNIMPLEMENTED;
-    return FALSE;
+    ULONG Value;
+    BOOLEAN Acquired;
+    PEX_RUNDOWN_REF RunRef;
+
+    RunRef = (PEX_RUNDOWN_REF)((ULONG_PTR)RunRefCacheAware->RunRefs +
+                               RunRefCacheAware->RunRefSize *
+                               (KeGetCurrentProcessorNumber() % 
RunRefCacheAware->Number));
+
+    /* Get current value */
+    Value = RunRef->Count & !EX_RUNDOWN_ACTIVE;
+    /* Try to acquire the quick way if already active */
+    if (ExpChangeRundown(RunRef,
+                         ((RunRef->Count & !EX_RUNDOWN_ACTIVE) + 
EX_RUNDOWN_COUNT_INC),
+                         Value) == Value)
+    {
+        Acquired = 1;
+    }
+    else
+    {
+        Acquired = ExfAcquireRundownProtection(RunRef);
+    }
+
+    return Acquired;
 }
 
 /*
@@ -404,14 +424,33 @@ ExfAcquireRundownProtectionCacheAwareEx(IN 
PEX_RUNDOWN_REF_CACHE_AWARE RunRefCac
 }
 
 /*
- * @unimplemented NT5.2
+ * @implemented NT5.2
  */
 VOID
 FASTCALL
 ExfReleaseRundownProtectionCacheAware(IN PEX_RUNDOWN_REF_CACHE_AWARE 
RunRefCacheAware)
 {
-    DBG_UNREFERENCED_PARAMETER(RunRefCacheAware);
-    UNIMPLEMENTED;
+    ULONG Value;
+    PEX_RUNDOWN_REF RunRef;
+
+    RunRef = (PEX_RUNDOWN_REF)((ULONG_PTR)RunRefCacheAware->RunRefs +
+                               RunRefCacheAware->RunRefSize *
+                               (KeGetCurrentProcessorNumber() % 
RunRefCacheAware->Number));
+
+    /* Get current value */
+    Value = RunRef->Count & !EX_RUNDOWN_ACTIVE;
+    /* Try to release the quick way if multiple actived */
+    if (ExpChangeRundown(RunRef,
+                         ((RunRef->Count & !EX_RUNDOWN_ACTIVE) - 
EX_RUNDOWN_COUNT_INC),
+                         Value) == Value)
+    {
+        /* Sanity check */
+        ASSERT((Value >= EX_RUNDOWN_COUNT_INC) || (KeNumberProcessors > 1));
+    }
+    else
+    {
+        ExfReleaseRundownProtection(RunRef);
+    }
 }
 
 /*

Reply via email to