Sync with trunk r63786.
[reactos.git] / ntoskrnl / ke / amd64 / 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 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 #undef KeAcquireSpinLock
16 #undef KeReleaseSpinLock
17
18 /* FUNCTIONS *****************************************************************/
19
20 /*
21 * @implemented
22 */
23 KIRQL
24 KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock)
25 {
26 KIRQL OldIrql;
27
28 /* Raise to sync */
29 KeRaiseIrql(SYNCH_LEVEL, &OldIrql);
30
31 /* Acquire the lock and return */
32 KxAcquireSpinLock(SpinLock);
33 return OldIrql;
34 }
35
36 /*
37 * @implemented
38 */
39 KIRQL
40 NTAPI
41 KeAcquireSpinLockRaiseToDpc(PKSPIN_LOCK SpinLock)
42 {
43 KIRQL OldIrql;
44
45 /* Raise to dispatch */
46 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
47
48 /* Acquire the lock and return */
49 KxAcquireSpinLock(SpinLock);
50 return OldIrql;
51 }
52
53 /*
54 * @implemented
55 */
56 VOID
57 NTAPI
58 KeReleaseSpinLock(PKSPIN_LOCK SpinLock,
59 KIRQL OldIrql)
60 {
61 /* Release the lock and lower IRQL back */
62 KxReleaseSpinLock(SpinLock);
63 KeLowerIrql(OldIrql);
64 }
65
66 /*
67 * @implemented
68 */
69 KIRQL
70 KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
71 {
72 KIRQL OldIrql;
73
74 /* Raise to dispatch */
75 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
76
77 /* Acquire the lock */
78 KxAcquireSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK
79 return OldIrql;
80 }
81
82 /*
83 * @implemented
84 */
85 KIRQL
86 KeAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
87 {
88 KIRQL OldIrql;
89
90 /* Raise to synch */
91 KeRaiseIrql(SYNCH_LEVEL, &OldIrql);
92
93 /* Acquire the lock */
94 KxAcquireSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK
95 return OldIrql;
96 }
97
98 /*
99 * @implemented
100 */
101 VOID
102 KeAcquireInStackQueuedSpinLock(IN PKSPIN_LOCK SpinLock,
103 IN PKLOCK_QUEUE_HANDLE LockHandle)
104 {
105 /* Set up the lock */
106 LockHandle->LockQueue.Next = NULL;
107 LockHandle->LockQueue.Lock = SpinLock;
108
109 /* Raise to dispatch */
110 KeRaiseIrql(DISPATCH_LEVEL, &LockHandle->OldIrql);
111
112 /* Acquire the lock */
113 KxAcquireSpinLock(LockHandle->LockQueue.Lock); // HACK
114 }
115
116
117 /*
118 * @implemented
119 */
120 VOID
121 KeAcquireInStackQueuedSpinLockRaiseToSynch(IN PKSPIN_LOCK SpinLock,
122 IN PKLOCK_QUEUE_HANDLE LockHandle)
123 {
124 /* Set up the lock */
125 LockHandle->LockQueue.Next = NULL;
126 LockHandle->LockQueue.Lock = SpinLock;
127
128 /* Raise to synch */
129 KeRaiseIrql(SYNCH_LEVEL, &LockHandle->OldIrql);
130
131 /* Acquire the lock */
132 KxAcquireSpinLock(LockHandle->LockQueue.Lock); // HACK
133 }
134
135
136 /*
137 * @implemented
138 */
139 VOID
140 KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
141 IN KIRQL OldIrql)
142 {
143 /* Release the lock */
144 KxReleaseSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK
145
146 /* Lower IRQL back */
147 KeLowerIrql(OldIrql);
148 }
149
150
151 /*
152 * @implemented
153 */
154 VOID
155 KeReleaseInStackQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle)
156 {
157 /* Simply lower IRQL back */
158 KxReleaseSpinLock(LockHandle->LockQueue.Lock); // HACK
159 KeLowerIrql(LockHandle->OldIrql);
160 }
161
162
163 /*
164 * @implemented
165 */
166 BOOLEAN
167 KeTryToAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
168 IN PKIRQL OldIrql)
169 {
170 #ifndef CONFIG_SMP
171 /* Simply raise to dispatch */
172 KeRaiseIrql(DISPATCH_LEVEL, OldIrql);
173
174 /* Add an explicit memory barrier to prevent the compiler from reordering
175 memory accesses across the borders of spinlocks */
176 KeMemoryBarrierWithoutFence();
177
178 /* Always return true on UP Machines */
179 return TRUE;
180 #else
181 UNIMPLEMENTED;
182 ASSERT(FALSE);
183 #endif
184 }
185
186 /*
187 * @implemented
188 */
189 LOGICAL
190 KeTryToAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
191 OUT PKIRQL OldIrql)
192 {
193 #ifndef CONFIG_SMP
194 /* Simply raise to dispatch */
195 KeRaiseIrql(DISPATCH_LEVEL, OldIrql);
196
197 /* Add an explicit memory barrier to prevent the compiler from reordering
198 memory accesses across the borders of spinlocks */
199 KeMemoryBarrierWithoutFence();
200
201 /* Always return true on UP Machines */
202 return TRUE;
203 #else
204 UNIMPLEMENTED;
205 ASSERT(FALSE);
206 #endif
207 }
208
209 /* EOF */