ReactOS  0.4.14-dev-77-gd9e7c48
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 
31 BOOLEAN
34 {
36 
37  /* Disable interrupts */
39 
40  /* Acquire the spinlock (inline) */
42 
43  return Enabled;
44 }
45 
47 VOID
51 {
52  /* Release the spinlock */
54 
55  /* Restore interrupts */
57 }
58 
59 
61 NTAPI
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 
86 ULONG
87 NTAPI
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 
113 NTAPI
115  IN OUT PLIST_ENTRY ListHead,
116  IN OUT PLIST_ENTRY ListEntry,
118 {
119  BOOLEAN Enable;
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 
139 NTAPI
141  IN OUT PLIST_ENTRY ListHead,
142  IN OUT PLIST_ENTRY ListEntry,
144 {
145  BOOLEAN Enable;
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 
165 NTAPI
167  IN OUT PLIST_ENTRY ListHead,
169 {
170  BOOLEAN Enable;
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 
200 NTAPI
202  IN OUT PSINGLE_LIST_ENTRY ListHead,
204 {
205  BOOLEAN Enable;
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 
226 NTAPI
228  IN OUT PSINGLE_LIST_ENTRY ListHead,
229  IN OUT PSINGLE_LIST_ENTRY ListEntry,
231 {
232  BOOLEAN Enable;
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 
252 NTAPI
254  IN PLONG Addend,
256 {
257  LONG Result;
258 
260  return (Result < 0) ? ResultNegative :
261  (Result > 0) ? ResultPositive :
262  ResultZero;
263 }
264 
266 NTAPI
268  IN PLONG Addend,
270 {
271  LONG Result;
272 
274  return (Result < 0) ? ResultNegative :
275  (Result > 0) ? ResultPositive :
276  ResultZero;
277 }
278 
279 ULONG
280 NTAPI
282  IN PULONG Target,
283  IN ULONG Value,
285 {
287 }
288 
289 #ifdef _M_IX86
290 
291 ULONG
292 FASTCALL
293 ExfInterlockedAddUlong(
297 {
298  BOOLEAN Enable;
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 
318 FASTCALL
319 ExfInterlockedInsertHeadList(
320  IN OUT PLIST_ENTRY ListHead,
321  IN PLIST_ENTRY ListEntry,
323 {
324  BOOLEAN Enable;
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 
344 FASTCALL
345 ExfInterlockedInsertTailList(
346  IN OUT PLIST_ENTRY ListHead,
347  IN PLIST_ENTRY ListEntry,
349 {
350  BOOLEAN Enable;
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 
371 FASTCALL
372 ExfInterlockedRemoveHeadList(
373  IN OUT PLIST_ENTRY ListHead,
375 {
376  BOOLEAN Enable;
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 
406 FASTCALL
407 ExfInterlockedPopEntryList(
408  IN OUT PSINGLE_LIST_ENTRY ListHead,
410 {
411  BOOLEAN Enable;
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 
432 FASTCALL
433 ExfInterlockedPushEntryList(
434  IN OUT PSINGLE_LIST_ENTRY ListHead,
435  IN PSINGLE_LIST_ENTRY ListEntry,
437 {
438  BOOLEAN Enable;
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 
458 NTAPI
460  IN PLONG Addend)
461 {
462  LONG Result;
463 
465  return (Result < 0) ? ResultNegative :
466  (Result > 0) ? ResultPositive :
467  ResultZero;
468 }
469 
471 FASTCALL
472 Exfi386InterlockedIncrementLong(
473  IN OUT LONG volatile *Addend)
474 {
475  LONG Result;
476 
478  return (Result < 0) ? ResultNegative :
479  (Result > 0) ? ResultPositive :
480  ResultZero;
481 }
482 
484 NTAPI
486  IN PLONG Addend)
487 {
488  LONG Result;
489 
491  return (Result < 0) ? ResultNegative :
492  (Result > 0) ? ResultPositive :
493  ResultZero;
494 }
495 
497 FASTCALL
498 Exfi386InterlockedDecrementLong(
499  IN OUT PLONG Addend)
500 {
501  LONG Result;
502 
504  return (Result < 0) ? ResultNegative :
505  (Result > 0) ? ResultPositive :
506  ResultZero;
507 }
508 
509 LONG
510 NTAPI
512  PLONG Target,
513  LONG Exchange)
514 {
515  return _InterlockedExchange(Target, Exchange);
516 }
517 
518 ULONG
519 FASTCALL
520 Exfi386InterlockedExchangeUlong(
522  IN ULONG Exchange)
523 {
524  return _InterlockedExchange((PLONG)Target, Exchange);
525 }
526 
527 LONGLONG
528 FASTCALL
530  IN OUT LONGLONG volatile *Destination,
531  IN PLONGLONG Exchange,
532  IN PLONGLONG Comparand,
534 {
535  return _InterlockedCompareExchange64(Destination, *Exchange, *Comparand);
536 }
537 
538 LONGLONG
539 FASTCALL
540 ExfInterlockedCompareExchange64(
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 
551 VOID
552 FASTCALL
556 {
557 }
558 
559 
560 #endif
561 
enum _INTERLOCKED_RESULT INTERLOCKED_RESULT
struct _LIST_ENTRY * PLIST_ENTRY
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define IN
Definition: typedefs.h:38
__int64 _InterlockedCompareExchange64(_Interlocked_operand_ __int64 volatile *_Destination, __int64 _Exchange, __int64 _Comparand)
Definition: ntbasedef.h:635
FORCEINLINE VOID KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.h:35
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
long __cdecl _InterlockedExchange(_Interlocked_operand_ long volatile *_Target, long _Value)
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
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
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
INTERLOCKED_RESULT NTAPI ExInterlockedIncrementLong(IN PLONG Addend, IN PKSPIN_LOCK Lock)
Definition: interlocked.c:253
KSPIN_LOCK * PKSPIN_LOCK
Definition: env_spec_w32.h:73
#define InsertTailList(ListHead, Entry)
FORCEINLINE BOOLEAN _ExiDisableInterruptsAndAcquireSpinlock(IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:32
NTKERNELAPI VOID FASTCALL ExInterlockedAddLargeStatistic(IN PLARGE_INTEGER Addend, IN ULONG Increment)
Definition: interlocked.c:103
#define FASTCALL
Definition: nt_native.h:50
IN OUT PLONG Addend
Definition: CrNtStubs.h:22
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE VOID PushEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry)
Definition: rtlfuncs.h:253
__GNU_EXTENSION typedef __int64 * PLONGLONG
Definition: ntbasedef.h:389
NTKERNELAPI LONGLONG FASTCALL ExInterlockedCompareExchange64(IN OUT PLONGLONG Destination, IN PLONGLONG Exchange, IN PLONGLONG Comparand, IN PKSPIN_LOCK Lock)
Definition: interlocked.c:113
PLIST_ENTRY NTAPI ExInterlockedInsertHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:114
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
unsigned char BOOLEAN
long __cdecl _InterlockedDecrement(_Interlocked_operand_ long volatile *_Addend)
smooth NULL
Definition: ftsmooth.c:416
#define FORCEINLINE
Definition: ntbasedef.h:221
_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:426
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
FORCEINLINE VOID KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.h:20
FORCEINLINE BOOLEAN KeDisableInterrupts(VOID)
Definition: ke.h:176
#define ULL(a, b)
Definition: format_msg.c:27
FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead)
Definition: rtlfuncs.h:240
int64_t LONGLONG
Definition: typedefs.h:66
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
PSINGLE_LIST_ENTRY NTAPI ExInterlockedPopEntryList(IN OUT PSINGLE_LIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:201
LONG NTAPI Exi386InterlockedExchangeUlong(PLONG Target, LONG Exch, LONG Compare)
Definition: stubs.c:48
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2891
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1068
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:636
LONG NTAPI Exi386InterlockedDecrementLong(PLONG Addend)
Definition: stubs.c:38
FORCEINLINE VOID _ExiReleaseSpinLockAndRestoreInterrupts(IN OUT PKSPIN_LOCK Lock, BOOLEAN Enable)
Definition: interlocked.c:48
Definition: typedefs.h:117
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
INTERLOCKED_RESULT NTAPI ExInterlockedDecrementLong(IN PLONG Addend, IN PKSPIN_LOCK Lock)
Definition: interlocked.c:267
LONG NTAPI Exi386InterlockedIncrementLong(PLONG Addend)
Definition: stubs.c:43
struct _SINGLE_LIST_ENTRY * PSINGLE_LIST_ENTRY
FORCEINLINE VOID KeRestoreInterrupts(BOOLEAN WereEnabled)
Definition: ke.h:191
LARGE_INTEGER NTAPI ExInterlockedAddLargeInteger(IN OUT PLARGE_INTEGER Addend, IN LARGE_INTEGER Increment, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:62
unsigned int * PULONG
Definition: retypes.h:1
ULONG NTAPI ExInterlockedAddUlong(IN OUT PULONG Addend, IN ULONG Increment, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:88
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:42
signed int * PLONG
Definition: retypes.h:5
ULONG NTAPI ExInterlockedExchangeUlong(IN PULONG Target, IN ULONG Value, IN PKSPIN_LOCK Lock)
Definition: interlocked.c:281
LONGLONG QuadPart
Definition: typedefs.h:112