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