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 ***************************************************************/
27 KeSynchronizeExecution (PKINTERRUPT Interrupt,
28 PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
29 PVOID SynchronizeContext)
31 * FUNCTION: Synchronizes the execution of a given routine with the ISR
32 * of a given interrupt object
34 * Interrupt = Interrupt object to synchronize with
35 * SynchronizeRoutine = Routine to call whose execution is
36 * synchronized with the ISR
37 * SynchronizeContext = Parameter to pass to the synchronized routine
38 * RETURNS: TRUE if the operation succeeded
44 KeRaiseIrql(Interrupt->SynchLevel,&oldlvl);
45 KeAcquireSpinLockAtDpcLevel(Interrupt->IrqLock);
47 ret = SynchronizeRoutine(SynchronizeContext);
49 KeReleaseSpinLockFromDpcLevel(Interrupt->IrqLock);
56 KeInitializeSpinLock (PKSPIN_LOCK SpinLock)
58 * FUNCTION: Initalizes a spinlock
60 * SpinLock = Caller supplied storage for the spinlock
67 KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock)
69 * FUNCTION: Acquires a spinlock when the caller is already running at
72 * SpinLock = Spinlock to acquire
78 * FIXME: This depends on gcc assembling this test to a single load from
79 * the spinlock's value.
81 if ((ULONG)SpinLock->Lock >= 2)
83 DbgPrint("Lock %x has bad value %x\n", SpinLock, SpinLock->Lock);
87 while ((i = InterlockedExchange(&SpinLock->Lock, 1)) == 1)
90 DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i);
93 /* Avoid reading the value again too fast */
99 KeReleaseSpinLockFromDpcLevel (PKSPIN_LOCK SpinLock)
101 * FUNCTION: Releases a spinlock when the caller was running at dispatch
102 * level before acquiring it
104 * SpinLock = Spinlock to release
107 if (SpinLock->Lock != 1)
109 DbgPrint("Releasing unacquired spinlock %x\n", SpinLock);
112 (void)InterlockedExchange(&SpinLock->Lock, 0);