ReactOS 0.4.15-dev-7961-gdcf9eb0
interlocked.c
Go to the documentation of this file.
1/*
2* PROJECT: ReactOS Kernel
3* LICENSE: GPL - See COPYING in the top level directory
4* FILE: ntoskrnl/ex/interlocked.c
5* PURPOSE: Interlocked functions
6* PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
7*/
8
9/* INCLUDES *****************************************************************/
10
11#include <ntoskrnl.h>
12
13#define NDEBUG
14#include <debug.h>
15
16#undef ExInterlockedAddUlong
17#undef ExInterlockedInsertHeadList
18#undef ExInterlockedInsertTailList
19#undef ExInterlockedRemoveHeadList
20#undef ExInterlockedPopEntryList
21#undef ExInterlockedPushEntryList
22#undef ExInterlockedIncrementLong
23#undef ExInterlockedDecrementLong
24#undef ExInterlockedExchangeUlong
25#undef ExInterlockedCompareExchange64
26
27
28/* FUNCTIONS ****************************************************************/
29
34{
36
37 /* Disable interrupts */
39
40 /* Acquire the spinlock (inline) */
41 KxAcquireSpinLock(Lock);
42
43 return Enabled;
44}
45
47VOID
51{
52 /* Release the spinlock */
53 KxReleaseSpinLock(Lock);
54
55 /* Restore interrupts */
57}
58
59
66{
67 LARGE_INTEGER OldValue;
69
70 /* Disable interrupts and acquire the spinlock */
72
73 /* Save the old value */
74 OldValue.QuadPart = Addend->QuadPart;
75
76 /* Do the operation */
77 Addend->QuadPart += Increment.QuadPart;
78
79 /* Release the spinlock and restore interrupts */
81
82 /* Return the old value */
83 return OldValue;
84}
85
92{
94 ULONG OldValue;
95
96 /* Disable interrupts and acquire the spinlock */
98
99 /* Save the old value */
100 OldValue = *Addend;
101
102 /* Do the operation */
103 *Addend += Increment;
104
105 /* Release the spinlock and restore interrupts */
107
108 /* Return the old value */
109 return OldValue;
110}
111
113NTAPI
115 IN OUT PLIST_ENTRY ListHead,
116 IN OUT PLIST_ENTRY ListEntry,
118{
120 PLIST_ENTRY FirstEntry;
121
122 /* Disable interrupts and acquire the spinlock */
124
125 /* Save the first entry */
126 FirstEntry = ListHead->Flink;
127
128 /* Insert the new entry */
129 InsertHeadList(ListHead, ListEntry);
130
131 /* Release the spinlock and restore interrupts */
133
134 /* Return the old first entry or NULL for empty list */
135 return (FirstEntry == ListHead) ? NULL : FirstEntry;
136}
137
139NTAPI
141 IN OUT PLIST_ENTRY ListHead,
142 IN OUT PLIST_ENTRY ListEntry,
144{
146 PLIST_ENTRY LastEntry;
147
148 /* Disable interrupts and acquire the spinlock */
150
151 /* Save the last entry */
152 LastEntry = ListHead->Blink;
153
154 /* Insert the new entry */
155 InsertTailList(ListHead, ListEntry);
156
157 /* Release the spinlock and restore interrupts */
159
160 /* Return the old last entry or NULL for empty list */
161 return (LastEntry == ListHead) ? NULL : LastEntry;
162}
163
165NTAPI
167 IN OUT PLIST_ENTRY ListHead,
169{
171 PLIST_ENTRY ListEntry;
172
173 /* Disable interrupts and acquire the spinlock */
175
176 /* Check if the list is empty */
177 if (IsListEmpty(ListHead))
178 {
179 /* Return NULL */
180 ListEntry = NULL;
181 }
182 else
183 {
184 /* Remove the first entry from the list head */
185 ListEntry = RemoveHeadList(ListHead);
186#if DBG
187 ListEntry->Flink = (PLIST_ENTRY)(ULONG_PTR)0xBADDD0FFBADDD0FFULL;
188 ListEntry->Blink = (PLIST_ENTRY)(ULONG_PTR)0xBADDD0FFBADDD0FFULL;
189#endif
190 }
191
192 /* Release the spinlock and restore interrupts */
194
195 /* Return the entry */
196 return ListEntry;
197}
198
200NTAPI
202 IN OUT PSINGLE_LIST_ENTRY ListHead,
204{
206 PSINGLE_LIST_ENTRY ListEntry;
207
208 /* Disable interrupts and acquire the spinlock */
210
211 /* Pop the first entry from the list */
212 ListEntry = PopEntryList(ListHead);
213#if DBG
214 if (ListEntry)
215 ListEntry->Next = (PSINGLE_LIST_ENTRY)(ULONG_PTR)0xBADDD0FFBADDD0FFULL;
216#endif
217
218 /* Release the spinlock and restore interrupts */
220
221 /* Return the entry */
222 return ListEntry;
223}
224
226NTAPI
228 IN OUT PSINGLE_LIST_ENTRY ListHead,
229 IN OUT PSINGLE_LIST_ENTRY ListEntry,
231{
233 PSINGLE_LIST_ENTRY OldListEntry;
234
235 /* Disable interrupts and acquire the spinlock */
237
238 /* Save the old top entry */
239 OldListEntry = ListHead->Next;
240
241 /* Push a new entry on the list */
242 PushEntryList(ListHead, ListEntry);
243
244 /* Release the spinlock and restore interrupts */
246
247 /* Return the entry */
248 return OldListEntry;
249}
250
252NTAPI
256{
257 LONG Result;
258
260 return (Result < 0) ? ResultNegative :
261 (Result > 0) ? ResultPositive :
263}
264
266NTAPI
270{
271 LONG Result;
272
274 return (Result < 0) ? ResultNegative :
275 (Result > 0) ? ResultPositive :
277}
278
279ULONG
280NTAPI
283 IN ULONG Value,
285{
287}
288
289#ifdef _M_IX86
290
291ULONG
293ExfInterlockedAddUlong(
297{
299 ULONG OldValue;
300
301 /* Disable interrupts and acquire the spinlock */
303
304 /* Save the old value */
305 OldValue = *Addend;
306
307 /* Do the operation */
308 *Addend += Increment;
309
310 /* Release the spinlock and restore interrupts */
312
313 /* Return the old value */
314 return OldValue;
315}
316
319ExfInterlockedInsertHeadList(
320 IN OUT PLIST_ENTRY ListHead,
321 IN PLIST_ENTRY ListEntry,
323{
325 PLIST_ENTRY FirstEntry;
326
327 /* Disable interrupts and acquire the spinlock */
329
330 /* Save the first entry */
331 FirstEntry = ListHead->Flink;
332
333 /* Insert the new entry */
334 InsertHeadList(ListHead, ListEntry);
335
336 /* Release the spinlock and restore interrupts */
338
339 /* Return the old first entry or NULL for empty list */
340 return (FirstEntry == ListHead) ? NULL : FirstEntry;
341}
342
345ExfInterlockedInsertTailList(
346 IN OUT PLIST_ENTRY ListHead,
347 IN PLIST_ENTRY ListEntry,
349{
351 PLIST_ENTRY LastEntry;
352
353 /* Disable interrupts and acquire the spinlock */
355
356 /* Save the last entry */
357 LastEntry = ListHead->Blink;
358
359 /* Insert the new entry */
360 InsertTailList(ListHead, ListEntry);
361
362 /* Release the spinlock and restore interrupts */
364
365 /* Return the old last entry or NULL for empty list */
366 return (LastEntry == ListHead) ? NULL : LastEntry;
367}
368
369
372ExfInterlockedRemoveHeadList(
373 IN OUT PLIST_ENTRY ListHead,
375{
377 PLIST_ENTRY ListEntry;
378
379 /* Disable interrupts and acquire the spinlock */
381
382 /* Check if the list is empty */
383 if (IsListEmpty(ListHead))
384 {
385 /* Return NULL */
386 ListEntry = NULL;
387 }
388 else
389 {
390 /* Remove the first entry from the list head */
391 ListEntry = RemoveHeadList(ListHead);
392#if DBG
393 ListEntry->Flink = (PLIST_ENTRY)0x0BADD0FF;
394 ListEntry->Blink = (PLIST_ENTRY)0x0BADD0FF;
395#endif
396 }
397
398 /* Release the spinlock and restore interrupts */
400
401 /* return the entry */
402 return ListEntry;
403}
404
407ExfInterlockedPopEntryList(
408 IN OUT PSINGLE_LIST_ENTRY ListHead,
410{
412 PSINGLE_LIST_ENTRY ListEntry;
413
414 /* Disable interrupts and acquire the spinlock */
416
417 /* Pop the first entry from the list */
418 ListEntry = PopEntryList(ListHead);
419#if DBG
420 if (ListEntry)
421 ListEntry->Next = (PSINGLE_LIST_ENTRY)(ULONG_PTR)0xBADDD0FFBADDD0FFULL;
422#endif
423
424 /* Release the spinlock and restore interrupts */
426
427 /* return the entry */
428 return ListEntry;
429}
430
433ExfInterlockedPushEntryList(
434 IN OUT PSINGLE_LIST_ENTRY ListHead,
435 IN PSINGLE_LIST_ENTRY ListEntry,
437{
439 PSINGLE_LIST_ENTRY OldListEntry;
440
441 /* Disable interrupts and acquire the spinlock */
443
444 /* Save the old top entry */
445 OldListEntry = ListHead->Next;
446
447 /* Push a new entry on the list */
448 PushEntryList(ListHead, ListEntry);
449
450 /* Release the spinlock and restore interrupts */
452
453 /* return the entry */
454 return OldListEntry;
455}
456
458NTAPI
459Exi386InterlockedIncrementLong(
461{
462 LONG Result;
463
465 return (Result < 0) ? ResultNegative :
466 (Result > 0) ? ResultPositive :
468}
469
472Exfi386InterlockedIncrementLong(
473 IN OUT LONG volatile *Addend)
474{
475 LONG Result;
476
478 return (Result < 0) ? ResultNegative :
479 (Result > 0) ? ResultPositive :
481}
482
484NTAPI
485Exi386InterlockedDecrementLong(
487{
488 LONG Result;
489
491 return (Result < 0) ? ResultNegative :
492 (Result > 0) ? ResultPositive :
494}
495
498Exfi386InterlockedDecrementLong(
500{
501 LONG Result;
502
504 return (Result < 0) ? ResultNegative :
505 (Result > 0) ? ResultPositive :
507}
508
509LONG
510NTAPI
511Exi386InterlockedExchangeUlong(
513 LONG Exchange)
514{
515 return _InterlockedExchange(Target, Exchange);
516}
517
518ULONG
520Exfi386InterlockedExchangeUlong(
522 IN ULONG Exchange)
523{
524 return _InterlockedExchange((PLONG)Target, Exchange);
525}
526
530 IN OUT LONGLONG volatile *Destination,
531 IN PLONGLONG Exchange,
532 IN PLONGLONG Comparand,
534{
535 return _InterlockedCompareExchange64(Destination, *Exchange, *Comparand);
536}
537
540ExfInterlockedCompareExchange64(
541 IN OUT LONGLONG volatile *Destination,
542 IN PLONGLONG Exchange,
543 IN PLONGLONG Comparand)
544{
545 return _InterlockedCompareExchange64(Destination, *Exchange, *Comparand);
546}
547#endif
548
549#if 0
550
551VOID
556{
557}
558
559
560#endif
561
unsigned char BOOLEAN
#define NULL
Definition: types.h:112
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
KSPIN_LOCK * PKSPIN_LOCK
Definition: env_spec_w32.h:73
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
IN OUT PLONG Addend
Definition: CrNtStubs.h:25
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:46
ULONG NTAPI ExInterlockedAddUlong(IN OUT PULONG Addend, IN ULONG Increment, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:88
PSINGLE_LIST_ENTRY NTAPI ExInterlockedPopEntryList(IN OUT PSINGLE_LIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:201
PLIST_ENTRY NTAPI ExInterlockedInsertHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:114
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
LARGE_INTEGER NTAPI ExInterlockedAddLargeInteger(IN OUT PLARGE_INTEGER Addend, IN LARGE_INTEGER Increment, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:62
FORCEINLINE BOOLEAN _ExiDisableInterruptsAndAcquireSpinlock(IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:32
FORCEINLINE VOID _ExiReleaseSpinLockAndRestoreInterrupts(IN OUT PKSPIN_LOCK Lock, BOOLEAN Enable)
Definition: interlocked.c:48
PSINGLE_LIST_ENTRY NTAPI ExInterlockedPushEntryList(IN OUT PSINGLE_LIST_ENTRY ListHead, IN OUT PSINGLE_LIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:227
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
__int64 _InterlockedCompareExchange64(_Interlocked_operand_ __int64 volatile *_Destination, __int64 _Exchange, __int64 _Comparand)
long __cdecl _InterlockedExchange(_Interlocked_operand_ long volatile *_Target, long _Value)
long __cdecl _InterlockedDecrement(_Interlocked_operand_ long volatile *_Addend)
@ Enabled
Definition: mountmgr.h:159
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3004
#define FASTCALL
Definition: nt_native.h:50
struct _SINGLE_LIST_ENTRY * PSINGLE_LIST_ENTRY
__GNU_EXTENSION typedef __int64 * PLONGLONG
Definition: ntbasedef.h:382
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
FORCEINLINE BOOLEAN KeDisableInterrupts(VOID)
Definition: ke.h:239
FORCEINLINE VOID KeRestoreInterrupts(BOOLEAN WereEnabled)
Definition: ke.h:254
long LONG
Definition: pedump.c:60
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
uint32_t * PULONG
Definition: typedefs.h:59
struct _LIST_ENTRY * PLIST_ENTRY
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
#define FORCEINLINE
Definition: wdftypes.h:67
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define ExInterlockedAddLargeStatistic(Addend, Increment)
Definition: exfuncs.h:850
#define ExInterlockedExchangeUlong(Target, Value, Lock)
#define ExInterlockedDecrementLong(Addend, Lock)
#define ExInterlockedIncrementLong(Addend, Lock)
enum _INTERLOCKED_RESULT INTERLOCKED_RESULT
#define ExInterlockedCompareExchange64(Destination, Exchange, Comperand, Lock)
Definition: exfuncs.h:880
@ ResultPositive
Definition: exfuncs.h:361
@ ResultZero
Definition: exfuncs.h:360
@ ResultNegative
Definition: exfuncs.h:359
FORCEINLINE VOID PushEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry)
Definition: rtlfuncs.h:253
FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead)
Definition: rtlfuncs.h:240