2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/include/internal/spinlock.h
5 * PURPOSE: Internal Inlined Functions for spinlocks, shared with HAL
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
11 Kii386SpinOnSpinLock(PKSPIN_LOCK SpinLock
, ULONG Flags
);
16 // Spinlock Acquire at IRQL >= DISPATCH_LEVEL
20 KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock
)
22 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
23 UNREFERENCED_PARAMETER(SpinLock
);
25 /* Add an explicit memory barrier to prevent the compiler from reordering
26 memory accesses across the borders of spinlocks */
27 KeMemoryBarrierWithoutFence();
31 // Spinlock Release at IRQL >= DISPATCH_LEVEL
35 KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock
)
37 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
38 UNREFERENCED_PARAMETER(SpinLock
);
40 /* Add an explicit memory barrier to prevent the compiler from reordering
41 memory accesses across the borders of spinlocks */
42 KeMemoryBarrierWithoutFence();
48 // Spinlock Acquisition at IRQL >= DISPATCH_LEVEL
52 KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock
)
55 /* Make sure that we don't own the lock already */
56 if (((KSPIN_LOCK
)KeGetCurrentThread() | 1) == *SpinLock
)
58 /* We do, bugcheck! */
59 KeBugCheckEx(SPIN_LOCK_ALREADY_OWNED
, (ULONG_PTR
)SpinLock
, 0, 0, 0);
63 /* Try to acquire the lock */
64 while (InterlockedBitTestAndSet((PLONG
)SpinLock
, 0))
66 #if defined(_M_IX86) && DBG
67 /* On x86 debug builds, we use a much slower but useful routine */
68 Kii386SpinOnSpinLock(SpinLock
, 5);
70 /* It's locked... spin until it's unlocked */
71 while (*(volatile KSPIN_LOCK
*)SpinLock
& 1)
73 /* Yield and keep looping */
79 /* On debug builds, we OR in the KTHREAD */
80 *SpinLock
= (KSPIN_LOCK
)KeGetCurrentThread() | 1;
85 // Spinlock Release at IRQL >= DISPATCH_LEVEL
89 KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock
)
92 /* Make sure that the threads match */
93 if (((KSPIN_LOCK
)KeGetCurrentThread() | 1) != *SpinLock
)
95 /* They don't, bugcheck */
96 KeBugCheckEx(SPIN_LOCK_NOT_OWNED
, (ULONG_PTR
)SpinLock
, 0, 0, 0);
100 InterlockedAnd((PLONG
)SpinLock
, 0);