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
41namespace tbb {
42
43namespace internal {
44
45const 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.
52const size_t ThreadStackSize = 1*MByte;
53#else
54const size_t ThreadStackSize = (sizeof(uintptr_t) <= 4 ? 2 : 4 )*MByte;
55#endif
56
57#ifndef __TBB_HardwareConcurrency
58
61
62#else
63
64inline int AvailableHwConcurrency() {
66 return n > 0 ? n : 1; // Fail safety strap
67}
68#endif /* __TBB_HardwareConcurrency */
69
72
73#if _WIN32||_WIN64
74
76
77int NumberOfProcessorGroups();
78
80int FindProcessorGroupIndex ( int processorIndex );
81
83void MoveThreadIntoProcessorGroup( void* hThread, int groupIndex );
84
85#endif /* _WIN32||_WIN64 */
86
88void handle_win_error( int error_code );
89
91void PrintVersion();
92
94void PrintExtraVersionInfo( const char* category, const char* format, ... );
95
97void 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
109template<typename T>
110T min ( const T& val1, const T& val2 ) {
111 return val1 < val2 ? val1 : val2;
112}
113
115
118template<typename T>
119T max ( const T& val1, const T& val2 ) {
120 return val1 < val2 ? val2 : val1;
121}
122
124template<int > struct int_to_type {};
125
126//------------------------------------------------------------------------
127// FastRandom
128//------------------------------------------------------------------------
129
131unsigned GetPrime ( unsigned seed );
132
134
136private:
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
144public:
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
185template<typename T1, typename T2, class Pred>
186T1 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
203
205
212template <typename F>
213void 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
232inline 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
238inline void run_initializer( bool (*f)(), atomic<do_once_state>& state ) {
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 };
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
271void fix_broken_rethrow();
272
273#if __TBB_NUMA_SUPPORT
274class binding_handler;
275
276binding_handler* construct_binding_handler(int slot_num);
277void destroy_binding_handler(binding_handler* handler_ptr);
278void bind_thread_to_node(binding_handler* handler_ptr, int slot_num , int numa_id);
279void restore_affinity_mask(binding_handler* handler_ptr, int slot_num);
280
281namespace 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 */
#define __TBB_HardwareConcurrency()
Definition: macos_common.h:39
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
The graph class.
bool gcc_rethrow_exception_broken()
Definition: tbb_misc.cpp:198
void atomic_do_once(const F &initializer, atomic< do_once_state > &state)
One-time initialization function.
Definition: tbb_misc.h:213
unsigned GetPrime(unsigned seed)
void run_initializer(void(*f)(), atomic< do_once_state > &state)
Definition: tbb_misc.h:232
void fix_broken_rethrow()
Definition: tbb_misc.cpp:197
size_t DefaultSystemPageSize()
Returns OS regular memory page size.
Definition: tbb_misc.cpp:70
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:186
void destroy_process_mask()
Definition: tbb_misc.h:266
const size_t MByte
Definition: tbb_misc.h:45
T max(const T &val1, const T &val2)
Utility template function returning greater of the two values.
Definition: tbb_misc.h:119
void PrintExtraVersionInfo(const char *category, const char *format,...)
Prints arbitrary extra TBB version information on stderr.
Definition: tbb_misc.cpp:211
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 handle_win_error(int error_code)
Throws std::runtime_error with what() returning error_code description prefixed with aux_info.
bool cpu_has_speculation()
check for transaction support.
Definition: tbb_misc.cpp:230
const size_t ThreadStackSize
Definition: tbb_misc.h:54
do_once_state
One-time initialization states.
Definition: tbb_misc.h:197
@ initialization_complete
Convenience alias.
Definition: tbb_misc.h:201
@ do_once_uninitialized
No execution attempts have been undertaken yet.
Definition: tbb_misc.h:198
@ do_once_executed
Do-once routine has been executed.
Definition: tbb_misc.h:200
@ do_once_pending
A thread is executing associated do-once routine.
Definition: tbb_misc.h:199
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
void PrintVersion()
Prints TBB version information on stderr.
Definition: tbb_misc.cpp:206
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:330
Utility helper structure to ease overload resolution.
Definition: tbb_misc.h:124
A fast random number generator.
Definition: tbb_misc.h:135
static const unsigned a
Definition: tbb_misc.h:142
FastRandom(uint64_t seed)
Definition: tbb_misc.h:159
void init(uint32_t seed, int_to_type< 4 >)
Definition: tbb_misc.h:167
FastRandom(uint32_t seed)
Definition: tbb_misc.h:158
unsigned short get()
Get a random number.
Definition: tbb_misc.h:146
void init(uint64_t seed, int_to_type< 8 >)
Definition: tbb_misc.h:164
FastRandom(void *unique_ptr)
Construct a random number generator.
Definition: tbb_misc.h:157
unsigned short get(unsigned &seed)
Get a random number for the given seed; update the seed for next use.
Definition: tbb_misc.h:150

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.