blocked_range.h | blocked_range.h | |||
---|---|---|---|---|
skipping to change at line 102 | skipping to change at line 102 | |||
my_end(r.my_end), | my_end(r.my_end), | |||
my_begin(do_split(r, split())), | my_begin(do_split(r, split())), | |||
my_grainsize(r.my_grainsize) | my_grainsize(r.my_grainsize) | |||
{ | { | |||
// only comparison 'less than' is required from values of blocked_r ange objects | // only comparison 'less than' is required from values of blocked_r ange objects | |||
__TBB_ASSERT( !(my_begin < r.my_end) && !(r.my_end < my_begin), "bl ocked_range has been split incorrectly" ); | __TBB_ASSERT( !(my_begin < r.my_end) && !(r.my_end < my_begin), "bl ocked_range has been split incorrectly" ); | |||
} | } | |||
#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES | #if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES | |||
//! Static field to support proportional split | //! Static field to support proportional split | |||
static const bool is_divisible_in_proportion = true; | static const bool is_splittable_in_proportion = true; | |||
//! Split range. | //! Split range. | |||
/** The new Range *this has the second part split according to specifie d proportion, the old range r has the first part. | /** The new Range *this has the second part split according to specifie d proportion, the old range r has the first part. | |||
Unspecified if end()<begin() or !is_divisible(). */ | Unspecified if end()<begin() or !is_divisible(). */ | |||
blocked_range( blocked_range& r, proportional_split& proportion ) : | blocked_range( blocked_range& r, proportional_split& proportion ) : | |||
my_end(r.my_end), | my_end(r.my_end), | |||
my_begin(do_split(r, proportion)), | my_begin(do_split(r, proportion)), | |||
my_grainsize(r.my_grainsize) | my_grainsize(r.my_grainsize) | |||
{ | { | |||
// only comparison 'less than' is required from values of blocked_r ange objects | // only comparison 'less than' is required from values of blocked_r ange objects | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
blocked_range2d.h | blocked_range2d.h | |||
---|---|---|---|---|
skipping to change at line 79 | skipping to change at line 79 | |||
blocked_range2d( blocked_range2d& r, split ) : | blocked_range2d( blocked_range2d& r, split ) : | |||
my_rows(r.my_rows), | my_rows(r.my_rows), | |||
my_cols(r.my_cols) | my_cols(r.my_cols) | |||
{ | { | |||
split split_obj; | split split_obj; | |||
do_split(r, split_obj); | do_split(r, split_obj); | |||
} | } | |||
#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES | #if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES | |||
//! Static field to support proportional split | //! Static field to support proportional split | |||
static const bool is_divisible_in_proportion = true; | static const bool is_splittable_in_proportion = true; | |||
blocked_range2d( blocked_range2d& r, proportional_split& proportion ) : | blocked_range2d( blocked_range2d& r, proportional_split& proportion ) : | |||
my_rows(r.my_rows), | my_rows(r.my_rows), | |||
my_cols(r.my_cols) | my_cols(r.my_cols) | |||
{ | { | |||
do_split(r, proportion); | do_split(r, proportion); | |||
} | } | |||
#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ | #endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ | |||
template <typename Split> | template <typename Split> | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
blocked_range3d.h | blocked_range3d.h | |||
---|---|---|---|---|
skipping to change at line 86 | skipping to change at line 86 | |||
my_pages(r.my_pages), | my_pages(r.my_pages), | |||
my_rows(r.my_rows), | my_rows(r.my_rows), | |||
my_cols(r.my_cols) | my_cols(r.my_cols) | |||
{ | { | |||
split split_obj; | split split_obj; | |||
do_split(r, split_obj); | do_split(r, split_obj); | |||
} | } | |||
#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES | #if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES | |||
//! Static field to support proportional split | //! Static field to support proportional split | |||
static const bool is_divisible_in_proportion = true; | static const bool is_splittable_in_proportion = true; | |||
blocked_range3d( blocked_range3d& r, proportional_split& proportion ) : | blocked_range3d( blocked_range3d& r, proportional_split& proportion ) : | |||
my_pages(r.my_pages), | my_pages(r.my_pages), | |||
my_rows(r.my_rows), | my_rows(r.my_rows), | |||
my_cols(r.my_cols) | my_cols(r.my_cols) | |||
{ | { | |||
do_split(r, proportion); | do_split(r, proportion); | |||
} | } | |||
#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ | #endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
partitioner.h | partitioner.h | |||
---|---|---|---|---|
skipping to change at line 275 | skipping to change at line 275 | |||
} while( !range_pool.empty() && !start.is_cancelled() ); | } while( !range_pool.empty() && !start.is_cancelled() ); | |||
} | } | |||
} | } | |||
}; | }; | |||
//! Provides default methods for auto (adaptive) partition objects. | //! Provides default methods for auto (adaptive) partition objects. | |||
template <typename Partition> | template <typename Partition> | |||
struct adaptive_partition_type_base : partition_type_base<Partition> { | struct adaptive_partition_type_base : partition_type_base<Partition> { | |||
size_t my_divisor; | size_t my_divisor; | |||
depth_t my_max_depth; | depth_t my_max_depth; | |||
static const unsigned factor = 1; | ||||
adaptive_partition_type_base() : my_max_depth(__TBB_INIT_DEPTH) { | adaptive_partition_type_base() : my_max_depth(__TBB_INIT_DEPTH) { | |||
my_divisor = tbb::internal::get_initial_auto_partitioner_divisor() / 4; | my_divisor = tbb::internal::get_initial_auto_partitioner_divisor() / 4 * Partition::factor; | |||
__TBB_ASSERT(my_divisor, "initial value of get_initial_auto_partiti oner_divisor() is not valid"); | __TBB_ASSERT(my_divisor, "initial value of get_initial_auto_partiti oner_divisor() is not valid"); | |||
} | } | |||
adaptive_partition_type_base(adaptive_partition_type_base &src, split) { | adaptive_partition_type_base(adaptive_partition_type_base &src, split) { | |||
my_max_depth = src.my_max_depth; | my_max_depth = src.my_max_depth; | |||
#if TBB_USE_ASSERT | #if TBB_USE_ASSERT | |||
size_t old_divisor = src.my_divisor; | size_t old_divisor = src.my_divisor; | |||
#endif | #endif | |||
#if __TBB_INITIAL_TASK_IMBALANCE | #if __TBB_INITIAL_TASK_IMBALANCE | |||
if( src.my_divisor <= 1 ) my_divisor = 0; | if( src.my_divisor <= 1 ) my_divisor = 0; | |||
skipping to change at line 302 | skipping to change at line 303 | |||
#endif | #endif | |||
// For affinity_partitioner, my_divisor indicates the number of aff inity array indices the task reserves. | // For affinity_partitioner, my_divisor indicates the number of aff inity array indices the task reserves. | |||
// A task which has only one index must produce the right split wit hout reserved index in order to avoid | // A task which has only one index must produce the right split wit hout reserved index in order to avoid | |||
// it to be overwritten in note_affinity() of the created (right) t ask. | // it to be overwritten in note_affinity() of the created (right) t ask. | |||
// I.e. a task created deeper than the affinity array can remember must not save its affinity (LIFO order) | // I.e. a task created deeper than the affinity array can remember must not save its affinity (LIFO order) | |||
__TBB_ASSERT( (old_divisor <= 1 && my_divisor == 0) || | __TBB_ASSERT( (old_divisor <= 1 && my_divisor == 0) || | |||
(old_divisor > 1 && my_divisor != 0), NULL); | (old_divisor > 1 && my_divisor != 0), NULL); | |||
} | } | |||
adaptive_partition_type_base(adaptive_partition_type_base &src, const p roportional_split& split_obj) { | adaptive_partition_type_base(adaptive_partition_type_base &src, const p roportional_split& split_obj) { | |||
my_max_depth = src.my_max_depth; | my_max_depth = src.my_max_depth; | |||
#if __TBB_ENABLE_RANGE_FEEDBACK | ||||
my_divisor = size_t(float(src.my_divisor) * float(split_obj.right() ) | my_divisor = size_t(float(src.my_divisor) * float(split_obj.right() ) | |||
/ float(split_obj.left() + split_obj.right())); | / float(split_obj.left() + split_obj.right())); | |||
#else | ||||
my_divisor = split_obj.right() * Partition::factor; | ||||
#endif | ||||
src.my_divisor -= my_divisor; | src.my_divisor -= my_divisor; | |||
} | } | |||
bool check_being_stolen( task &t) { // part of old should_execute_range () | bool check_being_stolen( task &t) { // part of old should_execute_range () | |||
if( !my_divisor ) { // if not from the top P tasks of binary tree | if( !my_divisor ) { // if not from the top P tasks of binary tree | |||
my_divisor = 1; // TODO: replace by on-stack flag (partition_st ate's member)? | my_divisor = 1; // TODO: replace by on-stack flag (partition_st ate's member)? | |||
if( t.is_stolen_task() && t.parent()->ref_count() >= 2 ) { // r uns concurrently with the left task | if( t.is_stolen_task() && t.parent()->ref_count() >= 2 ) { // r uns concurrently with the left task | |||
#if TBB_USE_EXCEPTIONS | #if TBB_USE_EXCEPTIONS | |||
// RTTI is available, check whether the cast is valid | // RTTI is available, check whether the cast is valid | |||
__TBB_ASSERT(dynamic_cast<flag_task*>(t.parent()), 0); | __TBB_ASSERT(dynamic_cast<flag_task*>(t.parent()), 0); | |||
// correctness of the cast relies on avoiding the root task for which: | // correctness of the cast relies on avoiding the root task for which: | |||
skipping to change at line 332 | skipping to change at line 337 | |||
} | } | |||
return false; | return false; | |||
} | } | |||
void align_depth(depth_t base) { | void align_depth(depth_t base) { | |||
__TBB_ASSERT(base <= my_max_depth, 0); | __TBB_ASSERT(base <= my_max_depth, 0); | |||
my_max_depth -= base; | my_max_depth -= base; | |||
} | } | |||
depth_t max_depth() { return my_max_depth; } | depth_t max_depth() { return my_max_depth; } | |||
}; | }; | |||
//! Helper that enables one or the other code branches (see example in is_r ange_divisible_in_proportion) | //! Helper that enables one or the other code branches (see example in is_s plittable_in_proportion) | |||
template<bool C, typename T = void> struct enable_if { typedef T type; }; | template<bool C, typename T = void> struct enable_if { typedef T type; }; | |||
template<typename T> struct enable_if<false, T> { }; | template<typename T> struct enable_if<false, T> { }; | |||
//! Class determines whether template parameter has static boolean | //! Class determines whether template parameter has static boolean constant | |||
//! constant 'is_divisible_in_proportion' initialized with value of | //! 'is_splittable_in_proportion' initialized with value of 'true' or not. | |||
//! 'true' or not. | /** If template parameter has such field that has been initialized with non | |||
/** If template parameter has such field that has been initialized | -zero | |||
* with non-zero value then class field will be set to 'true', | * value then class field will be set to 'true', otherwise - 'false' | |||
* otherwise - 'false' | ||||
*/ | */ | |||
template <typename Range> | template <typename Range> | |||
class is_range_divisible_in_proportion { | class is_splittable_in_proportion { | |||
private: | private: | |||
typedef char yes[1]; | typedef char yes[1]; | |||
typedef char no [2]; | typedef char no [2]; | |||
template <typename range_type> static yes& decide(typename enable_if<ra nge_type::is_divisible_in_proportion>::type *); | template <typename range_type> static yes& decide(typename enable_if<ra nge_type::is_splittable_in_proportion>::type *); | |||
template <typename range_type> static no& decide(...); | template <typename range_type> static no& decide(...); | |||
public: | public: | |||
// equals to 'true' if and only if static const variable 'is_divisible_ in_proportion' of template parameter | // equals to 'true' if and only if static const variable 'is_splittable _in_proportion' of template parameter | |||
// initialized with the value of 'true' | // initialized with the value of 'true' | |||
static const bool value = (sizeof(decide<Range>(0)) == sizeof(yes)); | static const bool value = (sizeof(decide<Range>(0)) == sizeof(yes)); | |||
}; | }; | |||
//! Provides default methods for affinity (adaptive) partition objects. | //! Provides default methods for affinity (adaptive) partition objects. | |||
class affinity_partition_type : public adaptive_partition_type_base<affinit y_partition_type> { | class affinity_partition_type : public adaptive_partition_type_base<affinit y_partition_type> { | |||
static const unsigned factor_power = 4; | static const unsigned factor_power = 4; | |||
static const unsigned factor = 1<<factor_power; // number of slots in affinity array per task | ||||
enum { | enum { | |||
start = 0, | start = 0, | |||
run, | run, | |||
pass | pass | |||
} my_delay; | } my_delay; | |||
#ifdef __TBB_USE_MACHINE_TIME_STAMPS | #ifdef __TBB_USE_MACHINE_TIME_STAMPS | |||
machine_tsc_t my_dst_tsc; | machine_tsc_t my_dst_tsc; | |||
#endif | #endif | |||
size_t my_begin; | size_t my_begin; | |||
tbb::internal::affinity_id* my_array; | tbb::internal::affinity_id* my_array; | |||
public: | public: | |||
static const unsigned factor = 1 << factor_power; // number of slots in affinity array per task | ||||
typedef proportional_split split_type; | typedef proportional_split split_type; | |||
affinity_partition_type( tbb::internal::affinity_partitioner_base_v3& a p ) | affinity_partition_type( tbb::internal::affinity_partitioner_base_v3& a p ) | |||
: adaptive_partition_type_base<affinity_partition_type>(), | : adaptive_partition_type_base<affinity_partition_type>(), my_delay | |||
my_delay(start) | (start) | |||
#ifdef __TBB_USE_MACHINE_TIME_STAMPS | #ifdef __TBB_USE_MACHINE_TIME_STAMPS | |||
, my_dst_tsc(0) | , my_dst_tsc(0) | |||
#endif | #endif | |||
{ | { | |||
__TBB_ASSERT( (factor&(factor-1))==0, "factor must be power of two" ); | __TBB_ASSERT( (factor&(factor-1))==0, "factor must be power of two" ); | |||
my_divisor *= factor; | ||||
ap.resize(factor); | ap.resize(factor); | |||
my_array = ap.my_array; | my_array = ap.my_array; | |||
my_begin = 0; | my_begin = 0; | |||
my_max_depth = factor_power + 1; // the first factor_power ranges w ill be spawned, and >=1 ranges should be left | my_max_depth = factor_power + 1; // the first factor_power ranges w ill be spawned, and >=1 ranges should be left | |||
__TBB_ASSERT( my_max_depth < __TBB_RANGE_POOL_CAPACITY, 0 ); | __TBB_ASSERT( my_max_depth < __TBB_RANGE_POOL_CAPACITY, 0 ); | |||
} | } | |||
affinity_partition_type(affinity_partition_type& p, split) | affinity_partition_type(affinity_partition_type& p, split) | |||
: adaptive_partition_type_base<affinity_partition_type>(p, split()) , | : adaptive_partition_type_base<affinity_partition_type>(p, split()) , | |||
my_delay(pass), | my_delay(pass), | |||
#ifdef __TBB_USE_MACHINE_TIME_STAMPS | #ifdef __TBB_USE_MACHINE_TIME_STAMPS | |||
skipping to change at line 410 | skipping to change at line 411 | |||
affinity_partition_type(affinity_partition_type& p, const proportional_ split& split_obj) | affinity_partition_type(affinity_partition_type& p, const proportional_ split& split_obj) | |||
: adaptive_partition_type_base<affinity_partition_type>(p, split_ob j), | : adaptive_partition_type_base<affinity_partition_type>(p, split_ob j), | |||
my_delay(start), | my_delay(start), | |||
#ifdef __TBB_USE_MACHINE_TIME_STAMPS | #ifdef __TBB_USE_MACHINE_TIME_STAMPS | |||
my_dst_tsc(0), | my_dst_tsc(0), | |||
#endif | #endif | |||
my_array(p.my_array) { | my_array(p.my_array) { | |||
size_t total_divisor = my_divisor + p.my_divisor; | size_t total_divisor = my_divisor + p.my_divisor; | |||
__TBB_ASSERT(total_divisor % factor == 0, NULL); | __TBB_ASSERT(total_divisor % factor == 0, NULL); | |||
my_divisor = (my_divisor + factor/2) & (0u - factor); | my_divisor = (my_divisor + factor/2) & (0u - factor); | |||
#if __TBB_ENABLE_RANGE_FEEDBACK | ||||
if (!my_divisor) | if (!my_divisor) | |||
my_divisor = factor; | my_divisor = factor; | |||
else if (my_divisor == total_divisor) | else if (my_divisor == total_divisor) | |||
my_divisor = total_divisor - factor; | my_divisor = total_divisor - factor; | |||
#endif | ||||
p.my_divisor = total_divisor - my_divisor; | p.my_divisor = total_divisor - my_divisor; | |||
__TBB_ASSERT(my_divisor && p.my_divisor, NULL); | __TBB_ASSERT(my_divisor && p.my_divisor, NULL); | |||
my_begin = p.my_begin + p.my_divisor; | my_begin = p.my_begin + p.my_divisor; | |||
} | } | |||
void set_affinity( task &t ) { | void set_affinity( task &t ) { | |||
if( my_divisor ) { | if( my_divisor ) { | |||
if( !my_array[my_begin] ) { | if( !my_array[my_begin] ) | |||
// TODO: consider code reuse for static_paritioner | // TODO: consider code reuse for static_paritioner | |||
my_array[my_begin] = affinity_id(my_begin / factor + 1); | t.set_affinity( affinity_id(my_begin / factor + 1) ); | |||
} | else | |||
t.set_affinity( my_array[my_begin] ); | t.set_affinity( my_array[my_begin] ); | |||
} | } | |||
} | } | |||
void note_affinity( task::affinity_id id ) { | void note_affinity( task::affinity_id id ) { | |||
if( my_divisor ) | if( my_divisor ) | |||
my_array[my_begin] = id; | my_array[my_begin] = id; | |||
} | } | |||
bool check_for_demand( task &t ) { | bool check_for_demand( task &t ) { | |||
if( pass == my_delay ) { | if( pass == my_delay ) { | |||
if( my_divisor > 1 ) // produce affinitized tasks while they ha ve slot in array | if( my_divisor > 1 ) // produce affinitized tasks while they ha ve slot in array | |||
return true; // do not do my_max_depth++ here, but be sure range_pool is splittable once more | return true; // do not do my_max_depth++ here, but be sure range_pool is splittable once more | |||
skipping to change at line 471 | skipping to change at line 474 | |||
return my_divisor > factor; | return my_divisor > factor; | |||
} | } | |||
#if _MSC_VER && !defined(__INTEL_COMPILER) | #if _MSC_VER && !defined(__INTEL_COMPILER) | |||
// Suppress "conditional expression is constant" warning. | // Suppress "conditional expression is constant" warning. | |||
#pragma warning( push ) | #pragma warning( push ) | |||
#pragma warning( disable: 4127 ) | #pragma warning( disable: 4127 ) | |||
#endif | #endif | |||
template <typename Range> | template <typename Range> | |||
split_type get_split() { | split_type get_split() { | |||
if (is_range_divisible_in_proportion<Range>::value) { | if (is_splittable_in_proportion<Range>::value) { | |||
size_t size = my_divisor / factor; | size_t size = my_divisor / factor; | |||
#if __TBB_NONUNIFORM_TASK_CREATION | #if __TBB_NONUNIFORM_TASK_CREATION | |||
size_t right = (size + 2) / 3; | size_t right = (size + 2) / 3; | |||
#else | #else | |||
size_t right = size / 2; | size_t right = size / 2; | |||
#endif | #endif | |||
size_t left = size - right; | size_t left = size - right; | |||
return split_type(left, right); | return split_type(left, right); | |||
} else { | } else { | |||
return split_type(1, 1); | return split_type(1, 1); | |||
End of changes. 19 change blocks. | ||||
21 lines changed or deleted | 26 lines changed or added | |||
tbb_config.h | tbb_config.h | |||
---|---|---|---|---|
skipping to change at line 450 | skipping to change at line 450 | |||
#else | #else | |||
/** Default partitioner for parallel loop templates since TBB 2.2 */ | /** Default partitioner for parallel loop templates since TBB 2.2 */ | |||
#define __TBB_DEFAULT_PARTITIONER tbb::auto_partitioner | #define __TBB_DEFAULT_PARTITIONER tbb::auto_partitioner | |||
#endif /* TBB_DEPRECATED */ | #endif /* TBB_DEPRECATED */ | |||
#endif /* !defined(__TBB_DEFAULT_PARTITIONER */ | #endif /* !defined(__TBB_DEFAULT_PARTITIONER */ | |||
#ifndef __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES | #ifndef __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES | |||
#define __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES 1 | #define __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES 1 | |||
#endif | #endif | |||
#ifndef __TBB_ENABLE_RANGE_FEEDBACK | ||||
#define __TBB_ENABLE_RANGE_FEEDBACK 0 | ||||
#endif | ||||
#ifdef _VARIADIC_MAX | #ifdef _VARIADIC_MAX | |||
#define __TBB_VARIADIC_MAX _VARIADIC_MAX | #define __TBB_VARIADIC_MAX _VARIADIC_MAX | |||
#else | #else | |||
#if _MSC_VER >= 1700 | #if _MSC_VER >= 1700 | |||
#define __TBB_VARIADIC_MAX 5 /* current VS11 setting, may change. */ | #define __TBB_VARIADIC_MAX 5 /* current VS11 setting, may change. */ | |||
#else | #else | |||
#define __TBB_VARIADIC_MAX 10 | #define __TBB_VARIADIC_MAX 10 | |||
#endif | #endif | |||
#endif | #endif | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 4 lines changed or added | |||
tbb_stddef.h | tbb_stddef.h | |||
---|---|---|---|---|
skipping to change at line 29 | skipping to change at line 29 | |||
*/ | */ | |||
#ifndef __TBB_tbb_stddef_H | #ifndef __TBB_tbb_stddef_H | |||
#define __TBB_tbb_stddef_H | #define __TBB_tbb_stddef_H | |||
// Marketing-driven product version | // Marketing-driven product version | |||
#define TBB_VERSION_MAJOR 4 | #define TBB_VERSION_MAJOR 4 | |||
#define TBB_VERSION_MINOR 3 | #define TBB_VERSION_MINOR 3 | |||
// Engineering-focused interface version | // Engineering-focused interface version | |||
#define TBB_INTERFACE_VERSION 8000 | #define TBB_INTERFACE_VERSION 8001 | |||
#define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000 | #define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000 | |||
// The oldest major interface version still supported | // The oldest major interface version still supported | |||
// To be used in SONAME, manifests, etc. | // To be used in SONAME, manifests, etc. | |||
#define TBB_COMPATIBLE_INTERFACE_VERSION 2 | #define TBB_COMPATIBLE_INTERFACE_VERSION 2 | |||
#define __TBB_STRING_AUX(x) #x | #define __TBB_STRING_AUX(x) #x | |||
#define __TBB_STRING(x) __TBB_STRING_AUX(x) | #define __TBB_STRING(x) __TBB_STRING_AUX(x) | |||
// We do not need defines below for resource processing on windows | // We do not need defines below for resource processing on windows | |||
skipping to change at line 210 | skipping to change at line 210 | |||
using std::size_t; | using std::size_t; | |||
using std::ptrdiff_t; | using std::ptrdiff_t; | |||
//! The function returns the interface version of the TBB shared library be ing used. | //! The function returns the interface version of the TBB shared library be ing used. | |||
/** | /** | |||
* The version it returns is determined at runtime, not at compile/link tim e. | * The version it returns is determined at runtime, not at compile/link tim e. | |||
* So it can be different than the value of TBB_INTERFACE_VERSION obtained at compile time. | * So it can be different than the value of TBB_INTERFACE_VERSION obtained at compile time. | |||
*/ | */ | |||
extern "C" int __TBB_EXPORTED_FUNC TBB_runtime_interface_version(); | extern "C" int __TBB_EXPORTED_FUNC TBB_runtime_interface_version(); | |||
//! Dummy type that distinguishes splitting constructor from copy construct | ||||
or. | ||||
/** | ||||
* See description of parallel_for and parallel_reduce for example usages. | ||||
* @ingroup algorithms | ||||
*/ | ||||
class split { | ||||
}; | ||||
//! Type enables transmission of splitting proportion from partitioners to | ||||
range objects | ||||
/** | ||||
* In order to make use of such facility Range objects must implement | ||||
* splitting constructor with this type passed and initialize static | ||||
* constant boolean field 'is_divisible_in_proportion' with the value | ||||
* of 'true' | ||||
*/ | ||||
class proportional_split { | ||||
public: | ||||
proportional_split(size_t _left = 1, size_t _right = 1) : my_left(_left | ||||
), my_right(_right) { } | ||||
proportional_split(split) : my_left(1), my_right(1) { } | ||||
size_t left() const { return my_left; } | ||||
size_t right() const { return my_right; } | ||||
void set_proportion(size_t _left, size_t _right) { | ||||
my_left = _left; | ||||
my_right = _right; | ||||
} | ||||
// used when range does not support proportional split | ||||
operator split() const { return split(); } | ||||
private: | ||||
size_t my_left, my_right; | ||||
}; | ||||
/** | /** | |||
* @cond INTERNAL | * @cond INTERNAL | |||
* @brief Identifiers declared inside namespace internal should never be us ed directly by client code. | * @brief Identifiers declared inside namespace internal should never be us ed directly by client code. | |||
*/ | */ | |||
namespace internal { | namespace internal { | |||
//! Compile-time constant that is upper bound on cache line/sector size. | //! Compile-time constant that is upper bound on cache line/sector size. | |||
/** It should be used only in situations where having a compile-time upper | /** It should be used only in situations where having a compile-time upper | |||
bound is more useful than a run-time exact answer. | bound is more useful than a run-time exact answer. | |||
@ingroup memory_allocation */ | @ingroup memory_allocation */ | |||
skipping to change at line 402 | skipping to change at line 368 | |||
// i.e. for strictly positive i and j, with j a power of 2, | // i.e. for strictly positive i and j, with j a power of 2, | |||
// determines whether i==j<<k for some nonnegative k (so i==j yields true). | // determines whether i==j<<k for some nonnegative k (so i==j yields true). | |||
template<typename argument_integer_type, typename divisor_integer_type> | template<typename argument_integer_type, typename divisor_integer_type> | |||
inline bool is_power_of_two_factor(argument_integer_type arg, divisor_integ er_type divisor) { | inline bool is_power_of_two_factor(argument_integer_type arg, divisor_integ er_type divisor) { | |||
// Divisor is assumed to be a power of two (which is valid for current uses). | // Divisor is assumed to be a power of two (which is valid for current uses). | |||
__TBB_ASSERT( is_power_of_two(divisor), "Divisor should be a power of t wo" ); | __TBB_ASSERT( is_power_of_two(divisor), "Divisor should be a power of t wo" ); | |||
return 0 == (arg & (arg - divisor)); | return 0 == (arg & (arg - divisor)); | |||
} | } | |||
//! Utility template function to prevent "unused" warnings by various compi lers. | //! Utility template function to prevent "unused" warnings by various compi lers. | |||
template<typename T> | template<typename T1> void suppress_unused_warning( const T1& ) {} | |||
void suppress_unused_warning( const T& ) {} | template<typename T1, typename T2> void suppress_unused_warning( const T1&, | |||
const T2& ) {} | ||||
template<typename T1, typename T2, typename T3> void suppress_unused_warnin | ||||
g( const T1&, const T2&, const T3& ) {} | ||||
// Struct to be used as a version tag for inline functions. | // Struct to be used as a version tag for inline functions. | |||
/** Version tag can be necessary to prevent loader on Linux from using the wrong | /** Version tag can be necessary to prevent loader on Linux from using the wrong | |||
symbol in debug builds (when inline functions are compiled as out-of-li ne). **/ | symbol in debug builds (when inline functions are compiled as out-of-li ne). **/ | |||
struct version_tag_v3 {}; | struct version_tag_v3 {}; | |||
typedef version_tag_v3 version_tag; | typedef version_tag_v3 version_tag; | |||
} // internal | } // internal | |||
//! Dummy type that distinguishes splitting constructor from copy construct | ||||
or. | ||||
/** | ||||
* See description of parallel_for and parallel_reduce for example usages. | ||||
* @ingroup algorithms | ||||
*/ | ||||
class split { | ||||
}; | ||||
//! Type enables transmission of splitting proportion from partitioners to | ||||
range objects | ||||
/** | ||||
* In order to make use of such facility Range objects must implement | ||||
* splitting constructor with this type passed and initialize static | ||||
* constant boolean field 'is_splittable_in_proportion' with the value | ||||
* of 'true' | ||||
*/ | ||||
class proportional_split: internal::no_assign { | ||||
public: | ||||
proportional_split(size_t _left = 1, size_t _right = 1) : my_left(_left | ||||
), my_right(_right) { } | ||||
size_t left() const { return my_left; } | ||||
size_t right() const { return my_right; } | ||||
// used when range does not support proportional split | ||||
operator split() const { return split(); } | ||||
#if __TBB_ENABLE_RANGE_FEEDBACK | ||||
void set_proportion(size_t _left, size_t _right) { | ||||
my_left = _left; | ||||
my_right = _right; | ||||
} | ||||
#endif | ||||
private: | ||||
size_t my_left, my_right; | ||||
}; | ||||
} // tbb | } // tbb | |||
// Following is a set of classes and functions typically used in compile-ti me "metaprogramming". | // Following is a set of classes and functions typically used in compile-ti me "metaprogramming". | |||
// TODO: move all that to a separate header | // TODO: move all that to a separate header | |||
#if __TBB_ALLOCATOR_TRAITS_PRESENT | #if __TBB_ALLOCATOR_TRAITS_PRESENT | |||
#include <memory> //for allocator_traits | #include <memory> //for allocator_traits | |||
#endif | #endif | |||
#if __TBB_CPP11_RVALUE_REF_PRESENT || _LIBCPP_VERSION | #if __TBB_CPP11_RVALUE_REF_PRESENT || _LIBCPP_VERSION | |||
End of changes. 4 change blocks. | ||||
40 lines changed or deleted | 45 lines changed or added | |||