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

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