3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ke/spinlock.c
6 * PURPOSE: Implements spinlocks
7 * PROGRAMMER: David Welch (welch@cwcom.net)
13 * NOTE: On a uniprocessor machine spinlocks are implemented by raising
17 /* INCLUDES ****************************************************************/
19 #include <ddk/ntddk.h>
22 #include <internal/debug.h>
24 /* FUNCTIONS ***************************************************************/
30 KeSynchronizeExecution (PKINTERRUPT Interrupt,
31 PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
32 PVOID SynchronizeContext)
34 * FUNCTION: Synchronizes the execution of a given routine with the ISR
35 * of a given interrupt object
37 * Interrupt = Interrupt object to synchronize with
38 * SynchronizeRoutine = Routine to call whose execution is
39 * synchronized with the ISR
40 * SynchronizeContext = Parameter to pass to the synchronized routine
41 * RETURNS: TRUE if the operation succeeded
47 KeRaiseIrql(Interrupt->SynchLevel,&oldlvl);
48 KeAcquireSpinLockAtDpcLevel(Interrupt->IrqLock);
50 ret = SynchronizeRoutine(SynchronizeContext);
52 KeReleaseSpinLockFromDpcLevel(Interrupt->IrqLock);
62 KeInitializeSpinLock (PKSPIN_LOCK SpinLock)
64 * FUNCTION: Initalizes a spinlock
66 * SpinLock = Caller supplied storage for the spinlock
72 #undef KeAcquireSpinLockAtDpcLevel
78 KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock)
80 * FUNCTION: Acquires a spinlock when the caller is already running at
83 * SpinLock = Spinlock to acquire
89 * FIXME: This depends on gcc assembling this test to a single load from
90 * the spinlock's value.
94 DbgPrint("Lock %x has bad value %x\n", SpinLock, *SpinLock);
98 while ((i = InterlockedExchange((LONG *)SpinLock, 1)) == 1)
101 DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i);
104 /* Avoid reading the value again too fast */
109 #undef KeReleaseSpinLockFromDpcLevel
115 KeReleaseSpinLockFromDpcLevel (PKSPIN_LOCK SpinLock)
117 * FUNCTION: Releases a spinlock when the caller was running at dispatch
118 * level before acquiring it
120 * SpinLock = Spinlock to release
125 DbgPrint("Releasing unacquired spinlock %x\n", SpinLock);
128 (void)InterlockedExchange((LONG *)SpinLock, 0);