1 /* $Id: spinlock.c,v 1.12 2002/09/07 15:12:57 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 ****************************************************************/
22 #include <internal/debug.h>
25 /* 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 KeAcquireSpinLockAtDpcLevel(Interrupt
->IrqLock
);
48 ret
= SynchronizeRoutine(SynchronizeContext
);
50 KeReleaseSpinLockFromDpcLevel(Interrupt
->IrqLock
);
57 KeInitializeSpinLock (PKSPIN_LOCK SpinLock
)
59 * FUNCTION: Initalizes a spinlock
61 * SpinLock = Caller supplied storage for the spinlock
68 KefAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock
)
70 * FUNCTION: Acquires a spinlock when the caller is already running at
73 * SpinLock = Spinlock to acquire
79 * FIXME: This depends on gcc assembling this test to a single load from
80 * the spinlock's value.
82 if ((ULONG
)*SpinLock
>= 2)
84 DbgPrint("Lock %x has bad value %x\n", SpinLock
, *SpinLock
);
88 while ((i
= InterlockedExchange(SpinLock
, 1)) == 1)
91 DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock
, i
);
94 /* Avoid reading the value again too fast */
99 #undef KeAcquireSpinLockAtDpcLevel
102 KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock
)
104 * FUNCTION: Acquires a spinlock when the caller is already running at
107 * SpinLock = Spinlock to acquire
110 KefAcquireSpinLockAtDpcLevel (SpinLock
);
114 KefReleaseSpinLockFromDpcLevel (PKSPIN_LOCK SpinLock
)
116 * FUNCTION: Releases a spinlock when the caller was running at dispatch
117 * level before acquiring it
119 * SpinLock = Spinlock to release
124 DbgPrint("Releasing unacquired spinlock %x\n", SpinLock
);
127 (void)InterlockedExchange(SpinLock
, 0);
130 #undef KeReleaseSpinLockFromDpcLevel
133 KeReleaseSpinLockFromDpcLevel (PKSPIN_LOCK SpinLock
)
135 * FUNCTION: Releases a spinlock when the caller was running at dispatch
136 * level before acquiring it
138 * SpinLock = Spinlock to release
141 KefReleaseSpinLockFromDpcLevel (SpinLock
);