From: Timo Kreuzer Date: Thu, 21 Jan 2010 22:34:01 +0000 (+0000) Subject: Merge from amd64-branch: X-Git-Tag: backups/aicom-network-stable@46924^3~56 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=f4519c0c43d81583f5562424347e43758372d13a;hp=36d8d87a11ecaff11c43c03f9cfda2238924818c Merge from amd64-branch: 44886 KxAcquireSpinLock: check for already owned lock only on debug builds, fix check in inner loop, don't call Kii386SpinOnSpinLock inside the inner loop, but instead of it, simplify the code. Stubplement Kii386SpinOnSpinLock in C 44893 Move spinlock inline functions into their own header, so they can be shared with hal. svn path=/trunk/; revision=45196 --- diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index d7861839be5..2c05bfe25bf 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -102,27 +102,6 @@ KeGetPreviousMode(VOID) } #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); -} - -// -// 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); -} // // This routine protects against multiple CPU acquires, it's meaningless on UP. @@ -303,72 +282,6 @@ KiReleaseTimerLock(IN PKSPIN_LOCK_QUEUE LockQueue) #else -// -// Spinlock Acquisition at IRQL >= DISPATCH_LEVEL -// -FORCEINLINE -VOID -KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock) -{ - /* 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); - } - - /* Start acquire loop */ - for (;;) - { - /* 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(); -#else - /* Otherwise, just yield and keep looping */ - YieldProcessor(); -#endif - } - } - else - { -#if DBG - /* On debug builds, we OR in the KTHREAD */ - *SpinLock = (KSPIN_LOCK)KeGetCurrentThread() | 1; -#endif - /* All is well, break out */ - break; - } - } -} - -// -// Spinlock Release at IRQL >= DISPATCH_LEVEL -// -FORCEINLINE -VOID -KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock) -{ -#if DBG - /* Make sure that the threads match */ - if (((KSPIN_LOCK)KeGetCurrentThread() | 1) != *SpinLock) - { - /* They don't, bugcheck */ - KeBugCheckEx(SPIN_LOCK_NOT_OWNED, (ULONG_PTR)SpinLock, 0, 0, 0); - } -#endif - /* Clear the lock */ - InterlockedAnd((PLONG)SpinLock, 0); -} - FORCEINLINE VOID KiAcquireDispatcherObject(IN DISPATCHER_HEADER* Object) diff --git a/reactos/ntoskrnl/include/internal/ntoskrnl.h b/reactos/ntoskrnl/include/internal/ntoskrnl.h index d85c8b61b3a..0823f1d229a 100644 --- a/reactos/ntoskrnl/include/internal/ntoskrnl.h +++ b/reactos/ntoskrnl/include/internal/ntoskrnl.h @@ -83,6 +83,7 @@ #include "../kdbg/kdb.h" #endif #include "dbgk.h" +#include "spinlock.h" #include "tag.h" #include "test.h" #include "inbv.h" diff --git a/reactos/ntoskrnl/include/internal/spinlock.h b/reactos/ntoskrnl/include/internal/spinlock.h new file mode 100644 index 00000000000..6d1ca71c231 --- /dev/null +++ b/reactos/ntoskrnl/include/internal/spinlock.h @@ -0,0 +1,95 @@ +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/include/spinlock.h +* PURPOSE: Internal Inlined Functions for spinlocks, shared with HAL +* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +*/ + +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); +} + +// +// 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); +} + +#else + +// +// Spinlock Acquisition at IRQL >= DISPATCH_LEVEL +// +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 + + /* Try to acquire the lock */ + while (InterlockedBitTestAndSet((PLONG)SpinLock, 0)) + { +#if defined(_M_IX86) && defined(DBG) + /* On x86 debug builds, we use a much slower but useful routine */ + Kii386SpinOnSpinLock(SpinLock, 5); +#else + /* It's locked... spin until it's unlocked */ + while (*(volatile KSPIN_LOCK *)SpinLock & 1) + { + /* Yield and keep looping */ + YieldProcessor(); + } +#endif + } +#ifdef DBG + /* On debug builds, we OR in the KTHREAD */ + *SpinLock = (KSPIN_LOCK)KeGetCurrentThread() | 1; +#endif +} + +// +// Spinlock Release at IRQL >= DISPATCH_LEVEL +// +FORCEINLINE +VOID +KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock) +{ +#if DBG + /* Make sure that the threads match */ + if (((KSPIN_LOCK)KeGetCurrentThread() | 1) != *SpinLock) + { + /* They don't, bugcheck */ + KeBugCheckEx(SPIN_LOCK_NOT_OWNED, (ULONG_PTR)SpinLock, 0, 0, 0); + } +#endif + /* Clear the lock */ + InterlockedAnd((PLONG)SpinLock, 0); +} + +#endif diff --git a/reactos/ntoskrnl/ke/spinlock.c b/reactos/ntoskrnl/ke/spinlock.c index abe31b27491..0a98b330fd0 100644 --- a/reactos/ntoskrnl/ke/spinlock.c +++ b/reactos/ntoskrnl/ke/spinlock.c @@ -456,15 +456,20 @@ KeTestSpinLock(IN PKSPIN_LOCK SpinLock) } #ifdef _M_IX86 -/* - * @unimplemented - */ VOID NTAPI -Kii386SpinOnSpinLock(IN PKSPIN_LOCK SpinLock, - IN ULONG Flags) +Kii386SpinOnSpinLock(PKSPIN_LOCK SpinLock, ULONG Flags) { - UNIMPLEMENTED; - while (TRUE); + // 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