DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
Interlocked.cpp
Go to the documentation of this file.
1#include "pch.h"
3
4#if defined(_WIN32)
5#include <windows.h>
6#include <intrin.h>
7#endif
8
9namespace DotNetDupe {
10 namespace System {
11 namespace Threading {
12
13 long InterlockedInternal::Increment32(volatile long* location) {
15#if defined(_WIN32)
16 return _InterlockedIncrement(location);
17#else
18 return __sync_add_and_fetch(location, 1);
19#endif
20 }
21
22 long InterlockedInternal::Decrement32(volatile long* location) {
24#if defined(_WIN32)
25 return _InterlockedDecrement(location);
26#else
27 return __sync_sub_and_fetch(location, 1);
28#endif
29 }
30
31 long InterlockedInternal::Add32(volatile long* location, long value) {
33#if defined(_WIN32)
34 return _InterlockedExchangeAdd(location, value) + value;
35#else
36 return __sync_add_and_fetch(location, value);
37#endif
38 }
39
40 long InterlockedInternal::Exchange32(volatile long* location, long value) {
42#if defined(_WIN32)
43 return _InterlockedExchange(location, value);
44#else
45 return __sync_lock_test_and_set(location, value);
46#endif
47 }
48
49 long InterlockedInternal::CompareExchange32(volatile long* location, long value, long comparand) {
51#if defined(_WIN32)
52 return _InterlockedCompareExchange(location, value, comparand);
53#else
54 return __sync_val_compare_and_swap(location, comparand, value);
55#endif
56 }
57
58 long long InterlockedInternal::Increment64(volatile long long* location) {
60#if defined(_WIN32)
61#if defined(_M_IX86)
62 long long oldVal, newVal;
63 do {
64 oldVal = *location;
65 newVal = oldVal + 1;
66 } while (_InterlockedCompareExchange64(location, newVal, oldVal) != oldVal);
67 return newVal;
68#else
69 return _InterlockedIncrement64(location);
70#endif
71#else
72 return __sync_add_and_fetch(location, 1);
73#endif
74 }
75
76 long long InterlockedInternal::Decrement64(volatile long long* location) {
78#if defined(_WIN32)
79#if defined(_M_IX86)
80 long long oldVal, newVal;
81 do {
82 oldVal = *location;
83 newVal = oldVal - 1;
84 } while (_InterlockedCompareExchange64(location, newVal, oldVal) != oldVal);
85 return newVal;
86#else
87 return _InterlockedDecrement64(location);
88#endif
89#else
90 return __sync_sub_and_fetch(location, 1);
91#endif
92 }
93
94 long long InterlockedInternal::Add64(volatile long long* location, long long value) {
96#if defined(_WIN32)
97#if defined(_M_IX86)
98 long long oldVal, newVal;
99 do {
100 oldVal = *location;
101 newVal = oldVal + value;
102 } while (_InterlockedCompareExchange64(location, newVal, oldVal) != oldVal);
103 return newVal;
104#else
105 return _InterlockedExchangeAdd64(location, value) + value;
106#endif
107#else
108 return __sync_add_and_fetch(location, value);
109#endif
110 }
111
112 long long InterlockedInternal::Exchange64(volatile long long* location, long long value) {
114#if defined(_WIN32)
115#if defined(_M_IX86)
116 long long oldVal;
117 do {
118 oldVal = *location;
119 } while (_InterlockedCompareExchange64(location, value, oldVal) != oldVal);
120 return oldVal;
121#else
122 return _InterlockedExchange64(location, value);
123#endif
124#else
125 return __sync_lock_test_and_set(location, value);
126#endif
127 }
128
129 long long InterlockedInternal::CompareExchange64(volatile long long* location, long long value, long long comparand) {
131#if defined(_WIN32)
132 return _InterlockedCompareExchange64(location, value, comparand);
133#else
134 return __sync_val_compare_and_swap(location, comparand, value);
135#endif
136 }
137 }
138 }
139}
Provides atomic operations for variables that are shared by multiple threads.
long __cdecl _InterlockedIncrement(long volatile *Addend)
long __cdecl _InterlockedDecrement(long volatile *Addend)