diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index e8945ff3b59..a23b2c22c38 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -101,6 +101,10 @@ KeGetPreviousMode(VOID) } \ } +VOID +NTAPI +Kii386SpinOnSpinLock(PKSPIN_LOCK SpinLock, ULONG Flags); + #ifndef CONFIG_SMP // // Spinlock Acquire at IRQL >= DISPATCH_LEVEL @@ -310,44 +314,34 @@ FORCEINLINE VOID KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock) { +#ifdef 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 - /* Start acquire loop */ - for (;;) + /* Try to acquire the lock */ + while (InterlockedBitTestAndSet((PLONG)SpinLock, 0)) { - /* Try to acquire it */ - if (InterlockedBitTestAndSet((PLONG)SpinLock, 0)) - { - /* Value changed... wait until it's unlocked */ - while (*(volatile KSPIN_LOCK *)SpinLock == 1) - { -#if DBG - /* On debug builds, we use a much slower but useful routine */ - //Kii386SpinOnSpinLock(SpinLock, 5); - - /* FIXME: Do normal yield for now */ - YieldProcessor(); +#if defined(_M_IX86) && defined(DBG) + /* On x86 debug builds, we use a much slower but useful routine */ + Kii386SpinOnSpinLock(SpinLock, 5); #else - /* Otherwise, just yield and keep looping */ - YieldProcessor(); -#endif - } - } - else + /* It's locked... spin until it's unlocked */ + while (*(volatile KSPIN_LOCK *)SpinLock & 1) { -#if DBG - /* On debug builds, we OR in the KTHREAD */ - *SpinLock = (KSPIN_LOCK)KeGetCurrentThread() | 1; -#endif - /* All is well, break out */ - break; + /* Yield and keep looping */ + YieldProcessor(); } +#endif } +#ifdef DBG + /* On debug builds, we OR in the KTHREAD */ + *SpinLock = (KSPIN_LOCK)KeGetCurrentThread() | 1; +#endif } // diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index c8458c387ed..df49ea0f003 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -2828,31 +2828,3 @@ _KeSynchronizeExecution@12: ret 12 .endfunc -/*++ - * Kii386SpinOnSpinLock - * - * FILLMEIN - * - * Params: - * SpinLock - FILLMEIN - * - * Flags - FILLMEIN - * - * Returns: - * None. - * - * Remarks: - * FILLMEIN - * - *--*/ -.globl _Kii386SpinOnSpinLock@8 -.func Kii386SpinOnSpinLock@8 -_Kii386SpinOnSpinLock@8: - -#ifdef CONFIG_SMP - /* FIXME: TODO */ - int 3 -#endif - - ret 8 -.endfunc diff --git a/reactos/ntoskrnl/ke/spinlock.c b/reactos/ntoskrnl/ke/spinlock.c index 399800b53c7..0a98b330fd0 100644 --- a/reactos/ntoskrnl/ke/spinlock.c +++ b/reactos/ntoskrnl/ke/spinlock.c @@ -454,3 +454,22 @@ KeTestSpinLock(IN PKSPIN_LOCK SpinLock) /* Spinlock appears to be free */ return TRUE; } + +#ifdef _M_IX86 +VOID +NTAPI +Kii386SpinOnSpinLock(PKSPIN_LOCK SpinLock, ULONG Flags) +{ + // FIXME: Handle flags + UNREFERENCED_PARAMETER(Flags); + + /* Spin until it's unlocked */ + while (*(volatile KSPIN_LOCK *)SpinLock & 1) + { + // FIXME: Check for timeout + + /* Yield and keep looping */ + YieldProcessor(); + } +} +#endif