1 /* $Id: spinlock.c,v 1.10 2001/04/26 14:26:22 phreak 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>
20 #include <internal/config.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);