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