BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_atomicoperations_arm64_win_msvc.h
Go to the documentation of this file.
1/// @file bsls_atomicoperations_arm64_win_msvc.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_atomicoperations_arm64_win_msvc.h -*-C++-*-
8#ifndef INCLUDED_BSLS_ATOMICOPERATIONS_ARM64_WIN_MSVC
9#define INCLUDED_BSLS_ATOMICOPERATIONS_ARM64_WIN_MSVC
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_atomicoperations_arm64_win_msvc bsls_atomicoperations_arm64_win_msvc
15/// @brief Provide implementations of atomic operations for arm64/MSVC/Win.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_atomicoperations_arm64_win_msvc
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_atomicoperations_arm64_win_msvc-purpose"> Purpose</a>
25/// * <a href="#bsls_atomicoperations_arm64_win_msvc-classes"> Classes </a>
26/// * <a href="#bsls_atomicoperations_arm64_win_msvc-description"> Description </a>
27///
28/// # Purpose {#bsls_atomicoperations_arm64_win_msvc-purpose}
29/// Provide implementations of atomic operations for arm64/MSVC/Win.
30///
31/// # Classes {#bsls_atomicoperations_arm64_win_msvc-classes}
32///
33/// - bsls::AtomicOperations_ARM64_WIN_MSVC: atomics for arm64/MSVC/Windows
34///
35/// # Description {#bsls_atomicoperations_arm64_win_msvc-description}
36/// This component provides classes necessary to implement atomics
37/// on the Windows platform with MSVC compiler for ARM CPUs. The classes are
38/// for private use only. See @ref bsls_atomicoperations and @ref bsls_atomic for
39/// the public interface to atomics.
40/// @}
41/** @} */
42/** @} */
43
44/** @addtogroup bsl
45 * @{
46 */
47/** @addtogroup bsls
48 * @{
49 */
50/** @addtogroup bsls_atomicoperations_arm64_win_msvc
51 * @{
52 */
53
54#include <bsls_atomicoperations_default.h>
55#include <bsls_platform.h>
56#include <bsls_types.h>
57
58#if defined(BSLS_PLATFORM_CPU_ARM) && defined(BSLS_PLATFORM_CPU_64_BIT) && \
59 defined(BSLS_PLATFORM_CMP_MSVC)
60#include <intrin.h>
61
62
63
64namespace bsls {
65
66struct AtomicOperations_ARM64_WIN_MSVC;
67typedef AtomicOperations_ARM64_WIN_MSVC AtomicOperations_Imp;
68
69 // =========================================================
70 // struct Atomic_TypeTraits<AtomicOperations_ARM64_WIN_MSVC>
71 // =========================================================
72
73template<>
74struct Atomic_TypeTraits<AtomicOperations_ARM64_WIN_MSVC>
75{
76 struct Int
77 {
78 __declspec(align(4))
79 volatile int d_value;
80 };
81
82 struct Int64
83 {
84 __declspec(align(8))
85 volatile Types::Int64 d_value;
86 };
87
88 struct Uint
89 {
90 __declspec(align(4))
91 volatile unsigned int d_value;
92 };
93
94 struct Uint64
95 {
96 __declspec(align(8))
97 volatile Types::Uint64 d_value;
98 };
99
100 struct Pointer
101 {
102 __declspec(align(8))
103 void * volatile d_value;
104 };
105};
106
107 // ======================================
108 // struct AtomicOperations_ARM64_WIN_MSVC
109 // ======================================
110
111struct AtomicOperations_ARM64_WIN_MSVC
112 : AtomicOperations_Default64<AtomicOperations_ARM64_WIN_MSVC>
113{
114 typedef Atomic_TypeTraits<AtomicOperations_ARM64_WIN_MSVC> AtomicTypes;
115
116 // *** atomic functions for int ***
117
118 static int getInt(const AtomicTypes::Int *atomicInt);
119
120 static int getIntAcquire(const AtomicTypes::Int *atomicInt);
121
122 static void setInt(AtomicTypes::Int *atomicInt, int value);
123
124 static void setIntRelease(AtomicTypes::Int *atomicInt, int value);
125
126 static int swapInt(AtomicTypes::Int *atomicInt, int swapValue);
127
128 static int testAndSwapInt(AtomicTypes::Int *atomicInt,
129 int compareValue,
130 int swapValue);
131
132 static int addIntNv(AtomicTypes::Int *atomicInt, int value);
133
134 // *** atomic functions for Int64 ***
135
136 static Types::Int64 getInt64(const AtomicTypes::Int64 *atomicInt);
137
138 static void setInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 value);
139
140 static Types::Int64 swapInt64(AtomicTypes::Int64 *atomicInt,
141 Types::Int64 swapValue);
142
143 static Types::Int64 testAndSwapInt64(AtomicTypes::Int64 *atomicInt,
144 Types::Int64 compareValue,
145 Types::Int64 swapValue);
146
147 static Types::Int64 addInt64Nv(AtomicTypes::Int64 *atomicInt,
148 Types::Int64 value);
149};
150
151// ===========================================================================
152// INLINE FUNCTION DEFINITIONS
153// ===========================================================================
154
155 // --------------------------------------
156 // struct AtomicOperations_ARM64_WIN_MSVC
157 // --------------------------------------
158
159// Memory barrier for atomic operations with sequential consistency.
160#define BSLS_ATOMIC_FENCE() \
161 __dmb(_ARM64_BARRIER_ISH)
162
163inline
164int AtomicOperations_ARM64_WIN_MSVC::getInt(const AtomicTypes::Int *atomicInt)
165{
166 unsigned int result = __ldar32(
167 reinterpret_cast<const volatile unsigned int *>(&atomicInt->d_value));
168 _ReadWriteBarrier();
169 return static_cast<int>(result);
170}
171
172inline
173int AtomicOperations_ARM64_WIN_MSVC::getIntAcquire(
174 const AtomicTypes::Int *atomicInt)
175{
176 unsigned int result = __ldar32(
177 reinterpret_cast<const volatile unsigned int *>(&atomicInt->d_value));
178 _ReadWriteBarrier();
179 return static_cast<int>(result);
180}
181
182inline
183void AtomicOperations_ARM64_WIN_MSVC::setInt(AtomicTypes::Int *atomicInt,
184 int value)
185{
186 _ReadWriteBarrier();
187 __stlr32(reinterpret_cast<volatile unsigned int *>(&atomicInt->d_value),
188 static_cast<unsigned int>(value));
189 BSLS_ATOMIC_FENCE();
190}
191
192inline
193void AtomicOperations_ARM64_WIN_MSVC::setIntRelease(
194 AtomicTypes::Int *atomicInt,
195 int value)
196{
197 _ReadWriteBarrier();
198 __stlr32(reinterpret_cast<volatile unsigned int *>(&atomicInt->d_value),
199 static_cast<unsigned int>(value));
200}
201
202inline
203int AtomicOperations_ARM64_WIN_MSVC::
204 swapInt(AtomicTypes::Int *atomicInt, int swapValue)
205{
206 return _InterlockedExchange(
207 reinterpret_cast<long volatile *>(&atomicInt->d_value),
208 swapValue);
209}
210
211inline
212int AtomicOperations_ARM64_WIN_MSVC::
213 testAndSwapInt(AtomicTypes::Int *atomicInt,
214 int compareValue,
215 int swapValue)
216{
217 return _InterlockedCompareExchange(
218 reinterpret_cast<long volatile *>(&atomicInt->d_value),
219 swapValue,
220 compareValue);
221}
222
223inline
224int AtomicOperations_ARM64_WIN_MSVC::
225 addIntNv(AtomicTypes::Int *atomicInt, int value)
226{
227 return static_cast<int>(
228 static_cast<unsigned int>(_InterlockedExchangeAdd(
229 reinterpret_cast<long volatile *>(&atomicInt->d_value),
230 value)) +
231 value);
232}
233
234 // *** atomic functions for Int64 ***
235
236inline
237Types::Int64 AtomicOperations_ARM64_WIN_MSVC::getInt64(
238 const AtomicTypes::Int64 *atomicInt)
239{
240 unsigned long long result =
241 __ldar64(reinterpret_cast<const volatile unsigned long long *>(
242 &atomicInt->d_value));
243 _ReadWriteBarrier();
244 return static_cast<Types::Int64>(result);
245}
246
247inline
248void AtomicOperations_ARM64_WIN_MSVC::setInt64(AtomicTypes::Int64 *atomicInt,
249 Types::Int64 value)
250{
251 _ReadWriteBarrier();
252 __stlr64(
253 reinterpret_cast<volatile unsigned long long *>(&atomicInt->d_value),
254 static_cast<unsigned long long>(value));
255 BSLS_ATOMIC_FENCE();
256}
257
258
259inline
260Types::Int64 AtomicOperations_ARM64_WIN_MSVC::
261 swapInt64(AtomicTypes::Int64 *atomicInt,
262 Types::Int64 swapValue)
263{
264 return _InterlockedExchange64(
265 &atomicInt->d_value,
266 swapValue);
267}
268
269inline
270Types::Int64 AtomicOperations_ARM64_WIN_MSVC::
271 testAndSwapInt64(AtomicTypes::Int64 *atomicInt,
272 Types::Int64 compareValue,
273 Types::Int64 swapValue)
274{
275 return _InterlockedCompareExchange64(
276 &atomicInt->d_value,
277 swapValue,
278 compareValue);
279}
280
281inline
282Types::Int64 AtomicOperations_ARM64_WIN_MSVC::
283 addInt64Nv(AtomicTypes::Int64 *atomicInt,
284 Types::Int64 value)
285{
286 return static_cast<Types::Int64>(
287 static_cast<Types::Uint64>(
288 _InterlockedExchangeAdd64(&atomicInt->d_value, value)) +
289 value);
290
291}
292
293#undef BSLS_ATOMIC_FENCE
294
295} // close package namespace
296
297
298
299#endif // arm64 && MSVC
300
301#endif
302
303// ----------------------------------------------------------------------------
304// Copyright 2024 Bloomberg Finance L.P.
305//
306// Licensed under the Apache License, Version 2.0 (the "License");
307// you may not use this file except in compliance with the License.
308// You may obtain a copy of the License at
309//
310// http://www.apache.org/licenses/LICENSE-2.0
311//
312// Unless required by applicable law or agreed to in writing, software
313// distributed under the License is distributed on an "AS IS" BASIS,
314// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
315// See the License for the specific language governing permissions and
316// limitations under the License.
317// ----------------------------- END-OF-FILE ----------------------------------
318
319/** @} */
320/** @} */
321/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlt_iso8601util.h:691