xref: /reactos/ntoskrnl/ke/amd64/spinlock.c (revision 84ccccab)
1 /*
2  * PROJECT:         ReactOS HAL
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            ntoskrnl/ke/amd64/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 */
210