Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
icc_generic.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2019 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 
18 
19 */
20 
21 #if !defined(__TBB_machine_H) || defined(__TBB_machine_icc_generic_H)
22 #error Do not #include this internal file directly; use public TBB headers instead.
23 #endif
24 
25 #if ! __TBB_ICC_BUILTIN_ATOMICS_PRESENT
26  #error "Intel C++ Compiler of at least 12.0 version is needed to use ICC intrinsics port"
27 #endif
28 
29 #define __TBB_machine_icc_generic_H
30 
31 //ICC mimics the "native" target compiler
32 #if _MSC_VER
33  #include "msvc_ia32_common.h"
34 #else
35  #include "gcc_ia32_common.h"
36 #endif
37 
38 //TODO: Make __TBB_WORDSIZE macro optional for ICC intrinsics port.
39 //As compiler intrinsics are used for all the operations it is possible to do.
40 
41 #if __TBB_x86_32
42  #define __TBB_WORDSIZE 4
43 #else
44  #define __TBB_WORDSIZE 8
45 #endif
46 #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
47 
48 //__TBB_compiler_fence() defined just in case, as it seems not to be used on its own anywhere else
49 #ifndef __TBB_compiler_fence
50 #if _MSC_VER
51  //TODO: any way to use same intrinsics on windows and linux?
52  #pragma intrinsic(_ReadWriteBarrier)
53  #define __TBB_compiler_fence() _ReadWriteBarrier()
54 #else
55  #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory")
56 #endif
57 #endif
58 
59 #ifndef __TBB_full_memory_fence
60 #if _MSC_VER
61  //TODO: any way to use same intrinsics on windows and linux?
62  #pragma intrinsic(_mm_mfence)
63  #define __TBB_full_memory_fence() _mm_mfence()
64 #else
65  #define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory")
66 #endif
67 #endif
68 
69 #ifndef __TBB_control_consistency_helper
70 #define __TBB_control_consistency_helper() __TBB_compiler_fence()
71 #endif
72 
73 namespace tbb { namespace internal {
74 //TODO: is there any way to reuse definition of memory_order enum from ICC instead of copy paste.
75 //however it seems unlikely that ICC will silently change exact enum values, as they are defined
76 //in the ISO exactly like this.
77 //TODO: add test that exact values of the enum are same as in the ISO C++11
78 typedef enum memory_order {
81 } memory_order;
82 
83 namespace icc_intrinsics_port {
84  template <typename T>
86  return value;
87  }
88  //The overload below is needed to have explicit conversion of pointer to void* in argument list.
89  //compiler bug?
90  //TODO: add according broken macro and recheck with ICC 13.0 if the overload is still needed
91  template <typename T>
93  return (void*)value;
94  }
95 }
96 //TODO: code below is a bit repetitive, consider simplifying it
97 template <typename T, size_t S>
99  static T load_with_acquire ( const volatile T& location ) {
100  return __atomic_load_explicit(&location, memory_order_acquire);
101  }
102  static void store_with_release ( volatile T &location, T value ) {
103  __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release);
104  }
105 };
106 
107 template <typename T, size_t S>
109  static inline T load ( const T& location ) {
110  return __atomic_load_explicit(&location, memory_order_relaxed);
111  }
112  static inline void store ( T& location, T value ) {
113  __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed);
114  }
115 };
116 
117 template <typename T, size_t S>
119  static T load ( const volatile T& location ) {
120  return __atomic_load_explicit(&location, memory_order_seq_cst);
121  }
122 
123  static void store ( volatile T &location, T value ) {
124  __atomic_store_explicit(&location, value, memory_order_seq_cst);
125  }
126 };
127 
128 }} // namespace tbb::internal
129 
130 namespace tbb{ namespace internal { namespace icc_intrinsics_port{
131  typedef enum memory_order_map {
137 }}}// namespace tbb::internal
138 
139 #define __TBB_MACHINE_DEFINE_ATOMICS(S,T,M) \
140 inline T __TBB_machine_cmpswp##S##M( volatile void *ptr, T value, T comparand ) { \
141  __atomic_compare_exchange_strong_explicit( \
142  (T*)ptr \
143  ,&comparand \
144  ,value \
145  , tbb::internal::icc_intrinsics_port::M \
146  , tbb::internal::icc_intrinsics_port::M); \
147  return comparand; \
148 } \
149  \
150 inline T __TBB_machine_fetchstore##S##M(volatile void *ptr, T value) { \
151  return __atomic_exchange_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M); \
152 } \
153  \
154 inline T __TBB_machine_fetchadd##S##M(volatile void *ptr, T value) { \
155  return __atomic_fetch_add_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M); \
156 } \
157 
158 __TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, full_fence)
159 __TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, acquire)
160 __TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, release)
161 __TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, relaxed)
162 
163 __TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, full_fence)
164 __TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, acquire)
165 __TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, release)
166 __TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, relaxed)
167 
168 __TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, full_fence)
169 __TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, acquire)
170 __TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, release)
171 __TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, relaxed)
172 
173 __TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, full_fence)
174 __TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, acquire)
175 __TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, release)
176 __TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, relaxed)
177 
178 
179 #undef __TBB_MACHINE_DEFINE_ATOMICS
180 
181 #define __TBB_USE_FENCED_ATOMICS 1
182 
183 namespace tbb { namespace internal {
184 #if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN
187 
190 
193 
194 template <typename T>
195 struct machine_load_store<T,8> {
196  static T load_with_acquire ( const volatile T& location ) {
197  if( tbb::internal::is_aligned(&location,8)) {
198  return __atomic_load_explicit(&location, memory_order_acquire);
199  } else {
200  return __TBB_machine_generic_load8acquire(&location);
201  }
202  }
203  static void store_with_release ( volatile T &location, T value ) {
204  if( tbb::internal::is_aligned(&location,8)) {
205  __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release);
206  } else {
207  return __TBB_machine_generic_store8release(&location,value);
208  }
209  }
210 };
211 
212 template <typename T>
213 struct machine_load_store_relaxed<T,8> {
214  static T load( const volatile T& location ) {
215  if( tbb::internal::is_aligned(&location,8)) {
216  return __atomic_load_explicit(&location, memory_order_relaxed);
217  } else {
218  return __TBB_machine_generic_load8relaxed(&location);
219  }
220  }
221  static void store( volatile T &location, T value ) {
222  if( tbb::internal::is_aligned(&location,8)) {
223  __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed);
224  } else {
225  return __TBB_machine_generic_store8relaxed(&location,value);
226  }
227  }
228 };
229 
230 template <typename T >
231 struct machine_load_store_seq_cst<T,8> {
232  static T load ( const volatile T& location ) {
233  if( tbb::internal::is_aligned(&location,8)) {
234  return __atomic_load_explicit(&location, memory_order_seq_cst);
235  } else {
236  return __TBB_machine_generic_load8full_fence(&location);
237  }
238 
239  }
240 
241  static void store ( volatile T &location, T value ) {
242  if( tbb::internal::is_aligned(&location,8)) {
243  __atomic_store_explicit(&location, value, memory_order_seq_cst);
244  } else {
245  return __TBB_machine_generic_store8full_fence(&location,value);
246  }
247 
248  }
249 };
250 
251 #endif
252 }} // namespace tbb::internal
253 template <typename T>
254 inline void __TBB_machine_OR( T *operand, T addend ) {
255  __atomic_fetch_or_explicit(operand, addend, tbb::internal::memory_order_seq_cst);
256 }
257 
258 template <typename T>
259 inline void __TBB_machine_AND( T *operand, T addend ) {
260  __atomic_fetch_and_explicit(operand, addend, tbb::internal::memory_order_seq_cst);
261 }
262 
static void store_with_release(volatile T &location, T value)
Definition: icc_generic.h:102
Sequential consistency.
Definition: atomic.h:45
#define __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(M)
Definition: tbb_machine.h:169
No ordering.
Definition: atomic.h:51
static void store(volatile T &location, T value)
Definition: icc_generic.h:123
Acquire.
Definition: atomic.h:47
static T load_with_acquire(const volatile T &location)
Definition: icc_generic.h:99
static T load(const volatile T &location)
Definition: icc_generic.h:119
#define __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(M)
Definition: tbb_machine.h:177
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:353
The graph class.
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
void __TBB_machine_OR(T *operand, T addend)
Definition: icc_generic.h:254
static void store(T &location, T value)
Definition: icc_generic.h:112
#define __TBB_MACHINE_DEFINE_ATOMICS(S, T, M)
Definition: icc_generic.h:139
Release.
Definition: atomic.h:49
void __TBB_machine_AND(T *operand, T addend)
Definition: icc_generic.h:259
static T load(const T &location)
Definition: icc_generic.h:109

Copyright © 2005-2019 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.