while (TRUE); (when something is unimplemented) ---> ASSERT(FALSE); // while (TRUE...
[reactos.git] / reactos / hal / halx86 / generic / spinlock.c
1 /*
2 * PROJECT: ReactOS HAL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: hal/halx86/up/spinlock.c
5 * PURPOSE: Spinlock and Queued Spinlock Support
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 /* This file is compiled twice. Once for UP and once for MP */
12
13 #include <hal.h>
14 #define NDEBUG
15 #include <debug.h>
16
17 #include <internal/spinlock.h>
18
19 #undef KeAcquireSpinLock
20 #undef KeReleaseSpinLock
21
22 /* GLOBALS *******************************************************************/
23
24 ULONG_PTR HalpSystemHardwareFlags;
25 KSPIN_LOCK HalpSystemHardwareLock;
26
27 /* FUNCTIONS *****************************************************************/
28
29 #ifdef _M_IX86
30
31 /*
32 * @implemented
33 */
34 KIRQL
35 FASTCALL
36 KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock)
37 {
38 KIRQL OldIrql;
39
40 /* Raise to sync */
41 KeRaiseIrql(SYNCH_LEVEL, &OldIrql);
42
43 /* Acquire the lock and return */
44 KxAcquireSpinLock(SpinLock);
45 return OldIrql;
46 }
47
48 /*
49 * @implemented
50 */
51 KIRQL
52 FASTCALL
53 KfAcquireSpinLock(PKSPIN_LOCK SpinLock)
54 {
55 KIRQL OldIrql;
56
57 /* Raise to dispatch and acquire the lock */
58 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
59 KxAcquireSpinLock(SpinLock);
60 return OldIrql;
61 }
62
63 /*
64 * @implemented
65 */
66 VOID
67 FASTCALL
68 KfReleaseSpinLock(PKSPIN_LOCK SpinLock,
69 KIRQL OldIrql)
70 {
71 /* Release the lock and lower IRQL back */
72 KxReleaseSpinLock(SpinLock);
73 KeLowerIrql(OldIrql);
74 }
75
76 /*
77 * @implemented
78 */
79 KIRQL
80 FASTCALL
81 KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
82 {
83 KIRQL OldIrql;
84
85 /* Raise to dispatch */
86 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
87
88 /* Acquire the lock */
89 KxAcquireSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK
90 return OldIrql;
91 }
92
93 /*
94 * @implemented
95 */
96 KIRQL
97 FASTCALL
98 KeAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
99 {
100 KIRQL OldIrql;
101
102 /* Raise to synch */
103 KeRaiseIrql(SYNCH_LEVEL, &OldIrql);
104
105 /* Acquire the lock */
106 KxAcquireSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK
107 return OldIrql;
108 }
109
110 /*
111 * @implemented
112 */
113 VOID
114 FASTCALL
115 KeAcquireInStackQueuedSpinLock(IN PKSPIN_LOCK SpinLock,
116 IN PKLOCK_QUEUE_HANDLE LockHandle)
117 {
118 /* Set up the lock */
119 LockHandle->LockQueue.Next = NULL;
120 LockHandle->LockQueue.Lock = SpinLock;
121
122 /* Raise to dispatch */
123 KeRaiseIrql(DISPATCH_LEVEL, &LockHandle->OldIrql);
124
125 /* Acquire the lock */
126 KxAcquireSpinLock(LockHandle->LockQueue.Lock); // HACK
127 }
128
129 /*
130 * @implemented
131 */
132 VOID
133 FASTCALL
134 KeAcquireInStackQueuedSpinLockRaiseToSynch(IN PKSPIN_LOCK SpinLock,
135 IN PKLOCK_QUEUE_HANDLE LockHandle)
136 {
137 /* Set up the lock */
138 LockHandle->LockQueue.Next = NULL;
139 LockHandle->LockQueue.Lock = SpinLock;
140
141 /* Raise to synch */
142 KeRaiseIrql(SYNCH_LEVEL, &LockHandle->OldIrql);
143
144 /* Acquire the lock */
145 KxAcquireSpinLock(LockHandle->LockQueue.Lock); // HACK
146 }
147
148 /*
149 * @implemented
150 */
151 VOID
152 FASTCALL
153 KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
154 IN KIRQL OldIrql)
155 {
156 /* Release the lock */
157 KxReleaseSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK
158
159 /* Lower IRQL back */
160 KeLowerIrql(OldIrql);
161 }
162
163 /*
164 * @implemented
165 */
166 VOID
167 FASTCALL
168 KeReleaseInStackQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle)
169 {
170 /* Simply lower IRQL back */
171 KxReleaseSpinLock(LockHandle->LockQueue.Lock); // HACK
172 KeLowerIrql(LockHandle->OldIrql);
173 }
174
175 /*
176 * @implemented
177 */
178 BOOLEAN
179 FASTCALL
180 KeTryToAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
181 IN PKIRQL OldIrql)
182 {
183 #ifdef CONFIG_SMP
184 ASSERT(FALSE); // FIXME: Unused
185 // while (TRUE);
186 return FALSE;
187 #endif
188
189 /* Simply raise to synch */
190 KeRaiseIrql(SYNCH_LEVEL, OldIrql);
191
192 /* Add an explicit memory barrier to prevent the compiler from reordering
193 memory accesses across the borders of spinlocks */
194 KeMemoryBarrierWithoutFence();
195
196 /* Always return true on UP Machines */
197 return TRUE;
198 }
199
200 /*
201 * @implemented
202 */
203 LOGICAL
204 FASTCALL
205 KeTryToAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
206 OUT PKIRQL OldIrql)
207 {
208 #ifdef CONFIG_SMP
209 ASSERT(FALSE); // FIXME: Unused
210 // while (TRUE);
211 return FALSE;
212 #endif
213
214 /* Simply raise to dispatch */
215 KeRaiseIrql(DISPATCH_LEVEL, OldIrql);
216
217 /* Add an explicit memory barrier to prevent the compiler from reordering
218 memory accesses across the borders of spinlocks */
219 KeMemoryBarrierWithoutFence();
220
221 /* Always return true on UP Machines */
222 return TRUE;
223 }
224
225 #endif
226
227 VOID
228 NTAPI
229 HalpAcquireCmosSpinLock(VOID)
230 {
231 ULONG_PTR Flags;
232
233 /* Get flags and disable interrupts */
234 Flags = __readeflags();
235 _disable();
236
237 /* Acquire the lock */
238 KxAcquireSpinLock(&HalpSystemHardwareLock);
239
240 /* We have the lock, save the flags now */
241 HalpSystemHardwareFlags = Flags;
242 }
243
244 VOID
245 NTAPI
246 HalpReleaseCmosSpinLock(VOID)
247 {
248 ULONG_PTR Flags;
249
250 /* Get the flags */
251 Flags = HalpSystemHardwareFlags;
252
253 /* Release the lock */
254 KxReleaseSpinLock(&HalpSystemHardwareLock);
255
256 /* Restore the flags */
257 __writeeflags(Flags);
258 }
259