sync with trunk r46493
[reactos.git] / 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 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 #endif
187
188 /* Simply raise to synch */
189 KeRaiseIrql(SYNCH_LEVEL, OldIrql);
190
191 /* Always return true on UP Machines */
192 return TRUE;
193 }
194
195 /*
196 * @implemented
197 */
198 LOGICAL
199 FASTCALL
200 KeTryToAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
201 OUT PKIRQL OldIrql)
202 {
203 #ifdef CONFIG_SMP
204 ASSERT(FALSE); // FIXME: Unused
205 while (TRUE);
206 #endif
207
208 /* Simply raise to dispatch */
209 KeRaiseIrql(DISPATCH_LEVEL, OldIrql);
210
211 /* Always return true on UP Machines */
212 return TRUE;
213 }
214
215 #endif
216
217 VOID
218 NTAPI
219 HalpAcquireSystemHardwareSpinLock(VOID)
220 {
221 ULONG Flags;
222
223 /* Get flags and disable interrupts */
224 Flags = __readeflags();
225 _disable();
226
227 /* Acquire the lock */
228 KxAcquireSpinLock(&HalpSystemHardwareLock);
229
230 /* We have the lock, save the flags now */
231 HalpSystemHardwareFlags = Flags;
232 }
233
234 VOID
235 NTAPI
236 HalpReleaseCmosSpinLock(VOID)
237 {
238 ULONG Flags;
239
240 /* Get the flags */
241 Flags = HalpSystemHardwareFlags;
242
243 /* Release the lock */
244 KxReleaseSpinLock(&HalpSystemHardwareLock);
245
246 /* Restore the flags */
247 __writeeflags(Flags);
248 }
249