e7863fd1ef50e6613807213590344ccc43a65695
[reactos.git] / reactos / ntoskrnl / ex / interlck.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/interlck.c
6 * PURPOSE: Implements interlocked functions
7 *
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* FUNCTIONS *****************************************************************/
18
19 #undef ExInterlockedDecrementLong
20
21 /*
22 * @implemented
23 */
24 INTERLOCKED_RESULT STDCALL
25 ExInterlockedDecrementLong (PLONG Addend,
26 PKSPIN_LOCK Lock)
27 /*
28 * Obsolete, use InterlockedDecrement instead
29 */
30 {
31 KIRQL oldlvl;
32 LONG oldval;
33
34 KeAcquireSpinLock (Lock, &oldlvl);
35
36 oldval = *Addend;
37 (*Addend)--;
38
39 KeReleaseSpinLock (Lock, oldlvl);
40
41 return oldval;
42 }
43
44 #undef ExInterlockedExchangeUlong
45
46 /*
47 * @implemented
48 */
49 ULONG STDCALL
50 ExInterlockedExchangeUlong (PULONG Target,
51 ULONG Value,
52 PKSPIN_LOCK Lock)
53 /*
54 * Obsolete, use InterlockedExchange instead
55 */
56 {
57 KIRQL oldlvl;
58 LONG oldval;
59
60 KeAcquireSpinLock (Lock, &oldlvl);
61
62 oldval = *Target;
63 *Target = Value;
64
65 KeReleaseSpinLock (Lock, oldlvl);
66
67 return oldval;
68 }
69
70
71 #undef ExInterlockedAddUlong
72
73 /*
74 * @implemented
75 */
76 ULONG STDCALL
77 ExInterlockedAddUlong (PULONG Addend,
78 ULONG Increment,
79 PKSPIN_LOCK Lock)
80 /*
81 * ExInterlockedAddUlong adds an unsigned long value to a given unsigned
82 * integer as an atomic operation.
83 *
84 * ADDEND = Points to an unsigned long integer whose value is to be adjusted
85 * by the Increment value.
86 *
87 * INCREMENT = Is an unsigned long integer to be added.
88 *
89 * LOCK = Points to a spinlock to be used to synchronize access to ADDEND.
90 *
91 * Returns:
92 *
93 * The original value of the unsigned integer pointed to by ADDEND.
94 */
95 {
96 KIRQL oldlvl;
97 ULONG oldval;
98
99 KeAcquireSpinLock (Lock, &oldlvl);
100
101 oldval = *Addend;
102 *Addend += Increment;
103
104 KeReleaseSpinLock (Lock, oldlvl);
105
106 return oldval;
107 }
108
109 /*
110 * @implemented
111 */
112 LARGE_INTEGER STDCALL
113 ExInterlockedAddLargeInteger (PLARGE_INTEGER Addend,
114 LARGE_INTEGER Increment,
115 PKSPIN_LOCK Lock)
116 /*
117 * Adds two large integer values as an atomic operation.
118 *
119 * ADDEND = Pointer to a large integer value that will have INCREMENT added.
120 *
121 * INCREMENT = Value to be added.
122 *
123 * LOCK = Spinlock used to synchronize access to ADDEND.
124 *
125 * Returns:
126 *
127 * The original value of the large integer pointed to by ADDEND.
128 */
129 {
130 KIRQL oldlvl;
131 LARGE_INTEGER oldval;
132
133
134 KeAcquireSpinLock (Lock, &oldlvl);
135
136
137 oldval.QuadPart = Addend->QuadPart;
138 Addend->QuadPart += Increment.QuadPart;
139
140 KeReleaseSpinLock (Lock, oldlvl);
141
142 return oldval;
143 }
144
145 #undef ExInterlockedIncrementLong
146
147 /*
148 * @implemented
149 */
150 INTERLOCKED_RESULT STDCALL
151 ExInterlockedIncrementLong (PLONG Addend,
152 PKSPIN_LOCK Lock)
153 /*
154 * Obsolete, use InterlockedIncrement instead.
155 */
156 {
157 KIRQL oldlvl;
158 LONG oldval;
159
160 KeAcquireSpinLock (Lock, &oldlvl);
161
162 oldval = *Addend;
163 (*Addend)++;
164
165 KeReleaseSpinLock (Lock, oldlvl);
166
167 return oldval;
168 }
169
170 /*
171 * @implemented
172 */
173 VOID FASTCALL
174 ExInterlockedAddLargeStatistic (IN PLARGE_INTEGER Addend,
175 IN ULONG Increment)
176 /*
177 * Undocumented in DDK.
178 */
179 {
180 Addend->QuadPart += Increment;
181 }
182
183 /*
184 * @implemented
185 */
186 LONGLONG FASTCALL
187 ExInterlockedCompareExchange64 (IN OUT PLONGLONG Destination,
188 IN PLONGLONG Exchange,
189 IN PLONGLONG Comparand,
190 IN PKSPIN_LOCK Lock)
191 /*
192 * Undocumented in DDK.
193 */
194 {
195 KIRQL oldlvl;
196 LONGLONG oldval;
197
198 KeAcquireSpinLock (Lock, &oldlvl);
199
200 oldval = *Destination;
201 if (*Destination == *Comparand)
202 {
203 *Destination = *Exchange;
204 }
205
206 KeReleaseSpinLock (Lock, oldlvl);
207
208 return oldval;
209 }
210
211 /*
212 * @implemented
213 */
214 ULONG FASTCALL
215 ExfInterlockedAddUlong(PULONG Addend,
216 ULONG Increment,
217 PKSPIN_LOCK Lock)
218 /*
219 * ExInterlockedAddUlong adds an unsigned long value to a given unsigned
220 * integer as an atomic operation.
221 *
222 * ADDEND = Points to an unsigned long integer whose value is to be adjusted
223 * by the Increment value.
224 *
225 * INCREMENT = Is an unsigned long integer to be added.
226 *
227 * LOCK = Points to a spinlock to be used to synchronize access to ADDEND.
228 *
229 * Returns:
230 *
231 * The original value of the unsigned integer pointed to by ADDEND.
232 */
233 {
234 KIRQL oldlvl;
235 ULONG oldval;
236
237 KeAcquireSpinLock (Lock, &oldlvl);
238
239 oldval = *Addend;
240 *Addend += Increment;
241
242 KeReleaseSpinLock (Lock, oldlvl);
243
244 return oldval;
245 }
246
247 /* EOF */