1 /* $Id: spinlock.c,v 1.22 2004/08/15 16:39:05 chorns 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 ****************************************************************/
20 #include <internal/debug.h>
22 /* FUNCTIONS ***************************************************************/
28 KeSynchronizeExecution (PKINTERRUPT Interrupt
,
29 PKSYNCHRONIZE_ROUTINE SynchronizeRoutine
,
30 PVOID SynchronizeContext
)
32 * FUNCTION: Synchronizes the execution of a given routine with the ISR
33 * of a given interrupt object
35 * Interrupt = Interrupt object to synchronize with
36 * SynchronizeRoutine = Routine to call whose execution is
37 * synchronized with the ISR
38 * SynchronizeContext = Parameter to pass to the synchronized routine
39 * RETURNS: TRUE if the operation succeeded
45 KeRaiseIrql(Interrupt
->SynchLevel
, &oldlvl
);
46 KiAcquireSpinLock(Interrupt
->IrqLock
);
48 ret
= SynchronizeRoutine(SynchronizeContext
);
50 KiReleaseSpinLock(Interrupt
->IrqLock
);
61 KeAcquireInterruptSpinLock(
62 IN PKINTERRUPT Interrupt
73 KeInitializeSpinLock (PKSPIN_LOCK SpinLock
)
75 * FUNCTION: Initalizes a spinlock
77 * SpinLock = Caller supplied storage for the spinlock
83 #undef KefAcquireSpinLockAtDpcLevel
89 KefAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock
)
91 assert(KeGetCurrentIrql() == DISPATCH_LEVEL
);
92 KiAcquireSpinLock(SpinLock
);
95 #undef KeAcquireSpinLockAtDpcLevel
101 KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock
)
103 * FUNCTION: Acquires a spinlock when the caller is already running at
106 * SpinLock = Spinlock to acquire
109 KefAcquireSpinLockAtDpcLevel(SpinLock
);
118 KeAcquireInStackQueuedSpinLockAtDpcLevel(
119 IN PKSPIN_LOCK SpinLock
,
120 IN PKLOCK_QUEUE_HANDLE LockHandle
127 #undef KefReleaseSpinLockFromDpcLevel
133 KefReleaseSpinLockFromDpcLevel(PKSPIN_LOCK SpinLock
)
135 assert(KeGetCurrentIrql() == DISPATCH_LEVEL
);
136 KiReleaseSpinLock(SpinLock
);
139 #undef KeReleaseSpinLockFromDpcLevel
145 KeReleaseSpinLockFromDpcLevel (PKSPIN_LOCK SpinLock
)
147 * FUNCTION: Releases a spinlock when the caller was running at dispatch
148 * level before acquiring it
150 * SpinLock = Spinlock to release
153 KefReleaseSpinLockFromDpcLevel(SpinLock
);
161 KeReleaseInStackQueuedSpinLockFromDpcLevel(
162 IN PKLOCK_QUEUE_HANDLE LockHandle
172 KiAcquireSpinLock(PKSPIN_LOCK SpinLock
)
177 * FIXME: This depends on gcc assembling this test to a single load from
178 * the spinlock's value.
182 DbgPrint("Lock %x has bad value %x\n", SpinLock
, *SpinLock
);
186 while ((i
= InterlockedExchange((LONG
*)SpinLock
, 1)) == 1)
189 DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock
, i
);
192 /* Avoid reading the value again too fast */
202 KeReleaseInterruptSpinLock(
203 IN PKINTERRUPT Interrupt
,
214 KiReleaseSpinLock(PKSPIN_LOCK SpinLock
)
218 DbgPrint("Releasing unacquired spinlock %x\n", SpinLock
);
221 (void)InterlockedExchange((LONG
*)SpinLock
, 0);