tbb_misc.h
Go to the documentation of this file.
/*
Copyright (c) 2005-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef _TBB_tbb_misc_H
#define _TBB_tbb_misc_H
#include "tbb/tbb_stddef.h"
#include "tbb/tbb_machine.h"
#include "tbb/atomic.h" // For atomic_xxx definitions
#if __TBB_NUMA_SUPPORT
#include "tbb/info.h"
#endif /*__TBB_NUMA_SUPPORT*/
#if __linux__ || __FreeBSD__
#include <sys/param.h> // __FreeBSD_version
#if __FreeBSD_version >= 701000
#include <sys/cpuset.h>
#endif
#endif
// Does the operating system have a system call to pin a thread to a set of OS processors?
#define __TBB_OS_AFFINITY_SYSCALL_PRESENT ((__linux__ && !__ANDROID__) || (__FreeBSD_version >= 701000))
// On IBM* Blue Gene* CNK nodes, the affinity API has restrictions that prevent its usability for TBB,
// and also sysconf(_SC_NPROCESSORS_ONLN) already takes process affinity into account.
#define __TBB_USE_OS_AFFINITY_SYSCALL (__TBB_OS_AFFINITY_SYSCALL_PRESENT && !__bg__)
namespace tbb {
namespace internal {
const size_t MByte = 1024*1024;
#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00)
// In Win8UI mode (Windows 8 Store* applications), TBB uses a thread creation API
// that does not allow to specify the stack size.
// Still, the thread stack size value, either explicit or default, is used by the scheduler.
// So here we set the default value to match the platform's default of 1MB.
const size_t ThreadStackSize = 1*MByte;
#else
const size_t ThreadStackSize = (sizeof(uintptr_t) <= 4 ? 2 : 4 )*MByte;
#endif
#ifndef __TBB_HardwareConcurrency
int AvailableHwConcurrency();
#else
inline int AvailableHwConcurrency() {
int n = __TBB_HardwareConcurrency();
return n > 0 ? n : 1; // Fail safety strap
}
#endif /* __TBB_HardwareConcurrency */
size_t DefaultSystemPageSize();
#if _WIN32||_WIN64
int NumberOfProcessorGroups();
int FindProcessorGroupIndex ( int processorIndex );
void MoveThreadIntoProcessorGroup( void* hThread, int groupIndex );
#endif /* _WIN32||_WIN64 */
void handle_win_error( int error_code );
void PrintVersion();
void PrintExtraVersionInfo( const char* category, const char* format, ... );
void PrintRMLVersionInfo( void* arg, const char* server_info );
// For TBB compilation only; not to be used in public headers
#if defined(min) || defined(max)
#undef min
#undef max
#endif
template<typename T>
T min ( const T& val1, const T& val2 ) {
return val1 < val2 ? val1 : val2;
}
template<typename T>
T max ( const T& val1, const T& val2 ) {
return val1 < val2 ? val2 : val1;
}
template<int > struct int_to_type {};
//------------------------------------------------------------------------
// FastRandom
//------------------------------------------------------------------------
unsigned GetPrime ( unsigned seed );
class FastRandom {
private:
#if __TBB_OLD_PRIMES_RNG
unsigned x, a;
static const unsigned c = 1;
#else
unsigned x, c;
static const unsigned a = 0x9e3779b1; // a big prime number
#endif //__TBB_OLD_PRIMES_RNG
public:
unsigned short get() {
return get(x);
}
unsigned short get( unsigned& seed ) {
unsigned short r = (unsigned short)(seed>>16);
__TBB_ASSERT(c&1, "c must be odd for big rng period");
seed = seed*a+c;
return r;
}
FastRandom( void* unique_ptr ) { init(uintptr_t(unique_ptr)); }
FastRandom( uint32_t seed) { init(seed); }
FastRandom( uint64_t seed) { init(seed); }
template <typename T>
void init( T seed ) {
init(seed,int_to_type<sizeof(seed)>());
}
void init( uint64_t seed , int_to_type<8> ) {
init(uint32_t((seed>>32)+seed), int_to_type<4>());
}
void init( uint32_t seed, int_to_type<4> ) {
#if __TBB_OLD_PRIMES_RNG
x = seed;
a = GetPrime( seed );
#else
// threads use different seeds for unique sequences
c = (seed|1)*0xba5703f5; // c must be odd, shuffle by a prime number
x = c^(seed>>1); // also shuffle x for the first get() invocation
#endif
}
};
//------------------------------------------------------------------------
// Atomic extensions
//------------------------------------------------------------------------
template<typename T1, typename T2, class Pred>
T1 atomic_update ( tbb::atomic<T1>& dst, T2 newValue, Pred compare ) {
T1 oldValue = dst;
while ( compare(oldValue, newValue) ) {
if ( dst.compare_and_swap((T1)newValue, oldValue) == oldValue )
break;
oldValue = dst;
}
return oldValue;
}
enum do_once_state {
do_once_uninitialized = 0,
do_once_pending,
do_once_executed,
initialization_complete = do_once_executed
};
template <typename F>
void atomic_do_once ( const F& initializer, atomic<do_once_state>& state ) {
// tbb::atomic provides necessary acquire and release fences.
// The loop in the implementation is necessary to avoid race when thread T2
// that arrived in the middle of initialization attempt by another thread T1
// has just made initialization possible.
// In such a case T2 has to rely on T1 to initialize, but T1 may already be past
// the point where it can recognize the changed conditions.
while ( state != do_once_executed ) {
if( state == do_once_uninitialized ) {
if( state.compare_and_swap( do_once_pending, do_once_uninitialized ) == do_once_uninitialized ) {
run_initializer( initializer, state );
break;
}
}
spin_wait_while_eq( state, do_once_pending );
}
}
// Run the initializer which can not fail
inline void run_initializer( void (*f)(), atomic<do_once_state>& state ) {
f();
state = do_once_executed;
}
// Run the initializer which can require repeated call
inline void run_initializer( bool (*f)(), atomic<do_once_state>& state ) {
state = f() ? do_once_executed : do_once_uninitialized;
}
#if __TBB_USE_OS_AFFINITY_SYSCALL
#if __linux__
typedef cpu_set_t basic_mask_t;
#elif __FreeBSD_version >= 701000
typedef cpuset_t basic_mask_t;
#else
#error affinity_helper is not implemented in this OS
#endif
class affinity_helper : no_copy {
basic_mask_t* threadMask;
int is_changed;
public:
affinity_helper() : threadMask(NULL), is_changed(0) {}
~affinity_helper();
void protect_affinity_mask( bool restore_process_mask );
void dismiss();
};
void destroy_process_mask();
#else
class affinity_helper : no_copy {
public:
void protect_affinity_mask( bool ) {}
void dismiss() {}
};
inline void destroy_process_mask(){}
#endif /* __TBB_USE_OS_AFFINITY_SYSCALL */
bool cpu_has_speculation();
bool gcc_rethrow_exception_broken();
void fix_broken_rethrow();
#if __TBB_NUMA_SUPPORT
class binding_handler;
binding_handler* construct_binding_handler(int slot_num);
void destroy_binding_handler(binding_handler* handler_ptr);
void bind_thread_to_node(binding_handler* handler_ptr, int slot_num , int numa_id);
void restore_affinity_mask(binding_handler* handler_ptr, int slot_num);
namespace numa_topology {
bool is_initialized();
void initialize();
void destroy();
}
#endif /*__TBB_NUMA_SUPPORT*/
} // namespace internal
} // namespace tbb
#endif /* _TBB_tbb_misc_H */
tbb::internal::FastRandom::x
unsigned x
Definition: tbb_misc.h:141
internal
Definition: _flow_graph_async_msg_impl.h:24
tbb::internal::GetPrime
unsigned GetPrime(unsigned seed)
tbb::internal::MByte
const size_t MByte
Definition: tbb_misc.h:45
tbb::internal::FastRandom::init
void init(uint32_t seed, int_to_type< 4 >)
Definition: tbb_misc.h:167
__TBB_ASSERT
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
tbb::internal::no_copy
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:330
tbb::internal::int_to_type
Utility helper structure to ease overload resolution.
Definition: tbb_misc.h:124
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:186
tbb::internal::do_once_pending
A thread is executing associated do-once routine.
Definition: tbb_misc.h:199
tbb::internal::FastRandom::FastRandom
FastRandom(uint64_t seed)
Definition: tbb_misc.h:159
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.
tbb
The graph class.
Definition: serial/tbb/parallel_for.h:46
tbb::internal::affinity_helper
Definition: tbb_misc.h:261
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:161
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::internal::destroy_process_mask
void destroy_process_mask()
Definition: tbb_misc.h:266
info.h
tbb::internal::affinity_helper::protect_affinity_mask
void protect_affinity_mask(bool)
Definition: tbb_misc.h:263
tbb::internal::run_initializer
void run_initializer(void(*f)(), atomic< do_once_state > &state)
Definition: tbb_misc.h:232
tbb::internal::binding_handler
Definition: tbb_bind.cpp:221
tbb::internal::fix_broken_rethrow
void fix_broken_rethrow()
Definition: tbb_misc.cpp:197
atomic.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_machine.h
tbb::internal::do_once_state
do_once_state
One-time initialization states.
Definition: tbb_misc.h:197
tbb::internal::do_once_uninitialized
No execution attempts have been undertaken yet.
Definition: tbb_misc.h:198
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::internal::atomic_do_once
void atomic_do_once(const F &initializer, atomic< do_once_state > &state)
One-time initialization function.
Definition: tbb_misc.h:213
tbb::internal::do_once_executed
Do-once routine has been executed.
Definition: tbb_misc.h:200
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:119
tbb::internal::FastRandom::get
unsigned short get()
Get a random number.
Definition: tbb_misc.h:146
tbb::internal::FastRandom::a
static const unsigned a
Definition: tbb_misc.h:142
tbb::internal::FastRandom::FastRandom
FastRandom(void *unique_ptr)
Construct a random number generator.
Definition: tbb_misc.h:157
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:54
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:150
tbb::internal::FastRandom
A fast random number generator.
Definition: tbb_misc.h:135
tbb_stddef.h
tbb::internal::affinity_helper::dismiss
void dismiss()
Definition: tbb_misc.h:264
tbb::internal::FastRandom::init
void init(uint64_t seed, int_to_type< 8 >)
Definition: tbb_misc.h:164
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_HardwareConcurrency
#define __TBB_HardwareConcurrency()
Definition: macos_common.h:39
tbb::internal::FastRandom::FastRandom
FastRandom(uint32_t seed)
Definition: tbb_misc.h:158
tbb::internal::min
T min(const T &val1, const T &val2)
Utility template function returning lesser of the two values.
Definition: tbb_misc.h:110
tbb::internal::initialization_complete
Convenience alias.
Definition: tbb_misc.h:201
tbb::internal::FastRandom::c
unsigned c
Definition: tbb_misc.h:141

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.