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

commit f30136bc79109af5df33526974e24b39353773c7
Author:     Jérôme Gardou <jerome.gar...@reactos.org>
AuthorDate: Thu May 20 10:13:40 2021 +0200
Commit:     Jérôme Gardou <zefk...@users.noreply.github.com>
CommitDate: Tue Jun 29 11:49:20 2021 +0200

    [NTOS:KE] Test spinlock ownership on both UP & MP build
    
    There is no reason not to, and this avoids introducing bugs stupidly.
---
 boot/freeldr/freeldr/arch/i386/ntoskrnl.c |  8 ++++
 ntoskrnl/include/internal/spinlock.h      | 72 ++++++++++++++-----------------
 ntoskrnl/ke/spinlock.c                    | 25 +++++++----
 sdk/lib/crt/crt.cmake                     |  3 +-
 sdk/lib/crt/libcntpr.cmake                |  3 +-
 5 files changed, 62 insertions(+), 49 deletions(-)

diff --git a/boot/freeldr/freeldr/arch/i386/ntoskrnl.c 
b/boot/freeldr/freeldr/arch/i386/ntoskrnl.c
index e44fa770771..4255e5cf0e0 100644
--- a/boot/freeldr/freeldr/arch/i386/ntoskrnl.c
+++ b/boot/freeldr/freeldr/arch/i386/ntoskrnl.c
@@ -28,6 +28,14 @@ FASTCALL
 KefAcquireSpinLockAtDpcLevel(
     IN PKSPIN_LOCK SpinLock)
 {
+#if DBG
+    /* To be on par with HAL/NTOSKRNL */
+#ifdef _M_AMD64
+    *SpinLock = (KSPIN_LOCK)KeGetCurrentThread() | 1;
+#else
+    *SpinLock = (KSPIN_LOCK)(((PKIPCR)KeGetPcr())->PrcbData.CurrentThread) | 1;
+#endif
+#endif
 }
 
 VOID
diff --git a/ntoskrnl/include/internal/spinlock.h 
b/ntoskrnl/include/internal/spinlock.h
index e126dbe0b03..013ad913c34 100644
--- a/ntoskrnl/include/internal/spinlock.h
+++ b/ntoskrnl/include/internal/spinlock.h
@@ -6,50 +6,25 @@
 * PROGRAMMERS:     Alex Ionescu (alex.ione...@reactos.org)
 */
 
+#if defined(_M_IX86)
 VOID
 NTAPI
 Kii386SpinOnSpinLock(PKSPIN_LOCK SpinLock, ULONG Flags);
-
-#ifndef CONFIG_SMP
-
-//
-// Spinlock Acquire at IRQL >= DISPATCH_LEVEL
-//
-FORCEINLINE
-VOID
-KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
-{
-    /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
-    UNREFERENCED_PARAMETER(SpinLock);
-
-    /* Add an explicit memory barrier to prevent the compiler from reordering
-       memory accesses across the borders of spinlocks */
-    KeMemoryBarrierWithoutFence();
-}
-
-//
-// Spinlock Release at IRQL >= DISPATCH_LEVEL
-//
-FORCEINLINE
-VOID
-KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
-{
-    /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
-    UNREFERENCED_PARAMETER(SpinLock);
-
-    /* Add an explicit memory barrier to prevent the compiler from reordering
-       memory accesses across the borders of spinlocks */
-    KeMemoryBarrierWithoutFence();
-}
-
-#else
+#endif
 
 //
 // Spinlock Acquisition at IRQL >= DISPATCH_LEVEL
 //
+_Acquires_nonreentrant_lock_(SpinLock)
 FORCEINLINE
 VOID
-KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
+KxAcquireSpinLock(
+#if defined(CONFIG_SMP) || DBG
+    _Inout_
+#else
+    _Unreferenced_parameter_
+#endif
+    PKSPIN_LOCK SpinLock)
 {
 #if DBG
     /* Make sure that we don't own the lock already */
@@ -60,6 +35,7 @@ KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
     }
 #endif
 
+#ifdef CONFIG_SMP
     /* Try to acquire the lock */
     while (InterlockedBitTestAndSet((PLONG)SpinLock, 0))
     {
@@ -75,6 +51,12 @@ KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
         }
 #endif
     }
+#endif
+
+    /* Add an explicit memory barrier to prevent the compiler from reordering
+       memory accesses across the borders of spinlocks */
+    KeMemoryBarrierWithoutFence();
+
 #if DBG
     /* On debug builds, we OR in the KTHREAD */
     *SpinLock = (KSPIN_LOCK)KeGetCurrentThread() | 1;
@@ -84,9 +66,16 @@ KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
 //
 // Spinlock Release at IRQL >= DISPATCH_LEVEL
 //
+_Releases_nonreentrant_lock_(SpinLock)
 FORCEINLINE
 VOID
-KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
+KxReleaseSpinLock(
+#if defined(CONFIG_SMP) || DBG
+    _Inout_
+#else
+    _Unreferenced_parameter_
+#endif
+    PKSPIN_LOCK SpinLock)
 {
 #if DBG
     /* Make sure that the threads match */
@@ -96,12 +85,17 @@ KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
         KeBugCheckEx(SPIN_LOCK_NOT_OWNED, (ULONG_PTR)SpinLock, 0, 0, 0);
     }
 #endif
-    /* Clear the lock */
+
+#if defined(CONFIG_SMP) || DBG
+    /* Clear the lock  */
 #ifdef _WIN64
     InterlockedAnd64((PLONG64)SpinLock, 0);
 #else
     InterlockedAnd((PLONG)SpinLock, 0);
 #endif
