Home ⌂Doc Index ◂Up ▴
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-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 #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 namespace internal {
44 
45 const size_t MByte = 1024*1024;
46 
47 #if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00)
48 // In Win8UI mode (Windows 8 Store* applications), TBB uses a thread creation API
49 // that does not allow to specify the stack size.
50 // Still, the thread stack size value, either explicit or default, is used by the scheduler.
51 // So here we set the default value to match the platform's default of 1MB.
52 const size_t ThreadStackSize = 1*MByte;
53 #else
54 const size_t ThreadStackSize = (sizeof(uintptr_t) <= 4 ? 2 : 4 )*MByte;
55 #endif
56 
57 #ifndef __TBB_HardwareConcurrency
58 
61 
62 #else
63 
64 inline int AvailableHwConcurrency() {
65  int n = __TBB_HardwareConcurrency();
66  return n > 0 ? n : 1; // Fail safety strap
67 }
68 #endif /* __TBB_HardwareConcurrency */
69 
71 size_t DefaultSystemPageSize();
72 
73 #if _WIN32||_WIN64
74 
76 
77 int NumberOfProcessorGroups();
78 
80 int FindProcessorGroupIndex ( int processorIndex );
81 
83 void MoveThreadIntoProcessorGroup( void* hThread, int groupIndex );
84 
85 #endif /* _WIN32||_WIN64 */
86 
88 void handle_win_error( int error_code );
89 
91 void PrintVersion();
92 
94 void PrintExtraVersionInfo( const char* category, const char* format, ... );
95 
97 void PrintRMLVersionInfo( void* arg, const char* server_info );
98 
99 // For TBB compilation only; not to be used in public headers
100 #if defined(min) || defined(max)
101 #undef min
102 #undef max
103 #endif
104 
106 
109 template<typename T>
110 T min ( const T& val1, const T& val2 ) {
111  return val1 < val2 ? val1 : val2;
112 }
113 
115 
118 template<typename T>
119 T max ( const T& val1, const T& val2 ) {
120  return val1 < val2 ? val2 : val1;
121 }
122 
124 template<int > struct int_to_type {};
125 
126 //------------------------------------------------------------------------
127 // FastRandom
128 //------------------------------------------------------------------------
129 
131 unsigned GetPrime ( unsigned seed );
132 
134 
135 class FastRandom {
136 private:
137 #if __TBB_OLD_PRIMES_RNG
138  unsigned x, a;
139  static const unsigned c = 1;
140 #else
141  unsigned x, c;
142  static const unsigned a = 0x9e3779b1; // a big prime number
143 #endif //__TBB_OLD_PRIMES_RNG
144 public:
146  unsigned short get() {
147  return get(x);
148  }
150  unsigned short get( unsigned& seed ) {
151  unsigned short r = (unsigned short)(seed>>16);
152  __TBB_ASSERT(c&1, "c must be odd for big rng period");
153  seed = seed*a+c;
154  return r;
155  }
157  FastRandom( void* unique_ptr ) { init(uintptr_t(unique_ptr)); }
158  FastRandom( uint32_t seed) { init(seed); }
159  FastRandom( uint64_t seed) { init(seed); }
160  template <typename T>
161  void init( T seed ) {
162  init(seed,int_to_type<sizeof(seed)>());
163  }
164  void init( uint64_t seed , int_to_type<8> ) {
165  init(uint32_t((seed>>32)+seed), int_to_type<4>());
166  }
167  void init( uint32_t seed, int_to_type<4> ) {
168 #if __TBB_OLD_PRIMES_RNG
169  x = seed;
170  a = GetPrime( seed );
171 #else
172  // threads use different seeds for unique sequences
173  c = (seed|1)*0xba5703f5; // c must be odd, shuffle by a prime number
174  x = c^(seed>>1); // also shuffle x for the first get() invocation
175 #endif
176  }
177 };
178 
179 //------------------------------------------------------------------------
180 // Atomic extensions
181 //------------------------------------------------------------------------
182 
184 
185 template<typename T1, typename T2, class Pred>
186 T1 atomic_update ( tbb::atomic<T1>& dst, T2 newValue, Pred compare ) {
187  T1 oldValue = dst;
188  while ( compare(oldValue, newValue) ) {
189  if ( dst.compare_and_swap((T1)newValue, oldValue) == oldValue )
190  break;
191  oldValue = dst;
192  }
193  return oldValue;
194 }
195 
202 };
203 
205 
212 template <typename F>
213 void atomic_do_once ( const F& initializer, atomic<do_once_state>& state ) {
214  // tbb::atomic provides necessary acquire and release fences.
215  // The loop in the implementation is necessary to avoid race when thread T2
216  // that arrived in the middle of initialization attempt by another thread T1
217  // has just made initialization possible.
218  // In such a case T2 has to rely on T1 to initialize, but T1 may already be past
219  // the point where it can recognize the changed conditions.
220  while ( state != do_once_executed ) {
221  if( state == do_once_uninitialized ) {
222  if( state.compare_and_swap( do_once_pending, do_once_uninitialized ) == do_once_uninitialized ) {
223  run_initializer( initializer, state );
224  break;
225  }
226  }
228  }
229 }
230 
231 // Run the initializer which can not fail
232 inline void run_initializer( void (*f)(), atomic<do_once_state>& state ) {
233  f();
234  state = do_once_executed;
235 }
236 
237 // Run the initializer which can require repeated call
238 inline void run_initializer( bool (*f)(), atomic<do_once_state>& state ) {
239  state = f() ? do_once_executed : do_once_uninitialized;
240 }
241 
242 #if __TBB_USE_OS_AFFINITY_SYSCALL
243  #if __linux__
244  typedef cpu_set_t basic_mask_t;
245  #elif __FreeBSD_version >= 701000
246  typedef cpuset_t basic_mask_t;
247  #else
248  #error affinity_helper is not implemented in this OS
249  #endif
250  class affinity_helper : no_copy {
251  basic_mask_t* threadMask;
252  int is_changed;
253  public:
254  affinity_helper() : threadMask(NULL), is_changed(0) {}
255  ~affinity_helper();
256  void protect_affinity_mask( bool restore_process_mask );
257  void dismiss();
258  };
259  void destroy_process_mask();
260 #else
262  public:
263  void protect_affinity_mask( bool ) {}
264  void dismiss() {}
265  };
266  inline void destroy_process_mask(){}
267 #endif /* __TBB_USE_OS_AFFINITY_SYSCALL */
268 
269 bool cpu_has_speculation();
271 void fix_broken_rethrow();
272 
273 #if __TBB_NUMA_SUPPORT
274 class binding_handler;
275 
276 binding_handler* construct_binding_handler(int slot_num);
277 void destroy_binding_handler(binding_handler* handler_ptr);
278 void bind_thread_to_node(binding_handler* handler_ptr, int slot_num , int numa_id);
279 void restore_affinity_mask(binding_handler* handler_ptr, int slot_num);
280 
281 namespace numa_topology {
282  bool is_initialized();
283  void initialize();
284  void destroy();
285 }
286 
287 #endif /*__TBB_NUMA_SUPPORT*/
288 
289 } // namespace internal
290 } // namespace tbb
291 
292 #endif /* _TBB_tbb_misc_H */
A fast random number generator.
Definition: tbb_misc.h:135
bool gcc_rethrow_exception_broken()
Definition: tbb_misc.cpp:198
int AvailableHwConcurrency()
Returns maximal parallelism level supported by the current OS configuration.
bool cpu_has_speculation()
check for transaction support.
Definition: tbb_misc.cpp:230
Do-once routine has been executed.
Definition: tbb_misc.h:200
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:391
size_t DefaultSystemPageSize()
Returns OS regular memory page size.
Definition: tbb_misc.cpp:70
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:186
No execution attempts have been undertaken yet.
Definition: tbb_misc.h:198
void PrintVersion()
Prints TBB version information on stderr.
Definition: tbb_misc.cpp:206
unsigned short get()
Get a random number.
Definition: tbb_misc.h:146
FastRandom(uint64_t seed)
Definition: tbb_misc.h:159
#define __TBB_HardwareConcurrency()
Definition: macos_common.h:39
FastRandom(void *unique_ptr)
Construct a random number generator.
Definition: tbb_misc.h:157
void init(uint64_t seed, int_to_type< 8 >)
Definition: tbb_misc.h:164
void init(uint32_t seed, int_to_type< 4 >)
Definition: tbb_misc.h:167
void atomic_do_once(const F &initializer, atomic< do_once_state > &state)
One-time initialization function.
Definition: tbb_misc.h:213
void run_initializer(void(*f)(), atomic< do_once_state > &state)
Definition: tbb_misc.h:232
do_once_state
One-time initialization states.
Definition: tbb_misc.h:197
void PrintRMLVersionInfo(void *arg, const char *server_info)
A callback routine to print RML version information on stderr.
Definition: tbb_misc.cpp:222
T min(const T &val1, const T &val2)
Utility template function returning lesser of the two values.
Definition: tbb_misc.h:110
void destroy_process_mask()
Definition: tbb_misc.h:266
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:330
A thread is executing associated do-once routine.
Definition: tbb_misc.h:199
static const unsigned a
Definition: tbb_misc.h:142
Utility helper structure to ease overload resolution.
Definition: tbb_misc.h:124
T max(const T &val1, const T &val2)
Utility template function returning greater of the two values.
Definition: tbb_misc.h:119
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
unsigned short get(unsigned &seed)
Get a random number for the given seed; update the seed for next use.
Definition: tbb_misc.h:150
FastRandom(uint32_t seed)
Definition: tbb_misc.h:158
The graph class.
void fix_broken_rethrow()
Definition: tbb_misc.cpp:197
void handle_win_error(int error_code)
Throws std::runtime_error with what() returning error_code description prefixed with aux_info.
const size_t ThreadStackSize
Definition: tbb_misc.h:54
void PrintExtraVersionInfo(const char *category, const char *format,...)
Prints arbitrary extra TBB version information on stderr.
Definition: tbb_misc.cpp:211
unsigned GetPrime(unsigned seed)
const size_t MByte
Definition: tbb_misc.h:45

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.