2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/ke/spinlock.c
5 * PURPOSE: Implements spinlocks
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * David Welch (welch@cwcom.net)
10 /* INCLUDES ****************************************************************/
14 #include <internal/debug.h>
16 #undef KefAcquireSpinLockAtDpcLevel
17 #undef KeAcquireSpinLockAtDpcLevel
18 #undef KefReleaseSpinLockFromDpcLevel
19 #undef KeReleaseSpinLockFromDpcLevel
21 /* FUNCTIONS ***************************************************************/
26 * FUNCTION: Synchronizes the execution of a given routine with the ISR
27 * of a given interrupt object
29 * Interrupt = Interrupt object to synchronize with
30 * SynchronizeRoutine = Routine to call whose execution is
31 * synchronized with the ISR
32 * SynchronizeContext = Parameter to pass to the synchronized routine
33 * RETURNS: TRUE if the operation succeeded
37 KeSynchronizeExecution(PKINTERRUPT Interrupt
,
38 PKSYNCHRONIZE_ROUTINE SynchronizeRoutine
,
39 PVOID SynchronizeContext
)
44 /* Raise IRQL and acquire lock on MP */
45 OldIrql
= KeAcquireInterruptSpinLock(Interrupt
);
47 /* Call the routine */
48 Status
= SynchronizeRoutine(SynchronizeContext
);
50 /* Release lock and lower IRQL */
51 KeReleaseInterruptSpinLock(Interrupt
, OldIrql
);
53 /* Return routine status */
62 KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt
)
67 KeRaiseIrql(Interrupt
->SynchronizeIrql
, &OldIrql
);
69 /* Acquire spinlock on MP */
70 KiAcquireSpinLock(Interrupt
->ActualLock
);
77 * FUNCTION: Initalizes a spinlock
79 * SpinLock = Caller supplied storage for the spinlock
83 KeInitializeSpinLock(PKSPIN_LOCK SpinLock
)
93 KefAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock
)
95 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
96 KiAcquireSpinLock(SpinLock
);
102 * FUNCTION: Acquires a spinlock when the caller is already running at
105 * SpinLock = Spinlock to acquire
109 KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock
)
111 KefAcquireSpinLockAtDpcLevel(SpinLock
);
119 KefReleaseSpinLockFromDpcLevel(PKSPIN_LOCK SpinLock
)
121 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
122 KiReleaseSpinLock(SpinLock
);
128 * FUNCTION: Releases a spinlock when the caller was running at dispatch
129 * level before acquiring it
131 * SpinLock = Spinlock to release
135 KeReleaseSpinLockFromDpcLevel (PKSPIN_LOCK SpinLock
)
137 KefReleaseSpinLockFromDpcLevel(SpinLock
);
145 KiAcquireSpinLock(PKSPIN_LOCK SpinLock
)
150 /* Try to acquire it */
151 if (InterlockedBitTestAndSet((PLONG
)SpinLock
, 0))
153 /* Value changed... wait until it's locked */
154 while (*SpinLock
== 1) YieldProcessor();
158 /* All is well, break out */
162 #endif /* CONFIG_SMP */
170 KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt
,
173 /* Release lock on MP */
174 KiReleaseSpinLock(Interrupt
->ActualLock
);
177 KeLowerIrql(OldIrql
);
185 KiReleaseSpinLock(PKSPIN_LOCK SpinLock
)
188 /* Simply clear it */
198 KeAcquireInStackQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock
,
199 IN PKLOCK_QUEUE_HANDLE LockHandle
)
209 KeReleaseInStackQueuedSpinLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE LockHandle
)