Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
tbb_misc.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 #ifndef _TBB_tbb_misc_H
18 #define _TBB_tbb_misc_H
19 
20 #include "tbb/tbb_stddef.h"
21 #include "tbb/tbb_machine.h"
22 #include "tbb/atomic.h" // For atomic_xxx definitions
23 
24 #if __TBB_NUMA_SUPPORT
25 #include "tbb/info.h"
26 #endif /*__TBB_NUMA_SUPPORT*/
27 
28 #if __linux__ || __FreeBSD__
29 #include <sys/param.h> // __FreeBSD_version
30 #if __FreeBSD_version >= 701000
31 #include <sys/cpuset.h>
32 #endif
33 #endif
34 
35 // Does the operating system have a system call to pin a thread to a set of OS processors?
36 #define __TBB_OS_AFFINITY_SYSCALL_PRESENT ((__linux__ && !__ANDROID__) || (__FreeBSD_version >= 701000))
37 // On IBM* Blue Gene* CNK nodes, the affinity API has restrictions that prevent its usability for TBB,
38 // and also sysconf(_SC_NPROCESSORS_ONLN) already takes process affinity into account.
39 #define __TBB_USE_OS_AFFINITY_SYSCALL (__TBB_OS_AFFINITY_SYSCALL_PRESENT && !__bg__)
40 
41 namespace tbb {
42 
43 #if __TBB_NUMA_SUPPORT
44 namespace interface7 { class task_arena; }
45 namespace interface6 { class task_scheduler_observer; }
46 #endif /*__TBB_NUMA_SUPPORT*/
47 
48 namespace internal {
49 
50 const size_t MByte = 1024*1024;
51 
52 #if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00)
53 // In Win8UI mode (Windows 8 Store* applications), TBB uses a thread creation API
54 // that does not allow to specify the stack size.
55 // Still, the thread stack size value, either explicit or default, is used by the scheduler.
56 // So here we set the default value to match the platform's default of 1MB.
57 const size_t ThreadStackSize = 1*MByte;
58 #else
59 const size_t ThreadStackSize = (sizeof(uintptr_t) <= 4 ? 2 : 4 )*MByte;
60 #endif
61 
62 #ifndef __TBB_HardwareConcurrency
63 
66 
67 #else
68 
69 inline int AvailableHwConcurrency() {
70  int n = __TBB_HardwareConcurrency();
71  return n > 0 ? n : 1; // Fail safety strap
72 }
73 #endif /* __TBB_HardwareConcurrency */
74 
76 size_t DefaultSystemPageSize();
77 
78 #if _WIN32||_WIN64
79 
81 
82 int NumberOfProcessorGroups();
83 
85 int FindProcessorGroupIndex ( int processorIndex );
86 
88 void MoveThreadIntoProcessorGroup( void* hThread, int groupIndex );
89 
90 #endif /* _WIN32||_WIN64 */
91 
93 void handle_win_error( int error_code );
94 
96 void PrintVersion();
97 
99 void PrintExtraVersionInfo( const char* category, const char* format, ... );
100 
102 void PrintRMLVersionInfo( void* arg, const char* server_info );
103 
104 // For TBB compilation only; not to be used in public headers
105 #if defined(min) || defined(max)
106 #undef min
107 #undef max
108 #endif
109 
111 
114 template<typename T>
115 T min ( const T& val1, const T& val2 ) {
116  return val1 < val2 ? val1 : val2;
117 }
118 
120 
123 template<typename T>
124 T max ( const T& val1, const T& val2 ) {
125  return val1 < val2 ? val2 : val1;
126 }
127 
129 template<int > struct int_to_type {};
130 
131 //------------------------------------------------------------------------
132 // FastRandom
133 //------------------------------------------------------------------------
134 
136 unsigned GetPrime ( unsigned seed );
137 
139 
140 class FastRandom {
141 private:
142 #if __TBB_OLD_PRIMES_RNG
143  unsigned x, a;
144  static const unsigned c = 1;
145 #else
146  unsigned x, c;
147  static const unsigned a = 0x9e3779b1; // a big prime number
148 #endif //__TBB_OLD_PRIMES_RNG
149 public:
151  unsigned short get() {
152  return get(x);
153  }
155  unsigned short get( unsigned& seed ) {
156  unsigned short r = (unsigned short)(seed>>16);
157  __TBB_ASSERT(c&1, "c must be odd for big rng period");
158  seed = seed*a+c;
159  return r;
160  }
162  FastRandom( void* unique_ptr ) { init(uintptr_t(unique_ptr)); }
163  FastRandom( uint32_t seed) { init(seed); }
164  FastRandom( uint64_t seed) { init(seed); }
165  template <typename T>
166  void init( T seed ) {
167  init(seed,int_to_type<sizeof(seed)>());
168  }
169  void init( uint64_t seed , int_to_type<8> ) {
170  init(uint32_t((seed>>32)+seed), int_to_type<4>());
171  }
172  void init( uint32_t seed, int_to_type<4> ) {
173 #if __TBB_OLD_PRIMES_RNG
174  x = seed;
175  a = GetPrime( seed );
176 #else
177  // threads use different seeds for unique sequences
178  c = (seed|1)*0xba5703f5; // c must be odd, shuffle by a prime number
179  x = c^(seed>>1); // also shuffle x for the first get() invocation
180 #endif
181  }
182 };
183 
184 //------------------------------------------------------------------------
185 // Atomic extensions
186 //------------------------------------------------------------------------
187 
189 
190 template<typename T1, typename T2, class Pred>
191 T1 atomic_update ( tbb::atomic<T1>& dst, T2 newValue, Pred compare ) {
192  T1 oldValue = dst;
193  while ( compare(oldValue, newValue) ) {
194  if ( dst.compare_and_swap((T1)newValue, oldValue) == oldValue )
195  break;
196  oldValue = dst;
197  }
198  return oldValue;
199 }
200 
207 };
208 
210 
217 template <typename F>
218 void atomic_do_once ( const F& initializer, atomic<do_once_state>& state ) {
219  // tbb::atomic provides necessary acquire and release fences.
220  // The loop in the implementation is necessary to avoid race when thread T2
221  // that arrived in the middle of initialization attempt by another thread T1
222  // has just made initialization possible.
223  // In such a case T2 has to rely on T1 to initialize, but T1 may already be past
224  // the point where it can recognize the changed conditions.
225  while ( state != do_once_executed ) {
226  if( state == do_once_uninitialized ) {
227  if( state.compare_and_swap( do_once_pending, do_once_uninitialized ) == do_once_uninitialized ) {
228  run_initializer( initializer, state );
229  break;
230  }
231  }
233  }
234 }
235 
236 // Run the initializer which can not fail
237 inline void run_initializer( void (*f)(), atomic<do_once_state>& state ) {
238  f();
239  state = do_once_executed;
240 }
241 
242 // Run the initializer which can require repeated call
243 inline void run_initializer( bool (*f)(), atomic<do_once_state>& state ) {
244  state = f() ? do_once_executed : do_once_uninitialized;
245 }
246 
247 #if __TBB_USE_OS_AFFINITY_SYSCALL
248  #if __linux__
249  typedef cpu_set_t basic_mask_t;
250  #elif __FreeBSD_version >= 701000
251  typedef cpuset_t basic_mask_t;
252  #else
253  #error affinity_helper is not implemented in this OS
254  #endif
255  class affinity_helper : no_copy {
256  basic_mask_t* threadMask;
257  int is_changed;
258  public:
259  affinity_helper() : threadMask(NULL), is_changed(0) {}
260  ~affinity_helper();
261  void protect_affinity_mask( bool restore_process_mask );
262  void dismiss();
263  };
264  void destroy_process_mask();
265 #else
267  public:
268  void protect_affinity_mask( bool ) {}
269  void dismiss() {}
270  };
271  inline void destroy_process_mask(){}
272 #endif /* __TBB_USE_OS_AFFINITY_SYSCALL */
273 
274 bool cpu_has_speculation();
276 void fix_broken_rethrow();
277 
278 #if __TBB_NUMA_SUPPORT
279 // Interfaces for binding threads to certain NUMA nodes by third-party library interfaces.
280 // - construct_binding_observer() returns pointer to constructed and enabled (observe(true) was called) observer
281 // that binds incoming thread during on_scheduler_entry() call and returns old affinity mask
282 // during on_scheduler_exit() call
283 // - destroy_binding_observer() deactivates, destroys and deallocates observer that was described earlier.
284 // If requested third party library does not exist on the system, then they are still may be called but do nothing.
285 tbb::interface6::task_scheduler_observer* construct_binding_observer(
286  tbb::interface7::task_arena* ta, int numa_id, int num_slots );
287 
288 void destroy_binding_observer( tbb::interface6::task_scheduler_observer* observer );
289 
290 namespace numa_topology {
291  bool is_initialized();
292  void initialize();
293  void destroy();
294 }
295 
296 #endif /*__TBB_NUMA_SUPPORT*/
297 
298 } // namespace internal
299 } // namespace tbb
300 
301 #endif /* _TBB_tbb_misc_H */
tbb::internal::gcc_rethrow_exception_broken
bool gcc_rethrow_exception_broken()
Definition: tbb_misc.cpp:198
tbb::internal::PrintVersion
void PrintVersion()
Prints TBB version information on stderr.
Definition: tbb_misc.cpp:206
tbb::internal::run_initializer
void run_initializer(void(*f)(), atomic< do_once_state > &state)
Definition: tbb_misc.h:237
tbb::internal::FastRandom
A fast random number generator.
Definition: tbb_misc.h:140
tbb::internal::do_once_state
do_once_state
One-time initialization states.
Definition: tbb_misc.h:202
__TBB_ASSERT
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
tbb::internal::PrintRMLVersionInfo
void PrintRMLVersionInfo(void *arg, const char *server_info)
A callback routine to print RML version information on stderr.
Definition: tbb_misc.cpp:222
tbb
The graph class.
Definition: serial/tbb/parallel_for.h:46
tbb::internal::do_once_uninitialized
No execution attempts have been undertaken yet.
Definition: tbb_misc.h:203
tbb::internal::FastRandom::FastRandom
FastRandom(void *unique_ptr)
Construct a random number generator.
Definition: tbb_misc.h:162
tbb::internal::AvailableHwConcurrency
int AvailableHwConcurrency()
Returns maximal parallelism level supported by the current OS configuration.
tbb::internal::ThreadStackSize
const size_t ThreadStackSize
Definition: tbb_misc.h:59
tbb::interface6::task_scheduler_observer
Definition: task_scheduler_observer.h:92
tbb::internal::int_to_type
Utility helper structure to ease overload resolution.
Definition: tbb_misc.h:129
tbb::internal::affinity_helper::protect_affinity_mask
void protect_affinity_mask(bool)
Definition: tbb_misc.h:268
tbb::internal::FastRandom::init
void init(uint64_t seed, int_to_type< 8 >)
Definition: tbb_misc.h:169
tbb::internal::do_once_executed
Do-once routine has been executed.
Definition: tbb_misc.h:205
tbb::internal::affinity_helper::dismiss
void dismiss()
Definition: tbb_misc.h:269
tbb::internal::atomic_do_once
void atomic_do_once(const F &initializer, atomic< do_once_state > &state)
One-time initialization function.
Definition: tbb_misc.h:218
tbb::internal::DefaultSystemPageSize
size_t DefaultSystemPageSize()
Returns OS regular memory page size.
Definition: tbb_misc.cpp:70
tbb::internal::max
T max(const T &val1, const T &val2)
Utility template function returning greater of the two values.
Definition: tbb_misc.h:124
tbb::internal::FastRandom::get
unsigned short get()
Get a random number.
Definition: tbb_misc.h:151
info.h
tbb::internal::FastRandom::a
static const unsigned a
Definition: tbb_misc.h:147
tbb::internal::FastRandom::get
unsigned short get(unsigned &seed)
Get a random number for the given seed; update the seed for next use.
Definition: tbb_misc.h:155
tbb::internal::PrintExtraVersionInfo
void PrintExtraVersionInfo(const char *category, const char *format,...)
Prints arbitrary extra TBB version information on stderr.
Definition: tbb_misc.cpp:211
tbb::internal::GetPrime
unsigned GetPrime(unsigned seed)
tbb::internal::initialization_complete
Convenience alias.
Definition: tbb_misc.h:206
tbb::internal::MByte
const size_t MByte
Definition: tbb_misc.h:50
tbb::internal::FastRandom::FastRandom
FastRandom(uint32_t seed)
Definition: tbb_misc.h:163
tbb::internal::min
T min(const T &val1, const T &val2)
Utility template function returning lesser of the two values.
Definition: tbb_misc.h:115
atomic.h
tbb::internal::FastRandom::c
unsigned c
Definition: tbb_misc.h:146
tbb::internal::do_once_pending
A thread is executing associated do-once routine.
Definition: tbb_misc.h:204
tbb::internal::FastRandom::FastRandom
FastRandom(uint64_t seed)
Definition: tbb_misc.h:164
tbb::internal::FastRandom::x
unsigned x
Definition: tbb_misc.h:146
tbb::internal::FastRandom::init
void init(uint32_t seed, int_to_type< 4 >)
Definition: tbb_misc.h:172
tbb::internal::spin_wait_while_eq
void spin_wait_while_eq(const volatile T &location, U value)
Spin WHILE the value of the variable is equal to a given value.
Definition: tbb_machine.h:394
tbb::interface7::task_arena
Definition: task_arena.h:228
tbb_machine.h
tbb::internal::atomic_update
T1 atomic_update(tbb::atomic< T1 > &dst, T2 newValue, Pred compare)
Atomically replaces value of dst with newValue if they satisfy condition of compare predicate.
Definition: tbb_misc.h:191
tbb::internal::destroy_process_mask
void destroy_process_mask()
Definition: tbb_misc.h:271
tbb::internal::handle_win_error
void handle_win_error(int error_code)
Throws std::runtime_error with what() returning error_code description prefixed with aux_info.
internal
Definition: _flow_graph_async_msg_impl.h:24
tbb_stddef.h
tbb::internal::cpu_has_speculation
bool cpu_has_speculation()
check for transaction support.
Definition: tbb_misc.cpp:230
tbb::internal::FastRandom::init
void init(T seed)
Definition: tbb_misc.h:166
__TBB_HardwareConcurrency
#define __TBB_HardwareConcurrency()
Definition: macos_common.h:39
tbb::internal::no_copy
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:330
tbb::internal::affinity_helper
Definition: tbb_misc.h:266
tbb::internal::fix_broken_rethrow
void fix_broken_rethrow()
Definition: tbb_misc.cpp:197

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.