Undo last change removing config.h, which is now correctly auto generated
[reactos.git] / reactos / ntoskrnl / ke / spinlock.c
1 /* $Id: spinlock.c,v 1.10 2001/04/26 14:26:22 phreak Exp $
2 *
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)
8 * UPDATE HISTORY:
9 * 3/6/98: Created
10 */
11
12 /*
13 * NOTE: On a uniprocessor machine spinlocks are implemented by raising
14 * the irq level
15 */
16
17 /* INCLUDES ****************************************************************/
18
19 #include <ddk/ntddk.h>
20 #include <internal/config.h>
21
22 #include <internal/debug.h>
23
24 /* FUNCTIONS ***************************************************************/
25
26 BOOLEAN STDCALL
27 KeSynchronizeExecution (PKINTERRUPT Interrupt,
28 PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
29 PVOID SynchronizeContext)
30 /*
31 * FUNCTION: Synchronizes the execution of a given routine with the ISR
32 * of a given interrupt object
33 * ARGUMENTS:
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
39 */
40 {
41 KIRQL oldlvl;
42 BOOLEAN ret;
43
44 KeRaiseIrql(Interrupt->SynchLevel,&oldlvl);
45 KeAcquireSpinLockAtDpcLevel(Interrupt->IrqLock);
46
47 ret = SynchronizeRoutine(SynchronizeContext);
48
49 KeReleaseSpinLockFromDpcLevel(Interrupt->IrqLock);
50 KeLowerIrql(oldlvl);
51
52 return(ret);
53 }
54
55 VOID STDCALL
56 KeInitializeSpinLock (PKSPIN_LOCK SpinLock)
57 /*
58 * FUNCTION: Initalizes a spinlock
59 * ARGUMENTS:
60 * SpinLock = Caller supplied storage for the spinlock
61 */
62 {
63 SpinLock->Lock = 0;
64 }
65
66 VOID STDCALL
67 KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock)
68 /*
69 * FUNCTION: Acquires a spinlock when the caller is already running at
70 * dispatch level
71 * ARGUMENTS:
72 * SpinLock = Spinlock to acquire
73 */
74 {
75 ULONG i;
76
77 /*
78 * FIXME: This depends on gcc assembling this test to a single load from
79 * the spinlock's value.
80 */
81 if ((ULONG)SpinLock->Lock >= 2)
82 {
83 DbgPrint("Lock %x has bad value %x\n", SpinLock, SpinLock->Lock);
84 KeBugCheck(0);
85 }
86
87 while ((i = InterlockedExchange(&SpinLock->Lock, 1)) == 1)
88 {
89 #ifndef MP
90 DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i);
91 KeBugCheck(0);
92 #else /* not MP */
93 /* Avoid reading the value again too fast */
94 #endif /* MP */
95 }
96 }
97
98 VOID STDCALL
99 KeReleaseSpinLockFromDpcLevel (PKSPIN_LOCK SpinLock)
100 /*
101 * FUNCTION: Releases a spinlock when the caller was running at dispatch
102 * level before acquiring it
103 * ARGUMENTS:
104 * SpinLock = Spinlock to release
105 */
106 {
107 if (SpinLock->Lock != 1)
108 {
109 DbgPrint("Releasing unacquired spinlock %x\n", SpinLock);
110 KeBugCheck(0);
111 }
112 (void)InterlockedExchange(&SpinLock->Lock, 0);
113 }
114
115 /* EOF */