-}
-
 #endif
+
+    /* Add an explicit memory barrier to prevent the compiler from reordering
+       memory accesses across the borders of spinlocks */
+    KeMemoryBarrierWithoutFence();
+}
diff --git a/ntoskrnl/ke/spinlock.c b/ntoskrnl/ke/spinlock.c
index 6648f75e5a9..deb52b85d29 100644
--- a/ntoskrnl/ke/spinlock.c
+++ b/ntoskrnl/ke/spinlock.c
@@ -109,10 +109,10 @@ KeAcquireQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK_QUEUE 
LockHandle)
                      0,
                      0);
     }
+#endif
 
     /* Do the inlined function */
     KxAcquireSpinLock(LockHandle->Lock);
-#endif
 }
 
 VOID
@@ -130,10 +130,10 @@ KeReleaseQueuedSpinLockFromDpcLevel(IN PKSPIN_LOCK_QUEUE 
LockHandle)
                      0,
                      0);
     }
+#endif
 
     /* Do the inlined function */
     KxReleaseSpinLock(LockHandle->Lock);
-#endif
 }
 
 #endif
@@ -302,6 +302,15 @@ BOOLEAN
 FASTCALL
 KeTryToAcquireSpinLockAtDpcLevel(IN OUT PKSPIN_LOCK SpinLock)
 {
+#if DBG
+    /* Make sure that we don't own the lock already */
+    if (((KSPIN_LOCK)KeGetCurrentThread() | 1) == *SpinLock)
+    {
+        /* We do, bugcheck! */
+        KeBugCheckEx(SPIN_LOCK_ALREADY_OWNED, (ULONG_PTR)SpinLock, 0, 0, 0);
+    }
+#endif
+
 #ifdef CONFIG_SMP
     /* Check if it's already acquired */
     if (!(*SpinLock))
@@ -318,11 +327,11 @@ KeTryToAcquireSpinLockAtDpcLevel(IN OUT PKSPIN_LOCK 
SpinLock)
         /* It was already acquired */
         return FALSE;
     }
+#endif
 
 #if DBG
     /* On debug builds, we OR in the KTHREAD */
     *SpinLock = (ULONG_PTR)KeGetCurrentThread() | 1;
-#endif
 #endif
 
     /* All is well, return TRUE */
@@ -337,10 +346,10 @@ FASTCALL
 KeAcquireInStackQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock,
                                          IN PKLOCK_QUEUE_HANDLE LockHandle)
 {
-#ifdef CONFIG_SMP
     /* Set it up properly */
     LockHandle->LockQueue.Next = NULL;
     LockHandle->LockQueue.Lock = SpinLock;
+#ifdef CONFIG_SMP
 #if 0
     KeAcquireQueuedSpinLockAtDpcLevel(LockHandle->LockQueue.Next);
 #else
@@ -354,11 +363,11 @@ KeAcquireInStackQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK 
SpinLock,
                      0,
                      0);
     }
+#endif
+#endif
 
     /* Acquire the lock */
     KxAcquireSpinLock(LockHandle->LockQueue.Lock); // HACK
-#endif
-#endif
 }
 
 /*
@@ -383,11 +392,11 @@ KeReleaseInStackQueuedSpinLockFromDpcLevel(IN 
PKLOCK_QUEUE_HANDLE LockHandle)
                      0,
                      0);
     }
+#endif
+#endif
 
     /* Release the lock */
     KxReleaseSpinLock(LockHandle->LockQueue.Lock); // HACK
-#endif
-#endif
 }
 
 /*
diff --git a/sdk/lib/crt/crt.cmake b/sdk/lib/crt/crt.cmake
index f3b9160a9b5..1090ff33a78 100644
--- a/sdk/lib/crt/crt.cmake
+++ b/sdk/lib/crt/crt.cmake
@@ -117,6 +117,7 @@ list(APPEND CRT_SOURCE
     mem/memcmp.c
     mem/memccpy.c
     mem/memicmp.c
+    mem/memset.c
     misc/__crt_MessageBoxA.c
     misc/amsg.c
     misc/assert.c
@@ -399,7 +400,7 @@ if(ARCH STREQUAL "i386")
         math/i386/fmodf_asm.s
         mem/i386/memchr_asm.s
         mem/i386/memmove_asm.s
-        mem/i386/memset_asm.s
+        # mem/i386/memset_asm.s
         misc/i386/readcr4.S
         setjmp/i386/setjmp.s
         string/i386/strcat_asm.s
diff --git a/sdk/lib/crt/libcntpr.cmake b/sdk/lib/crt/libcntpr.cmake
index 178a18cd704..cff2a2e7286 100644
--- a/sdk/lib/crt/libcntpr.cmake
+++ b/sdk/lib/crt/libcntpr.cmake
@@ -9,6 +9,7 @@ list(APPEND LIBCNTPR_SOURCE
     mem/memccpy.c
     mem/memcmp.c
     mem/memicmp.c
+    mem/memset.c
     misc/fltused.c
     printf/_snprintf.c
     printf/_snwprintf.c
@@ -186,7 +187,7 @@ if(ARCH STREQUAL "i386")
     list(APPEND LIBCNTPR_ASM_SOURCE
         mem/i386/memchr_asm.s
         mem/i386/memmove_asm.s
-        mem/i386/memset_asm.s
+        # mem/i386/memset_asm.s
         string/i386/strcat_asm.s
         string/i386/strchr_asm.s
         string/i386/strcmp_asm.s

Reply via email to