Intel(R) Threading Building Blocks Doxygen Documentation version 4.2.3
Loading...
Searching...
No Matches
icc_generic.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2005-2020 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17#if !defined(__TBB_machine_H) || defined(__TBB_machine_icc_generic_H)
18#error Do not #include this internal file directly; use public TBB headers instead.
19#endif
20
21#if ! __TBB_ICC_BUILTIN_ATOMICS_PRESENT
22 #error "Intel(R) C++ Compiler of at least 12.0 version is needed to use ICC intrinsics port"
23#endif
24
25#define __TBB_machine_icc_generic_H
26
27//ICC mimics the "native" target compiler
28#if _MSC_VER
29 #include "msvc_ia32_common.h"
30#else
31 #include "gcc_ia32_common.h"
32#endif
33
34//TODO: Make __TBB_WORDSIZE macro optional for ICC intrinsics port.
35//As compiler intrinsics are used for all the operations it is possible to do.
36
37#if __TBB_x86_32
38 #define __TBB_WORDSIZE 4
39#else
40 #define __TBB_WORDSIZE 8
41#endif
42#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
43
44//__TBB_compiler_fence() defined just in case, as it seems not to be used on its own anywhere else
45#ifndef __TBB_compiler_fence
46#if _MSC_VER
47 //TODO: any way to use same intrinsics on windows and linux?
48 #pragma intrinsic(_ReadWriteBarrier)
49 #define __TBB_compiler_fence() _ReadWriteBarrier()
50#else
51 #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory")
52#endif
53#endif
54
55#ifndef __TBB_full_memory_fence
56#if _MSC_VER
57 //TODO: any way to use same intrinsics on windows and linux?
58 #pragma intrinsic(_mm_mfence)
59 #define __TBB_full_memory_fence() _mm_mfence()
60#else
61 #define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory")
62#endif
63#endif
64
65#ifndef __TBB_control_consistency_helper
66#define __TBB_control_consistency_helper() __TBB_compiler_fence()
67#endif
68
69namespace tbb { namespace internal {
70//TODO: is there any way to reuse definition of memory_order enum from ICC instead of copy paste.
71//however it seems unlikely that ICC will silently change exact enum values, as they are defined
72//in the ISO exactly like this.
73//TODO: add test that exact values of the enum are same as in the ISO C++11
74typedef enum memory_order {
78
79namespace icc_intrinsics_port {
80 template <typename T>
82 return value;
83 }
84 //The overload below is needed to have explicit conversion of pointer to void* in argument list.
85 //compiler bug?
86 //TODO: add according broken macro and recheck with ICC 13.0 if the overload is still needed
87 template <typename T>
89 return (void*)value;
90 }
91}
92//TODO: code below is a bit repetitive, consider simplifying it
93template <typename T, size_t S>
95 static T load_with_acquire ( const volatile T& location ) {
96 return __atomic_load_explicit(&location, memory_order_acquire);
97 }
98 static void store_with_release ( volatile T &location, T value ) {
99 __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release);
100 }
101};
102
103template <typename T, size_t S>
105 static inline T load ( const T& location ) {
106 return __atomic_load_explicit(&location, memory_order_relaxed);
107 }
108 static inline void store ( T& location, T value ) {
109 __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed);
110 }
111};
112
113template <typename T, size_t S>
115 static T load ( const volatile T& location ) {
116 return __atomic_load_explicit(&location, memory_order_seq_cst);
117 }
118
119 static void store ( volatile T &location, T value ) {
120 __atomic_store_explicit(&location, value, memory_order_seq_cst);
121 }
122};
123
124}} // namespace tbb::internal
125
126namespace tbb{ namespace internal { namespace icc_intrinsics_port{
127 typedef enum memory_order_map {
133}}}// namespace tbb::internal
134
135#define __TBB_MACHINE_DEFINE_ATOMICS(S,T,M) \
136inline T __TBB_machine_cmpswp##S##M( volatile void *ptr, T value, T comparand ) { \
137 __atomic_compare_exchange_strong_explicit( \
138 (T*)ptr \
139 ,&comparand \
140 ,value \
141 , tbb::internal::icc_intrinsics_port::M \
142 , tbb::internal::icc_intrinsics_port::M); \
143 return comparand; \
144} \
145 \
146inline T __TBB_machine_fetchstore##S##M(volatile void *ptr, T value) { \
147 return __atomic_exchange_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M); \
148} \
149 \
150inline T __TBB_machine_fetchadd##S##M(volatile void *ptr, T value) { \
151 return __atomic_fetch_add_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M); \
152} \
153
154__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, full_fence)
155__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, acquire)
156__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, release)
157__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, relaxed)
158
159__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, full_fence)
160__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, acquire)
161__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, release)
162__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, relaxed)
163
164__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, full_fence)
165__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, acquire)
166__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, release)
167__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, relaxed)
168
169__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, full_fence)
170__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, acquire)
171__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, release)
172__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, relaxed)
173
174
175#undef __TBB_MACHINE_DEFINE_ATOMICS
176
177#define __TBB_USE_FENCED_ATOMICS 1
178
179namespace tbb { namespace internal {
180#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN
183
186
189
190template <typename T>
191struct machine_load_store<T,8> {
192 static T load_with_acquire ( const volatile T& location ) {
193 if( tbb::internal::is_aligned(&location,8)) {
194 return __atomic_load_explicit(&location, memory_order_acquire);
195 } else {
196 return __TBB_machine_generic_load8acquire(&location);
197 }
198 }
199 static void store_with_release ( volatile T &location, T value ) {
200 if( tbb::internal::is_aligned(&location,8)) {
201 __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release);
202 } else {
203 return __TBB_machine_generic_store8release(&location,value);
204 }
205 }
206};
207
208template <typename T>
209struct machine_load_store_relaxed<T,8> {
210 static T load( const volatile T& location ) {
211 if( tbb::internal::is_aligned(&location,8)) {
212 return __atomic_load_explicit(&location, memory_order_relaxed);
213 } else {
214 return __TBB_machine_generic_load8relaxed(&location);
215 }
216 }
217 static void store( volatile T &location, T value ) {
218 if( tbb::internal::is_aligned(&location,8)) {
219 __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed);
220 } else {
221 return __TBB_machine_generic_store8relaxed(&location,value);
222 }
223 }
224};
225
226template <typename T >
227struct machine_load_store_seq_cst<T,8> {
228 static T load ( const volatile T& location ) {
229 if( tbb::internal::is_aligned(&location,8)) {
230 return __atomic_load_explicit(&location, memory_order_seq_cst);
231 } else {
232 return __TBB_machine_generic_load8full_fence(&location);
233 }
234
235 }
236
237 static void store ( volatile T &location, T value ) {
238 if( tbb::internal::is_aligned(&location,8)) {
239 __atomic_store_explicit(&location, value, memory_order_seq_cst);
240 } else {
241 return __TBB_machine_generic_store8full_fence(&location,value);
242 }
243
244 }
245};
246
247#endif
248}} // namespace tbb::internal
249template <typename T>
250inline void __TBB_machine_OR( T *operand, T addend ) {
251 __atomic_fetch_or_explicit(operand, addend, tbb::internal::memory_order_seq_cst);
252}
253
254template <typename T>
255inline void __TBB_machine_AND( T *operand, T addend ) {
256 __atomic_fetch_and_explicit(operand, addend, tbb::internal::memory_order_seq_cst);
257}
258
#define __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(M)
Definition: tbb_machine.h:165
#define __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(M)
Definition: tbb_machine.h:173
#define __TBB_MACHINE_DEFINE_ATOMICS(S, T, M)
Definition: icc_generic.h:135
void __TBB_machine_OR(T *operand, T addend)
Definition: icc_generic.h:250
void __TBB_machine_AND(T *operand, T addend)
Definition: icc_generic.h:255
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value
The graph class.
@ release
Release.
Definition: atomic.h:59
@ full_fence
Sequential consistency.
Definition: atomic.h:55
@ relaxed
No ordering.
Definition: atomic.h:61
@ acquire
Acquire.
Definition: atomic.h:57
bool is_aligned(T *pointer, uintptr_t alignment)
A function to check if passed in pointer is aligned on a specific border.
Definition: tbb_stddef.h:370
@ memory_order_acquire
Definition: icc_generic.h:75
@ memory_order_seq_cst
Definition: icc_generic.h:76
@ memory_order_release
Definition: icc_generic.h:76
@ memory_order_consume
Definition: icc_generic.h:75
@ memory_order_acq_rel
Definition: icc_generic.h:76
@ memory_order_relaxed
Definition: icc_generic.h:75
static void store_with_release(volatile T &location, T value)
Definition: icc_generic.h:98
static T load_with_acquire(const volatile T &location)
Definition: icc_generic.h:95
static void store(T &location, T value)
Definition: icc_generic.h:108
static T load(const T &location)
Definition: icc_generic.h:105
static void store(volatile T &location, T value)
Definition: icc_generic.h:119
static T load(const volatile T &location)
Definition: icc_generic.h:115

Copyright © 2005-2020 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.