1 /* $Id: spinlock.c,v 1.18 2003/07/21 21:53:51 royce Exp $
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);