_concurrent_queue_impl.h   _concurrent_queue_impl.h 
skipping to change at line 219 skipping to change at line 219
micro_queue& assign( const micro_queue& src, concurrent_queue_base_v3<T >& base ) ; micro_queue& assign( const micro_queue& src, concurrent_queue_base_v3<T >& base ) ;
page* make_copy( concurrent_queue_base_v3<T>& base, const page* src_pag e, size_t begin_in_page, size_t end_in_page, ticket& g_index ) ; page* make_copy( concurrent_queue_base_v3<T>& base, const page* src_pag e, size_t begin_in_page, size_t end_in_page, ticket& g_index ) ;
void invalidate_page_and_rethrow( ticket k ) ; void invalidate_page_and_rethrow( ticket k ) ;
}; };
template<typename T> template<typename T>
void micro_queue<T>::spin_wait_until_my_turn( atomic<ticket>& counter, tick et k, concurrent_queue_rep_base& rb ) const { void micro_queue<T>::spin_wait_until_my_turn( atomic<ticket>& counter, tick et k, concurrent_queue_rep_base& rb ) const {
atomic_backoff backoff; for( atomic_backoff b(true);;b.pause() ) {
do { ticket c = counter;
backoff.pause(); if( c==k ) return;
if( counter&1 ) { else if( c&1 ) {
++rb.n_invalid_entries; ++rb.n_invalid_entries;
throw_exception( eid_bad_last_alloc ); throw_exception( eid_bad_last_alloc );
} }
} while( counter!=k ) ; }
} }
template<typename T> template<typename T>
void micro_queue<T>::push( const void* item, ticket k, concurrent_queue_bas e_v3<T>& base ) { void micro_queue<T>::push( const void* item, ticket k, concurrent_queue_bas e_v3<T>& base ) {
k &= -concurrent_queue_rep_base::n_queue; k &= -concurrent_queue_rep_base::n_queue;
page* p = NULL; page* p = NULL;
size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queu e, base.my_rep->items_per_page); size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queu e, base.my_rep->items_per_page);
if( !index ) { if( !index ) {
__TBB_TRY { __TBB_TRY {
concurrent_queue_page_allocator& pa = base; concurrent_queue_page_allocator& pa = base;
 End of changes. 2 change blocks. 
5 lines changed or deleted 5 lines changed or added


 _flow_graph_node_impl.h   _flow_graph_node_impl.h 
skipping to change at line 485 skipping to change at line 485
my_body( new internal::function_body_leaf< input_type, output_ type, Body>(body) ) { } my_body( new internal::function_body_leaf< input_type, output_ type, Body>(body) ) { }
template< typename Body > template< typename Body >
continue_input( graph &g, int number_of_predecessors, Body& body ) continue_input( graph &g, int number_of_predecessors, Body& body )
: continue_receiver( number_of_predecessors ), my_root_task(g.r oot_task()), : continue_receiver( number_of_predecessors ), my_root_task(g.r oot_task()),
my_body( new internal::function_body_leaf< input_type, output_ type, Body>(body) ) { } my_body( new internal::function_body_leaf< input_type, output_ type, Body>(body) ) { }
continue_input( const continue_input& src ) : continue_receiver(src ), continue_input( const continue_input& src ) : continue_receiver(src ),
my_root_task(src.my_root_task), my_body( src.my_body->clone() ) {} my_root_task(src.my_root_task), my_body( src.my_body->clone() ) {}
~continue_input() {
delete my_body;
}
template< typename Body > template< typename Body >
Body copy_function_object() { Body copy_function_object() {
internal::function_body<input_type, output_type> &body_ref = *m y_body; internal::function_body<input_type, output_type> &body_ref = *m y_body;
return dynamic_cast< internal::function_body_leaf<input_type, o utput_type, Body> & >(body_ref).get_body(); return dynamic_cast< internal::function_body_leaf<input_type, o utput_type, Body> & >(body_ref).get_body();
} }
protected: protected:
task *my_root_task; task *my_root_task;
function_body<input_type, output_type> *my_body; function_body<input_type, output_type> *my_body;
 End of changes. 1 change blocks. 
0 lines changed or deleted 4 lines changed or added


 concurrent_hash_map.h   concurrent_hash_map.h 
skipping to change at line 1007 skipping to change at line 1007
goto restart; // b.release() is done in ~b(). TODO: rep lace by continue goto restart; // b.release() is done in ~b(). TODO: rep lace by continue
return false; return false;
} }
return_value = true; return_value = true;
} }
exists: exists:
if( !result ) goto check_growth; if( !result ) goto check_growth;
// TODO: the following seems as generic/regular operation // TODO: the following seems as generic/regular operation
// acquire the item // acquire the item
if( !result->try_acquire( n->mutex, write ) ) { if( !result->try_acquire( n->mutex, write ) ) {
// we are unlucky, prepare for longer wait for( tbb::internal::atomic_backoff backoff(true);; ) {
tbb::internal::atomic_backoff trials; if( result->try_acquire( n->mutex, write ) ) break;
do { if( !backoff.bounded_pause() ) {
if( !trials.bounded_pause() ) {
// the wait takes really long, restart the operation // the wait takes really long, restart the operation
b.release(); b.release();
__TBB_ASSERT( !op_insert || !return_value, "Can't acqui re new item in locked bucket?" ); __TBB_ASSERT( !op_insert || !return_value, "Can't acqui re new item in locked bucket?" );
__TBB_Yield(); __TBB_Yield();
m = (hashcode_t) itt_load_word_with_acquire( my_mask ); m = (hashcode_t) itt_load_word_with_acquire( my_mask );
goto restart; goto restart;
} }
} while( !result->try_acquire( n->mutex, write ) ); }
} }
}//lock scope }//lock scope
result->my_node = n; result->my_node = n;
result->my_hash = h; result->my_hash = h;
check_growth: check_growth:
// [opt] grow the container // [opt] grow the container
if( grow_segment ) { if( grow_segment ) {
#if __TBB_STATISTICS #if __TBB_STATISTICS
my_info_resizes++; // concurrent ones my_info_resizes++; // concurrent ones
#endif #endif
 End of changes. 2 change blocks. 
5 lines changed or deleted 4 lines changed or added


 concurrent_priority_queue.h   concurrent_priority_queue.h 
skipping to change at line 42 skipping to change at line 42
#include "atomic.h" #include "atomic.h"
#include "cache_aligned_allocator.h" #include "cache_aligned_allocator.h"
#include "tbb_exception.h" #include "tbb_exception.h"
#include "tbb_stddef.h" #include "tbb_stddef.h"
#include "tbb_profiling.h" #include "tbb_profiling.h"
#include "internal/_aggregator_impl.h" #include "internal/_aggregator_impl.h"
#include <vector> #include <vector>
#include <iterator> #include <iterator>
#include <functional> #include <functional>
#if __TBB_INITIALIZER_LISTS_PRESENT
#include <initializer_list>
#endif
namespace tbb { namespace tbb {
namespace interface5 { namespace interface5 {
using namespace tbb::internal; using namespace tbb::internal;
//! Concurrent priority queue //! Concurrent priority queue
template <typename T, typename Compare=std::less<T>, typename A=cache_align ed_allocator<T> > template <typename T, typename Compare=std::less<T>, typename A=cache_align ed_allocator<T> >
class concurrent_priority_queue { class concurrent_priority_queue {
public: public:
//! Element type in the queue. //! Element type in the queue.
skipping to change at line 86 skipping to change at line 90
explicit concurrent_priority_queue(size_type init_capacity, const alloc ator_type& a = allocator_type()) : explicit concurrent_priority_queue(size_type init_capacity, const alloc ator_type& a = allocator_type()) :
mark(0), my_size(0), data(a) mark(0), my_size(0), data(a)
{ {
data.reserve(init_capacity); data.reserve(init_capacity);
my_aggregator.initialize_handler(my_functor_t(this)); my_aggregator.initialize_handler(my_functor_t(this));
} }
//! [begin,end) constructor //! [begin,end) constructor
template<typename InputIterator> template<typename InputIterator>
concurrent_priority_queue(InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) : concurrent_priority_queue(InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) :
data(begin, end, a) mark(0), data(begin, end, a)
{ {
mark = 0;
my_aggregator.initialize_handler(my_functor_t(this)); my_aggregator.initialize_handler(my_functor_t(this));
heapify(); heapify();
my_size = data.size(); my_size = data.size();
} }
#if __TBB_INITIALIZER_LISTS_PRESENT
//! Constructor from std::initializer_list
concurrent_priority_queue(std::initializer_list<T> const& init_list, co
nst allocator_type &a = allocator_type()) :
mark(0),data(init_list.begin(), init_list.end(), a)
{
my_aggregator.initialize_handler(my_functor_t(this));
heapify();
my_size = data.size();
}
#endif //# __TBB_INITIALIZER_LISTS_PRESENT
//! Copy constructor //! Copy constructor
/** This operation is unsafe if there are pending concurrent operations on the src queue. */ /** This operation is unsafe if there are pending concurrent operations on the src queue. */
explicit concurrent_priority_queue(const concurrent_priority_queue& src ) : mark(src.mark), explicit concurrent_priority_queue(const concurrent_priority_queue& src ) : mark(src.mark),
my_size(src.my_size), data(src.data.begin(), src.data.end(), src.da ta.get_allocator()) my_size(src.my_size), data(src.data.begin(), src.data.end(), src.da ta.get_allocator())
{ {
my_aggregator.initialize_handler(my_functor_t(this)); my_aggregator.initialize_handler(my_functor_t(this));
heapify(); heapify();
} }
//! Copy constructor with specific allocator //! Copy constructor with specific allocator
skipping to change at line 123 skipping to change at line 137
/** This operation is unsafe if there are pending concurrent operations on the src queue. */ /** This operation is unsafe if there are pending concurrent operations on the src queue. */
concurrent_priority_queue& operator=(const concurrent_priority_queue& s rc) { concurrent_priority_queue& operator=(const concurrent_priority_queue& s rc) {
if (this != &src) { if (this != &src) {
std::vector<value_type, allocator_type>(src.data.begin(), src.d ata.end(), src.data.get_allocator()).swap(data); std::vector<value_type, allocator_type>(src.data.begin(), src.d ata.end(), src.data.get_allocator()).swap(data);
mark = src.mark; mark = src.mark;
my_size = src.my_size; my_size = src.my_size;
} }
return *this; return *this;
} }
//! Assign the queue from [begin,end) range, not thread-safe
template<typename InputIterator>
void assign(InputIterator begin, InputIterator end) {
std::vector<value_type, allocator_type>(begin, end, data.get_alloca
tor()).swap(data);
mark = 0;
my_size = data.size();
heapify();
}
#if __TBB_INITIALIZER_LISTS_PRESENT
//! Assign the queue from std::initializer_list, not thread-safe
void assign(std::initializer_list<T> const& il) { this->assign(il.begin
(), il.end()); }
//! Assign from std::initializer_list, not thread-safe
concurrent_priority_queue& operator=(std::initializer_list<T> const& il
) {
this->assign(il.begin(), il.end());
return *this;
}
#endif //# __TBB_INITIALIZER_LISTS_PRESENT
//! Returns true if empty, false otherwise //! Returns true if empty, false otherwise
/** Returned value may not reflect results of pending operations. /** Returned value may not reflect results of pending operations.
This operation reads shared data and will trigger a race condition. */ This operation reads shared data and will trigger a race condition. */
bool empty() const { return size()==0; } bool empty() const { return size()==0; }
//! Returns the current number of elements contained in the queue //! Returns the current number of elements contained in the queue
/** Returned value may not reflect results of pending operations. /** Returned value may not reflect results of pending operations.
This operation reads shared data and will trigger a race condition. */ This operation reads shared data and will trigger a race condition. */
size_type size() const { return __TBB_load_with_acquire(my_size); } size_type size() const { return __TBB_load_with_acquire(my_size); }
 End of changes. 5 change blocks. 
2 lines changed or deleted 40 lines changed or added


 flow_graph.h   flow_graph.h 
skipping to change at line 1959 skipping to change at line 1959
// template for tag_matching join_node // template for tag_matching join_node
template<typename OutputTuple> template<typename OutputTuple>
class join_node<OutputTuple, tag_matching> : public internal::unfolded_join _node<tbb::flow::tuple_size<OutputTuple>::value, class join_node<OutputTuple, tag_matching> : public internal::unfolded_join _node<tbb::flow::tuple_size<OutputTuple>::value,
tag_matching_port, OutputTuple, tag_matching> { tag_matching_port, OutputTuple, tag_matching> {
private: private:
static const int N = tbb::flow::tuple_size<OutputTuple>::value; static const int N = tbb::flow::tuple_size<OutputTuple>::value;
typedef typename internal::unfolded_join_node<N, tag_matching_port, Out putTuple, tag_matching> unfolded_type; typedef typename internal::unfolded_join_node<N, tag_matching_port, Out putTuple, tag_matching> unfolded_type;
public: public:
typedef OutputTuple output_type; typedef OutputTuple output_type;
typedef typename unfolded_type::input_ports_type input_ports_type; typedef typename unfolded_type::input_ports_type input_ports_type;
template<typename B0, typename B1> template<typename __TBB_B0, typename __TBB_B1>
join_node(graph &g, B0 b0, B1 b1) : unfolded_type(g, b0, b1) { } join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1) : unfolded_type(g, b0, b1
template<typename B0, typename B1, typename B2> ) { }
join_node(graph &g, B0 b0, B1 b1, B2 b2) : unfolded_type(g, b0, b1, b2) template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2>
{ } join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2) : unfolded_t
template<typename B0, typename B1, typename B2, typename B3> ype(g, b0, b1, b2) { }
join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3) : unfolded_type(g, b0, template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typen
b1, b2, b3) { } ame __TBB_B3>
template<typename B0, typename B1, typename B2, typename B3, typename B join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3)
4> : unfolded_type(g, b0, b1, b2, b3) { }
join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) : unfolded_type( template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typen
g, b0, b1, b2, b3, b4) { } ame __TBB_B3, typename __TBB_B4>
join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3,
__TBB_B4 b4) :
unfolded_type(g, b0, b1, b2, b3, b4) { }
#if __TBB_VARIADIC_MAX >= 6 #if __TBB_VARIADIC_MAX >= 6
template<typename B0, typename B1, typename B2, typename B3, typename B template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typen
4, typename B5> ame __TBB_B3, typename __TBB_B4,
join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5) : unfolde typename __TBB_B5>
d_type(g, b0, b1, b2, b3, b4, b5) { } join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3,
__TBB_B4 b4, __TBB_B5 b5) :
unfolded_type(g, b0, b1, b2, b3, b4, b5) { }
#endif #endif
#if __TBB_VARIADIC_MAX >= 7 #if __TBB_VARIADIC_MAX >= 7
template<typename B0, typename B1, typename B2, typename B3, typename B template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typen
4, typename B5, typename B6> ame __TBB_B3, typename __TBB_B4,
join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6) : typename __TBB_B5, typename __TBB_B6>
unfolded_type(g, b0, b1, b2, b3, b4, b5, b6) { } join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3,
__TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6) :
unfolded_type(g, b0, b1, b2, b3, b4, b5, b6) { }
#endif #endif
#if __TBB_VARIADIC_MAX >= 8 #if __TBB_VARIADIC_MAX >= 8
template<typename B0, typename B1, typename B2, typename B3, typename B template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typen
4, typename B5, typename B6, typename B7> ame __TBB_B3, typename __TBB_B4,
join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 typename __TBB_B5, typename __TBB_B6, typename __TBB_B7>
b7) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7) { } join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3,
__TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6,
__TBB_B7 b7) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7)
{ }
#endif #endif
#if __TBB_VARIADIC_MAX >= 9 #if __TBB_VARIADIC_MAX >= 9
template<typename B0, typename B1, typename B2, typename B3, typename B template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typen
4, typename B5, typename B6, typename B7, typename B8> ame __TBB_B3, typename __TBB_B4,
join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 typename __TBB_B5, typename __TBB_B6, typename __TBB_B7, typename _
b7, B8 b8) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8) { } _TBB_B8>
join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3,
__TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6,
__TBB_B7 b7, __TBB_B8 b8) : unfolded_type(g, b0, b1, b2, b3, b4
, b5, b6, b7, b8) { }
#endif #endif
#if __TBB_VARIADIC_MAX >= 10 #if __TBB_VARIADIC_MAX >= 10
template<typename B0, typename B1, typename B2, typename B3, typename B template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typen
4, typename B5, typename B6, typename B7, typename B8, typename B9> ame __TBB_B3, typename __TBB_B4,
join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 typename __TBB_B5, typename __TBB_B6, typename __TBB_B7, typename _
b7, B8 b8, B9 b9) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8, b _TBB_B8, typename __TBB_B9>
9) { } join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3,
__TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6,
__TBB_B7 b7, __TBB_B8 b8, __TBB_B9 b9) : unfolded_type(g, b0, b
1, b2, b3, b4, b5, b6, b7, b8, b9) { }
#endif #endif
join_node(const join_node &other) : unfolded_type(other) {} join_node(const join_node &other) : unfolded_type(other) {}
}; };
#if TBB_PREVIEW_GRAPH_NODES #if TBB_PREVIEW_GRAPH_NODES
// or node // or node
#include "internal/_flow_graph_or_impl.h" #include "internal/_flow_graph_or_impl.h"
template<typename InputTuple> template<typename InputTuple>
class or_node : public internal::unfolded_or_node<InputTuple> { class or_node : public internal::unfolded_or_node<InputTuple> {
 End of changes. 6 change blocks. 
33 lines changed or deleted 50 lines changed or added


 linux_ia32.h   linux_ia32.h 
skipping to change at line 161 skipping to change at line 161
#endif // warning 998 is back #endif // warning 998 is back
static inline void __TBB_machine_or( volatile void *ptr, uint32_t addend ) { static inline void __TBB_machine_or( volatile void *ptr, uint32_t addend ) {
__asm__ __volatile__("lock\norl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory"); __asm__ __volatile__("lock\norl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory");
} }
static inline void __TBB_machine_and( volatile void *ptr, uint32_t addend ) { static inline void __TBB_machine_and( volatile void *ptr, uint32_t addend ) {
__asm__ __volatile__("lock\nandl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_ t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory"); __asm__ __volatile__("lock\nandl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_ t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory");
} }
//TODO: Check if it possible and profitable for IA-32 on (Linux and Windows ) //TODO: Check if it possible and profitable for IA-32 architecture on (Linu x* and Windows*)
//to use of 64-bit load/store via floating point registers together with fu ll fence //to use of 64-bit load/store via floating point registers together with fu ll fence
//for sequentially consistent load/store, instead of CAS. //for sequentially consistent load/store, instead of CAS.
#if __clang__ #if __clang__
#define __TBB_fildq "fildll" #define __TBB_fildq "fildll"
#define __TBB_fistpq "fistpll" #define __TBB_fistpq "fistpll"
#else #else
#define __TBB_fildq "fildq" #define __TBB_fildq "fildq"
#define __TBB_fistpq "fistpq" #define __TBB_fistpq "fistpq"
#endif #endif
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 macos_common.h   macos_common.h 
skipping to change at line 65 skipping to change at line 65
// headers was included). // headers was included).
#define __TBB_UnknownArchitecture 1 #define __TBB_UnknownArchitecture 1
#endif #endif
#if __TBB_UnknownArchitecture #if __TBB_UnknownArchitecture
// Implementation of atomic operations based on OS provided primitives // Implementation of atomic operations based on OS provided primitives
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>
static inline int64_t __TBB_machine_cmpswp8_OsX(volatile void *ptr, int64_t value, int64_t comparand) static inline int64_t __TBB_machine_cmpswp8_OsX(volatile void *ptr, int64_t value, int64_t comparand)
{ {
__TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly a ligned for Mac OS atomics"); __TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly a ligned for OS X* atomics");
int64_t* address = (int64_t*)ptr; int64_t* address = (int64_t*)ptr;
while( !OSAtomicCompareAndSwap64Barrier(comparand, value, address) ){ while( !OSAtomicCompareAndSwap64Barrier(comparand, value, address) ){
#if __TBB_WORDSIZE==8 #if __TBB_WORDSIZE==8
int64_t snapshot = *address; int64_t snapshot = *address;
#else #else
int64_t snapshot = OSAtomicAdd64( 0, address ); int64_t snapshot = OSAtomicAdd64( 0, address );
#endif #endif
if( snapshot!=comparand ) return snapshot; if( snapshot!=comparand ) return snapshot;
} }
return comparand; return comparand;
skipping to change at line 110 skipping to change at line 110
fence usages where a more lightweight synchronization means (or none at all) fence usages where a more lightweight synchronization means (or none at all)
could suffice. Thus if you use this header to enable TBB on a new platf orm, could suffice. Thus if you use this header to enable TBB on a new platf orm,
consider forking it and relaxing below helpers as appropriate. **/ consider forking it and relaxing below helpers as appropriate. **/
#define __TBB_control_consistency_helper() OSMemoryBarrier() #define __TBB_control_consistency_helper() OSMemoryBarrier()
#define __TBB_acquire_consistency_helper() OSMemoryBarrier() #define __TBB_acquire_consistency_helper() OSMemoryBarrier()
#define __TBB_release_consistency_helper() OSMemoryBarrier() #define __TBB_release_consistency_helper() OSMemoryBarrier()
#define __TBB_full_memory_fence() OSMemoryBarrier() #define __TBB_full_memory_fence() OSMemoryBarrier()
static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t val ue, int32_t comparand) static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t val ue, int32_t comparand)
{ {
__TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly a ligned for Mac OS atomics"); __TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly a ligned for OS X* atomics");
int32_t* address = (int32_t*)ptr; int32_t* address = (int32_t*)ptr;
while( !OSAtomicCompareAndSwap32Barrier(comparand, value, address) ){ while( !OSAtomicCompareAndSwap32Barrier(comparand, value, address) ){
int32_t snapshot = *address; int32_t snapshot = *address;
if( snapshot!=comparand ) return snapshot; if( snapshot!=comparand ) return snapshot;
} }
return comparand; return comparand;
} }
static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t a ddend) static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t a ddend)
{ {
__TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly a ligned for Mac OS atomics"); __TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly a ligned for OS X* atomics");
return OSAtomicAdd32Barrier(addend, (int32_t*)ptr) - addend; return OSAtomicAdd32Barrier(addend, (int32_t*)ptr) - addend;
} }
static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t a ddend) static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t a ddend)
{ {
__TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly a ligned for Mac OS atomics"); __TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly a ligned for OS X* atomics");
return OSAtomicAdd64Barrier(addend, (int64_t*)ptr) - addend; return OSAtomicAdd64Barrier(addend, (int64_t*)ptr) - addend;
} }
#define __TBB_USE_GENERIC_PART_WORD_CAS 1 #define __TBB_USE_GENERIC_PART_WORD_CAS 1
#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 #define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1
#define __TBB_USE_GENERIC_FETCH_STORE 1 #define __TBB_USE_GENERIC_FETCH_STORE 1
#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1
#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 #define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1
#if __TBB_WORDSIZE == 4 #if __TBB_WORDSIZE == 4
#define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 #define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1
 End of changes. 4 change blocks. 
4 lines changed or deleted 4 lines changed or added


 memory_pool.h   memory_pool.h 
skipping to change at line 39 skipping to change at line 39
#ifndef __TBB_memory_pool_H #ifndef __TBB_memory_pool_H
#define __TBB_memory_pool_H #define __TBB_memory_pool_H
#if !TBB_PREVIEW_MEMORY_POOL #if !TBB_PREVIEW_MEMORY_POOL
#error Set TBB_PREVIEW_MEMORY_POOL to include memory_pool.h #error Set TBB_PREVIEW_MEMORY_POOL to include memory_pool.h
#endif #endif
/** @file */ /** @file */
#include "scalable_allocator.h" #include "scalable_allocator.h"
#include "tbb_stddef.h" #include "tbb_stddef.h"
#include "tbb_machine.h" // TODO: avoid linkage with libtbb on IA-64 #include "tbb_machine.h" // TODO: avoid linkage with libtbb on IA-64 archit ecture
#include "tbb/atomic.h" // for as_atomic #include "tbb/atomic.h" // for as_atomic
#include <new> // std::bad_alloc #include <new> // std::bad_alloc
#if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_CPP11_STD_FORWARD_BROKEN #if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_CPP11_STD_FORWARD_BROKEN
#include <utility> // std::forward #include <utility> // std::forward
#endif #endif
#if __TBB_EXTRA_DEBUG #if __TBB_EXTRA_DEBUG
#define __TBBMALLOC_ASSERT ASSERT #define __TBBMALLOC_ASSERT ASSERT
#else #else
#define __TBBMALLOC_ASSERT(a,b) ((void)0) #define __TBBMALLOC_ASSERT(a,b) ((void)0)
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 mic_common.h   mic_common.h 
skipping to change at line 49 skipping to change at line 49
#ifndef __TBB_PREFETCHING #ifndef __TBB_PREFETCHING
#define __TBB_PREFETCHING 1 #define __TBB_PREFETCHING 1
#endif #endif
#if __TBB_PREFETCHING #if __TBB_PREFETCHING
#include <immintrin.h> #include <immintrin.h>
#define __TBB_cl_prefetch(p) _mm_prefetch((const char*)p, _MM_HINT_T1) #define __TBB_cl_prefetch(p) _mm_prefetch((const char*)p, _MM_HINT_T1)
#define __TBB_cl_evict(p) _mm_clevict(p, _MM_HINT_T1) #define __TBB_cl_evict(p) _mm_clevict(p, _MM_HINT_T1)
#endif #endif
/** Early Intel(R) MIC Architecture does not support mfence and pause instr uctions **/ /** Early Intel(R) Many Integrated Core Architecture does not support mfenc e and pause instructions **/
#define __TBB_full_memory_fence __TBB_release_consistency_helper #define __TBB_full_memory_fence __TBB_release_consistency_helper
#define __TBB_Pause(x) _mm_delay_32(16*(x)) #define __TBB_Pause(x) _mm_delay_32(16*(x))
#define __TBB_STEALING_PAUSE 1500/16 #define __TBB_STEALING_PAUSE 1500/16
#include <sched.h> #include <sched.h>
#define __TBB_Yield() sched_yield() #define __TBB_Yield() sched_yield()
/** FPU control setting **/ /** FPU control setting **/
#define __TBB_CPU_CTL_ENV_PRESENT 0 #define __TBB_CPU_CTL_ENV_PRESENT 0
/** Specifics **/ /** Specifics **/
 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 406 skipping to change at line 406
my_max_depth++; my_max_depth++;
return true; return true;
} }
} else my_delay = false; } else my_delay = false;
return false; return false;
} }
bool divisions_left() { // part of old should_execute_range() bool divisions_left() { // part of old should_execute_range()
return my_divisor > 1; return my_divisor > 1;
} }
bool should_create_trap() { bool should_create_trap() {
return true; // TODO: rethink for the stage after memorizing level return false;
} }
static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY; static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY;
}; };
class auto_partition_type: public auto_partition_type_base<auto_partition_t ype> { class auto_partition_type: public auto_partition_type_base<auto_partition_t ype> {
public: public:
auto_partition_type( const auto_partitioner& ) {} auto_partition_type( const auto_partitioner& ) {}
auto_partition_type( auto_partition_type& src, split) auto_partition_type( auto_partition_type& src, split)
: auto_partition_type_base<auto_partition_type>(src, split()) {} : auto_partition_type_base<auto_partition_type>(src, split()) {}
static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY; static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY;
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 tbb_config.h   tbb_config.h 
skipping to change at line 423 skipping to change at line 423
#define __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN 1 #define __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN 1
#endif #endif
#if defined(_MSC_VER) && _MSC_VER < 1500 && !defined(__INTEL_COMPILER) #if defined(_MSC_VER) && _MSC_VER < 1500 && !defined(__INTEL_COMPILER)
/** VS2005 and earlier do not allow declaring template class as a frien d /** VS2005 and earlier do not allow declaring template class as a frien d
of classes defined in other namespaces. **/ of classes defined in other namespaces. **/
#define __TBB_TEMPLATE_FRIENDS_BROKEN 1 #define __TBB_TEMPLATE_FRIENDS_BROKEN 1
#endif #endif
//TODO: recheck for different clang versions //TODO: recheck for different clang versions
#if __GLIBC__==2 && __GLIBC_MINOR__==3 || __MINGW32__ || (__APPLE__ && (__c lang__ || __INTEL_COMPILER==1200 && !TBB_USE_DEBUG)) #if __GLIBC__==2 && __GLIBC_MINOR__==3 || __MINGW32__ || (__APPLE__ && ( __ INTEL_COMPILER==1200 && !TBB_USE_DEBUG))
/** Macro controlling EH usages in TBB tests. /** Macro controlling EH usages in TBB tests.
Some older versions of glibc crash when exception handling happens concurrently. **/ Some older versions of glibc crash when exception handling happens concurrently. **/
#define __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN 1 #define __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN 1
#else #else
#define __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN 0 #define __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN 0
#endif #endif
#if (_WIN32||_WIN64) && __INTEL_COMPILER == 1110 #if (_WIN32||_WIN64) && __INTEL_COMPILER == 1110
/** That's a bug in Intel compiler 11.1.044/IA-32/Windows, that leads t o a worker thread crash on the thread's startup. **/ /** That's a bug in Intel compiler 11.1.044/IA-32/Windows, that leads t o a worker thread crash on the thread's startup. **/
#define __TBB_ICL_11_1_CODE_GEN_BROKEN 1 #define __TBB_ICL_11_1_CODE_GEN_BROKEN 1
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 tbb_machine.h   tbb_machine.h 
skipping to change at line 108 skipping to change at line 108
__TBB_machine_<op><S><fence>(...), where __TBB_machine_<op><S><fence>(...), where
<op> = {cmpswp, fetchadd, fetchstore} <op> = {cmpswp, fetchadd, fetchstore}
<S> = {1, 2, 4, 8} <S> = {1, 2, 4, 8}
<fence> = {full_fence, acquire, release, relaxed} <fence> = {full_fence, acquire, release, relaxed}
Must be provided if __TBB_USE_FENCED_ATOMICS is set. Must be provided if __TBB_USE_FENCED_ATOMICS is set.
__TBB_control_consistency_helper() __TBB_control_consistency_helper()
Bridges the memory-semantics gap between architectures providing on ly Bridges the memory-semantics gap between architectures providing on ly
implicit C++0x "consume" semantics (like Power Architecture) and th ose implicit C++0x "consume" semantics (like Power Architecture) and th ose
also implicitly obeying control dependencies (like IA-64). also implicitly obeying control dependencies (like IA-64 architectu re).
It must be used only in conditional code where the condition is its elf It must be used only in conditional code where the condition is its elf
data-dependent, and will then make subsequent code behave as if the data-dependent, and will then make subsequent code behave as if the
original data dependency were acquired. original data dependency were acquired.
It needs only a compiler fence where implied by the architecture It needs only a compiler fence where implied by the architecture
either specifically (like IA-64) or because generally stronger "acq either specifically (like IA-64 architecture) or because generally
uire" stronger
semantics are enforced (like x86). "acquire" semantics are enforced (like x86).
It is always valid, though potentially suboptimal, to replace It is always valid, though potentially suboptimal, to replace
control with acquire on the load and then remove the helper. control with acquire on the load and then remove the helper.
__TBB_acquire_consistency_helper(), __TBB_release_consistency_helper() __TBB_acquire_consistency_helper(), __TBB_release_consistency_helper()
Must be provided if __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE is set . Must be provided if __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE is set .
Enforce acquire and release semantics in generic implementations of fenced Enforce acquire and release semantics in generic implementations of fenced
store and load operations. Depending on the particular architecture /compiler store and load operations. Depending on the particular architecture /compiler
combination they may be a hardware fence, a compiler fence, both or nothing. combination they may be a hardware fence, a compiler fence, both or nothing.
**/ **/
skipping to change at line 363 skipping to change at line 363
//! Class that implements exponential backoff. //! Class that implements exponential backoff.
/** See implementation of spin_wait_while_eq for an example. */ /** See implementation of spin_wait_while_eq for an example. */
class atomic_backoff : no_copy { class atomic_backoff : no_copy {
//! Time delay, in units of "pause" instructions. //! Time delay, in units of "pause" instructions.
/** Should be equal to approximately the number of "pause" instructions /** Should be equal to approximately the number of "pause" instructions
that take the same time as an context switch. */ that take the same time as an context switch. */
static const int32_t LOOPS_BEFORE_YIELD = 16; static const int32_t LOOPS_BEFORE_YIELD = 16;
int32_t count; int32_t count;
public: public:
// In many cases, an object of this type is initialized eagerly on hot
path,
// as in for(atomic_backoff b; ; b.pause()) { /*loop body*/ }
// For this reason, the construction cost must be very small!
atomic_backoff() : count(1) {} atomic_backoff() : count(1) {}
// This constructor pauses immediately; do not use on hot paths!
atomic_backoff( bool ) : count(1) { pause(); }
//! Pause for a while. //! Pause for a while.
void pause() { void pause() {
if( count<=LOOPS_BEFORE_YIELD ) { if( count<=LOOPS_BEFORE_YIELD ) {
__TBB_Pause(count); __TBB_Pause(count);
// Pause twice as long the next time. // Pause twice as long the next time.
count*=2; count*=2;
} else { } else {
// Pause is so long that we might as well yield CPU to schedule r. // Pause is so long that we might as well yield CPU to schedule r.
__TBB_Yield(); __TBB_Yield();
skipping to change at line 454 skipping to change at line 459
const uint32_t byte_offset = (uint32_t) ((uintptr_t)ptr & 0x 3); const uint32_t byte_offset = (uint32_t) ((uintptr_t)ptr & 0x 3);
volatile uint32_t * const aligned_ptr = (uint32_t*)((uintptr_t)ptr - by te_offset ); volatile uint32_t * const aligned_ptr = (uint32_t*)((uintptr_t)ptr - by te_offset );
// location of T within uint32_t for a C++ shift operation // location of T within uint32_t for a C++ shift operation
const uint32_t bits_to_shift = 8*(endianness::is_big_endian() ? (4 - sizeof(T) - (byte_offset)) : byte_offset); const uint32_t bits_to_shift = 8*(endianness::is_big_endian() ? (4 - sizeof(T) - (byte_offset)) : byte_offset);
const uint32_t mask = (((uint32_t)1<<(sizeof(T)*8)) - 1 )< <bits_to_shift; const uint32_t mask = (((uint32_t)1<<(sizeof(T)*8)) - 1 )< <bits_to_shift;
// for signed T, any sign extension bits in cast value/comparand are im mediately clipped by mask // for signed T, any sign extension bits in cast value/comparand are im mediately clipped by mask
const uint32_t shifted_comparand = ((uint32_t)comparand << bits_to_shif t)&mask; const uint32_t shifted_comparand = ((uint32_t)comparand << bits_to_shif t)&mask;
const uint32_t shifted_value = ((uint32_t)value << bits_to_shif t)&mask; const uint32_t shifted_value = ((uint32_t)value << bits_to_shif t)&mask;
for(atomic_backoff b;;b.pause()) { for( atomic_backoff b;;b.pause() ) {
const uint32_t surroundings = *aligned_ptr & ~mask ; // may have c hanged during the pause const uint32_t surroundings = *aligned_ptr & ~mask ; // may have c hanged during the pause
const uint32_t big_comparand = surroundings | shifted_comparand ; const uint32_t big_comparand = surroundings | shifted_comparand ;
const uint32_t big_value = surroundings | shifted_value ; const uint32_t big_value = surroundings | shifted_value ;
// __TBB_machine_cmpswp4 presumed to have full fence. // __TBB_machine_cmpswp4 presumed to have full fence.
// Cast shuts up /Wp64 warning // Cast shuts up /Wp64 warning
const uint32_t big_result = (uint32_t)__TBB_machine_cmpswp4( aligne d_ptr, big_value, big_comparand ); const uint32_t big_result = (uint32_t)__TBB_machine_cmpswp4( aligne d_ptr, big_value, big_comparand );
if( big_result == big_comparand // CAS succeeded if( big_result == big_comparand // CAS succeeded
|| ((big_result ^ big_comparand) & mask) != 0) // CAS failed an d the bits of interest have changed || ((big_result ^ big_comparand) & mask) != 0) // CAS failed an d the bits of interest have changed
{ {
return T((big_result & mask) >> bits_to_shift); return T((big_result & mask) >> bits_to_shift);
skipping to change at line 508 skipping to change at line 513
#if __TBB_64BIT_ATOMICS #if __TBB_64BIT_ATOMICS
template<> template<>
inline uint64_t __TBB_CompareAndSwapGeneric <8,uint64_t> (volatile void *pt r, uint64_t value, uint64_t comparand ) { inline uint64_t __TBB_CompareAndSwapGeneric <8,uint64_t> (volatile void *pt r, uint64_t value, uint64_t comparand ) {
return __TBB_machine_cmpswp8(ptr,value,comparand); return __TBB_machine_cmpswp8(ptr,value,comparand);
} }
#endif #endif
template<size_t S, typename T> template<size_t S, typename T>
inline T __TBB_FetchAndAddGeneric (volatile void *ptr, T addend) { inline T __TBB_FetchAndAddGeneric (volatile void *ptr, T addend) {
atomic_backoff b;
T result; T result;
for(;;) { for( atomic_backoff b;;b.pause() ) {
result = *reinterpret_cast<volatile T *>(ptr); result = *reinterpret_cast<volatile T *>(ptr);
// __TBB_CompareAndSwapGeneric presumed to have full fence. // __TBB_CompareAndSwapGeneric presumed to have full fence.
if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, result+addend, result ) ==result ) if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, result+addend, result ) ==result )
break; break;
b.pause();
} }
return result; return result;
} }
template<size_t S, typename T> template<size_t S, typename T>
inline T __TBB_FetchAndStoreGeneric (volatile void *ptr, T value) { inline T __TBB_FetchAndStoreGeneric (volatile void *ptr, T value) {
atomic_backoff b;
T result; T result;
for(;;) { for( atomic_backoff b;;b.pause() ) {
result = *reinterpret_cast<volatile T *>(ptr); result = *reinterpret_cast<volatile T *>(ptr);
// __TBB_CompareAndSwapGeneric presumed to have full fence. // __TBB_CompareAndSwapGeneric presumed to have full fence.
if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, value, result )==result ) if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, value, result )==result )
break; break;
b.pause();
} }
return result; return result;
} }
#if __TBB_USE_GENERIC_PART_WORD_CAS #if __TBB_USE_GENERIC_PART_WORD_CAS
#define __TBB_machine_cmpswp1 tbb::internal::__TBB_CompareAndSwapGeneric<1, uint8_t> #define __TBB_machine_cmpswp1 tbb::internal::__TBB_CompareAndSwapGeneric<1, uint8_t>
#define __TBB_machine_cmpswp2 tbb::internal::__TBB_CompareAndSwapGeneric<2, uint16_t> #define __TBB_machine_cmpswp2 tbb::internal::__TBB_CompareAndSwapGeneric<2, uint16_t>
#endif #endif
#if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_PART_WORD_FETCH_ADD #if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_PART_WORD_FETCH_ADD
skipping to change at line 866 skipping to change at line 867
if( uintptr_t tmp = x>>8 ) { x=tmp; result += 8; } if( uintptr_t tmp = x>>8 ) { x=tmp; result += 8; }
if( uintptr_t tmp = x>>4 ) { x=tmp; result += 4; } if( uintptr_t tmp = x>>4 ) { x=tmp; result += 4; }
if( uintptr_t tmp = x>>2 ) { x=tmp; result += 2; } if( uintptr_t tmp = x>>2 ) { x=tmp; result += 2; }
return (x&2)? result+1: result; return (x&2)? result+1: result;
} }
#endif #endif
#ifndef __TBB_AtomicOR #ifndef __TBB_AtomicOR
inline void __TBB_AtomicOR( volatile void *operand, uintptr_t addend ) { inline void __TBB_AtomicOR( volatile void *operand, uintptr_t addend ) {
tbb::internal::atomic_backoff b; for( tbb::internal::atomic_backoff b;;b.pause() ) {
for(;;) {
uintptr_t tmp = *(volatile uintptr_t *)operand; uintptr_t tmp = *(volatile uintptr_t *)operand;
uintptr_t result = __TBB_CompareAndSwapW(operand, tmp|addend, tmp); uintptr_t result = __TBB_CompareAndSwapW(operand, tmp|addend, tmp);
if( result==tmp ) break; if( result==tmp ) break;
b.pause();
} }
} }
#endif #endif
#ifndef __TBB_AtomicAND #ifndef __TBB_AtomicAND
inline void __TBB_AtomicAND( volatile void *operand, uintptr_t addend ) { inline void __TBB_AtomicAND( volatile void *operand, uintptr_t addend ) {
tbb::internal::atomic_backoff b; for( tbb::internal::atomic_backoff b;;b.pause() ) {
for(;;) {
uintptr_t tmp = *(volatile uintptr_t *)operand; uintptr_t tmp = *(volatile uintptr_t *)operand;
uintptr_t result = __TBB_CompareAndSwapW(operand, tmp&addend, tmp); uintptr_t result = __TBB_CompareAndSwapW(operand, tmp&addend, tmp);
if( result==tmp ) break; if( result==tmp ) break;
b.pause();
} }
} }
#endif #endif
#if __TBB_PREFETCHING #if __TBB_PREFETCHING
#ifndef __TBB_cl_prefetch #ifndef __TBB_cl_prefetch
#error This platform does not define cache management primitives required f or __TBB_PREFETCHING #error This platform does not define cache management primitives required f or __TBB_PREFETCHING
#endif #endif
#ifndef __TBB_cl_evict #ifndef __TBB_cl_evict
skipping to change at line 911 skipping to change at line 908
typedef __TBB_atomic __TBB_Flag __TBB_atomic_flag; typedef __TBB_atomic __TBB_Flag __TBB_atomic_flag;
#ifndef __TBB_TryLockByte #ifndef __TBB_TryLockByte
inline bool __TBB_TryLockByte( __TBB_atomic_flag &flag ) { inline bool __TBB_TryLockByte( __TBB_atomic_flag &flag ) {
return __TBB_machine_cmpswp1(&flag,1,0)==0; return __TBB_machine_cmpswp1(&flag,1,0)==0;
} }
#endif #endif
#ifndef __TBB_LockByte #ifndef __TBB_LockByte
inline __TBB_Flag __TBB_LockByte( __TBB_atomic_flag& flag ) { inline __TBB_Flag __TBB_LockByte( __TBB_atomic_flag& flag ) {
if ( !__TBB_TryLockByte(flag) ) { tbb::internal::atomic_backoff backoff;
tbb::internal::atomic_backoff b; while( !__TBB_TryLockByte(flag) ) backoff.pause();
do {
b.pause();
} while ( !__TBB_TryLockByte(flag) );
}
return 0; return 0;
} }
#endif #endif
#ifndef __TBB_UnlockByte #ifndef __TBB_UnlockByte
#define __TBB_UnlockByte(addr) __TBB_store_with_release((addr),0) #define __TBB_UnlockByte(addr) __TBB_store_with_release((addr),0)
#endif #endif
#ifndef __TBB_ReverseByte #ifndef __TBB_ReverseByte
inline unsigned char __TBB_ReverseByte(unsigned char src) { inline unsigned char __TBB_ReverseByte(unsigned char src) {
 End of changes. 16 change blocks. 
23 lines changed or deleted 17 lines changed or added


 tbb_stddef.h   tbb_stddef.h 
skipping to change at line 37 skipping to change at line 37
*/ */
#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 1 #define TBB_VERSION_MINOR 1
// Engineering-focused interface version // Engineering-focused interface version
#define TBB_INTERFACE_VERSION 6104 #define TBB_INTERFACE_VERSION 6105
#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 244 skipping to change at line 244
Note that no problems have yet been observed relating to the definition currently being empty, Note that no problems have yet been observed relating to the definition currently being empty,
even if at least "volatile" would seem to be in order to avoid data som etimes temporarily hiding even if at least "volatile" would seem to be in order to avoid data som etimes temporarily hiding
in a register (although "volatile" as a "poor man's atomic" lacks sever al other features of a proper in a register (although "volatile" as a "poor man's atomic" lacks sever al other features of a proper
atomic, some of which are now provided instead through specialized func tions). atomic, some of which are now provided instead through specialized func tions).
Note that usage is intentionally compatible with a definition as qualif ier "volatile", Note that usage is intentionally compatible with a definition as qualif ier "volatile",
both as a way to have the compiler help enforce use of the label and to quickly rule out both as a way to have the compiler help enforce use of the label and to quickly rule out
one potential issue. one potential issue.
Note however that, with some architecture/compiler combinations, e.g. o n IA-64, "volatile" Note however that, with some architecture/compiler combinations, e.g. o n IA-64 architecture, "volatile"
also has non-portable memory semantics that are needlessly expensive fo r "relaxed" operations. also has non-portable memory semantics that are needlessly expensive fo r "relaxed" operations.
Note that this must only be applied to data that will not change bit pa tterns when cast to/from Note that this must only be applied to data that will not change bit pa tterns when cast to/from
an integral type of the same length; tbb::atomic must be used instead f or, e.g., floating-point types. an integral type of the same length; tbb::atomic must be used instead f or, e.g., floating-point types.
TODO: apply wherever relevant **/ TODO: apply wherever relevant **/
#define __TBB_atomic // intentionally empty, see above #define __TBB_atomic // intentionally empty, see above
template<class T, int S> template<class T, int S>
struct padded_base : T { struct padded_base : T {
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 tuple   tuple 
skipping to change at line 49 skipping to change at line 49
#define __TBB_U_PACK #define __TBB_U_PACK
#define __TBB_TYPENAME_T_PACK #define __TBB_TYPENAME_T_PACK
#define __TBB_TYPENAME_U_PACK #define __TBB_TYPENAME_U_PACK
#define __TBB_NULL_TYPE_PACK #define __TBB_NULL_TYPE_PACK
#define __TBB_REF_T_PARAM_PACK #define __TBB_REF_T_PARAM_PACK
#define __TBB_CONST_REF_T_PARAM_PACK #define __TBB_CONST_REF_T_PARAM_PACK
#define __TBB_T_PARAM_LIST_PACK #define __TBB_T_PARAM_LIST_PACK
#define __TBB_CONST_NULL_REF_PACK #define __TBB_CONST_NULL_REF_PACK
// //
#elif __TBB_VARIADIC_MAX == 6 #elif __TBB_VARIADIC_MAX == 6
#define __TBB_T_PACK ,T5 #define __TBB_T_PACK ,__T5
#define __TBB_U_PACK ,U5 #define __TBB_U_PACK ,__U5
#define __TBB_TYPENAME_T_PACK , typename T5 #define __TBB_TYPENAME_T_PACK , typename __T5
#define __TBB_TYPENAME_U_PACK , typename U5 #define __TBB_TYPENAME_U_PACK , typename __U5
#define __TBB_NULL_TYPE_PACK , null_type #define __TBB_NULL_TYPE_PACK , null_type
#define __TBB_REF_T_PARAM_PACK ,T5& t5 #define __TBB_REF_T_PARAM_PACK ,__T5& t5
#define __TBB_CONST_REF_T_PARAM_PACK ,const T5& t5 #define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5
#define __TBB_T_PARAM_LIST_PACK ,t5 #define __TBB_T_PARAM_LIST_PACK ,t5
#define __TBB_CONST_NULL_REF_PACK , const null_type& #define __TBB_CONST_NULL_REF_PACK , const null_type&
// //
#elif __TBB_VARIADIC_MAX == 7 #elif __TBB_VARIADIC_MAX == 7
#define __TBB_T_PACK ,T5, T6 #define __TBB_T_PACK ,__T5, __T6
#define __TBB_U_PACK ,U5, U6 #define __TBB_U_PACK ,__U5, __U6
#define __TBB_TYPENAME_T_PACK , typename T5 , typename T6 #define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6
#define __TBB_TYPENAME_U_PACK , typename U5 , typename U6 #define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6
#define __TBB_NULL_TYPE_PACK , null_type, null_type #define __TBB_NULL_TYPE_PACK , null_type, null_type
#define __TBB_REF_T_PARAM_PACK ,T5& t5, T6& t6 #define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6
#define __TBB_CONST_REF_T_PARAM_PACK ,const T5& t5, const T6& t6 #define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5, const __T6& t6
#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 #define __TBB_T_PARAM_LIST_PACK ,t5 ,t6
#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type& #define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&
// //
#elif __TBB_VARIADIC_MAX == 8 #elif __TBB_VARIADIC_MAX == 8
#define __TBB_T_PACK ,T5, T6, T7 #define __TBB_T_PACK ,__T5, __T6, __T7
#define __TBB_U_PACK ,U5, U6, U7 #define __TBB_U_PACK ,__U5, __U6, __U7
#define __TBB_TYPENAME_T_PACK , typename T5 , typename T6, typename T7 #define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6, typename __T
#define __TBB_TYPENAME_U_PACK , typename U5 , typename U6, typename U7 7
#define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6, typename __U
7
#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type #define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type
#define __TBB_REF_T_PARAM_PACK ,T5& t5, T6& t6, T7& t7 #define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7
#define __TBB_CONST_REF_T_PARAM_PACK , const T5& t5, const T6& t6, const T7 #define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, cons
& t7 t __T7& t7
#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 #define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7
#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, con st null_type& #define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, con st null_type&
// //
#elif __TBB_VARIADIC_MAX == 9 #elif __TBB_VARIADIC_MAX == 9
#define __TBB_T_PACK ,T5, T6, T7, T8 #define __TBB_T_PACK ,__T5, __T6, __T7, __T8
#define __TBB_U_PACK ,U5, U6, U7, U8 #define __TBB_U_PACK ,__U5, __U6, __U7, __U8
#define __TBB_TYPENAME_T_PACK , typename T5, typename T6, typename T7, type #define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7
name T8 , typename __T8
#define __TBB_TYPENAME_U_PACK , typename U5, typename U6, typename U7, type #define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7
name U8 , typename __U8
#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type #define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type
#define __TBB_REF_T_PARAM_PACK ,T5& t5, T6& t6, T7& t7, T8& t8 #define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8
#define __TBB_CONST_REF_T_PARAM_PACK , const T5& t5, const T6& t6, const T7 #define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, cons
& t7, const T8& t8 t __T7& t7, const __T8& t8
#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8 #define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8
#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, con st null_type&, const null_type& #define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, con st null_type&, const null_type&
// //
#elif __TBB_VARIADIC_MAX >= 10 #elif __TBB_VARIADIC_MAX >= 10
#define __TBB_T_PACK ,T5, T6, T7, T8, T9 #define __TBB_T_PACK ,__T5, __T6, __T7, __T8, __T9
#define __TBB_U_PACK ,U5, U6, U7, U8, U9 #define __TBB_U_PACK ,__U5, __U6, __U7, __U8, __U9
#define __TBB_TYPENAME_T_PACK , typename T5, typename T6, typename T7, type #define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7
name T8, typename T9 , typename __T8, typename __T9
#define __TBB_TYPENAME_U_PACK , typename U5, typename U6, typename U7, type #define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7
name U8, typename U9 , typename __U8, typename __U9
#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type, null_type #define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type, null_type
#define __TBB_REF_T_PARAM_PACK ,T5& t5, T6& t6, T7& t7, T8& t8, T9& t9 #define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8, __T
#define __TBB_CONST_REF_T_PARAM_PACK , const T5& t5, const T6& t6, const T7 9& t9
& t7, const T8& t8, const T9& t9 #define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, cons
t __T7& t7, const __T8& t8, const __T9& t9
#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8 ,t9 #define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8 ,t9
#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, con st null_type&, const null_type&, const null_type& #define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, con st null_type&, const null_type&, const null_type&
#endif #endif
namespace tbb { namespace tbb {
namespace interface5 { namespace interface5 {
namespace internal { namespace internal {
struct null_type { }; struct null_type { };
} }
using internal::null_type; using internal::null_type;
// tuple forward declaration // tuple forward declaration
template <typename T0=null_type, typename T1=null_type, typename T2=null_ty template <typename __T0=null_type, typename __T1=null_type, typename __T2=n
pe, ull_type,
typename T3=null_type, typename T4=null_type typename __T3=null_type, typename __T4=null_type
#if __TBB_VARIADIC_MAX >= 6 #if __TBB_VARIADIC_MAX >= 6
, typename T5=null_type , typename __T5=null_type
#if __TBB_VARIADIC_MAX >= 7 #if __TBB_VARIADIC_MAX >= 7
, typename T6=null_type , typename __T6=null_type
#if __TBB_VARIADIC_MAX >= 8 #if __TBB_VARIADIC_MAX >= 8
, typename T7=null_type , typename __T7=null_type
#if __TBB_VARIADIC_MAX >= 9 #if __TBB_VARIADIC_MAX >= 9
, typename T8=null_type , typename __T8=null_type
#if __TBB_VARIADIC_MAX >= 10 #if __TBB_VARIADIC_MAX >= 10
, typename T9=null_type , typename __T9=null_type
#endif #endif
#endif #endif
#endif #endif
#endif #endif
#endif #endif
> >
class tuple; class tuple;
namespace internal { namespace internal {
// const null_type temp // const null_type temp
inline const null_type cnull() { return null_type(); } inline const null_type cnull() { return null_type(); }
// cons forward declaration // cons forward declaration
template <typename HT, typename TT> struct cons; template <typename __HT, typename __TT> struct cons;
// type of a component of the cons // type of a component of the cons
template<int N, typename T> template<int __N, typename __T>
struct component { struct component {
typedef typename T::tail_type next; typedef typename __T::tail_type next;
typedef typename component<N-1,next>::type type; typedef typename component<__N-1,next>::type type;
}; };
template<typename T> template<typename __T>
struct component<0,T> { struct component<0,__T> {
typedef typename T::head_type type; typedef typename __T::head_type type;
}; };
template<> template<>
struct component<0,null_type> { struct component<0,null_type> {
typedef null_type type; typedef null_type type;
}; };
// const version of component // const version of component
template<int N, typename T> template<int __N, typename __T>
struct component<N, const T> struct component<__N, const __T>
{ {
typedef typename T::tail_type next; typedef typename __T::tail_type next;
typedef const typename component<N-1,next>::type type; typedef const typename component<__N-1,next>::type type;
}; };
template<typename T> template<typename __T>
struct component<0, const T> struct component<0, const __T>
{ {
typedef const typename T::head_type type; typedef const typename __T::head_type type;
}; };
// helper class for getting components of cons // helper class for getting components of cons
template< int N> template< int __N>
struct get_helper { struct get_helper {
template<typename HT, typename TT> template<typename __HT, typename __TT>
inline static typename component<N, cons<HT,TT> >::type& get(cons<HT,TT>& t inline static typename component<__N, cons<__HT,__TT> >::type& get(cons<__H
i) { T,__TT>& ti) {
return get_helper<N-1>::get(ti.tail); return get_helper<__N-1>::get(ti.tail);
} }
template<typename HT, typename TT> template<typename __HT, typename __TT>
inline static typename component<N, cons<HT,TT> >::type const& get(const co inline static typename component<__N, cons<__HT,__TT> >::type const& get(co
ns<HT,TT>& ti) { nst cons<__HT,__TT>& ti) {
return get_helper<N-1>::get(ti.tail); return get_helper<__N-1>::get(ti.tail);
} }
}; };
template<> template<>
struct get_helper<0> { struct get_helper<0> {
template<typename HT, typename TT> template<typename __HT, typename __TT>
inline static typename component<0, cons<HT,TT> >::type& get(cons<HT,TT>& t inline static typename component<0, cons<__HT,__TT> >::type& get(cons<__HT,
i) { __TT>& ti) {
return ti.head; return ti.head;
} }
template<typename HT, typename TT> template<typename __HT, typename __TT>
inline static typename component<0, cons<HT,TT> >::type const& get(const co inline static typename component<0, cons<__HT,__TT> >::type const& get(cons
ns<HT,TT>& ti) { t cons<__HT,__TT>& ti) {
return ti.head; return ti.head;
} }
}; };
// traits adaptor // traits adaptor
template <typename T0, typename T1, typename T2, typename T3, typename T4 _ _TBB_TYPENAME_T_PACK> template <typename __T0, typename __T1, typename __T2, typename __T3, typen ame __T4 __TBB_TYPENAME_T_PACK>
struct tuple_traits { struct tuple_traits {
typedef cons <T0, typename tuple_traits<T1, T2, T3, T4 __TBB_T_PACK , n ull_type>::U > U; typedef cons <__T0, typename tuple_traits<__T1, __T2, __T3, __T4 __TBB_ T_PACK , null_type>::U > U;
}; };
template <typename T0> template <typename __T0>
struct tuple_traits<T0, null_type, null_type, null_type, null_type __TBB_NU struct tuple_traits<__T0, null_type, null_type, null_type, null_type __TBB_
LL_TYPE_PACK > { NULL_TYPE_PACK > {
typedef cons<T0, null_type> U; typedef cons<__T0, null_type> U;
}; };
template<> template<>
struct tuple_traits<null_type, null_type, null_type, null_type, null_type _ _TBB_NULL_TYPE_PACK > { struct tuple_traits<null_type, null_type, null_type, null_type, null_type _ _TBB_NULL_TYPE_PACK > {
typedef null_type U; typedef null_type U;
}; };
// core cons defs // core cons defs
template <typename HT, typename TT> template <typename __HT, typename __TT>
struct cons{ struct cons{
typedef HT head_type; typedef __HT head_type;
typedef TT tail_type; typedef __TT tail_type;
head_type head; head_type head;
tail_type tail; tail_type tail;
static const int length = 1 + tail_type::length; static const int length = 1 + tail_type::length;
// default constructors // default constructors
explicit cons() : head(), tail() { } explicit cons() : head(), tail() { }
// non-default constructors // non-default constructors
cons(head_type& h, const tail_type& t) : head(h), tail(t) { } cons(head_type& h, const tail_type& t) : head(h), tail(t) { }
template <typename T0, typename T1, typename T2, typename T3, typename template <typename __T0, typename __T1, typename __T2, typename __T3, t
T4 __TBB_TYPENAME_T_PACK > ypename __T4 __TBB_TYPENAME_T_PACK >
cons(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& cons(const __T0& t0, const __T1& t1, const __T2& t2, const __T3& t3, co
t4 __TBB_CONST_REF_T_PARAM_PACK) : nst __T4& t4 __TBB_CONST_REF_T_PARAM_PACK) :
head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK, cnull()) { } head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK, cnull()) { }
template <typename T0, typename T1, typename T2, typename T3, typename template <typename __T0, typename __T1, typename __T2, typename __T3, t
T4 __TBB_TYPENAME_T_PACK > ypename __T4 __TBB_TYPENAME_T_PACK >
cons(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4 __TBB_REF_T_PARAM_PACK) : cons(__T0& t0, __T1& t1, __T2& t2, __T3& t3, __T4& t4 __TBB_REF_T_PARAM
_PACK) :
head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK , cnull()) { } head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK , cnull()) { }
template <typename HT1, typename TT1> template <typename __HT1, typename __TT1>
cons(const cons<HT1,TT1>& other) : head(other.head), tail(other.tail) { cons(const cons<__HT1,__TT1>& other) : head(other.head), tail(other.tai
} l) { }
cons& operator=(const cons& other) { head = other.head; tail = other.ta il; return *this; } cons& operator=(const cons& other) { head = other.head; tail = other.ta il; return *this; }
friend bool operator==(const cons& me, const cons& other) { friend bool operator==(const cons& me, const cons& other) {
return me.head == other.head && me.tail == other.tail; return me.head == other.head && me.tail == other.tail;
} }
friend bool operator<(const cons& me, const cons& other) { friend bool operator<(const cons& me, const cons& other) {
return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail); return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail);
} }
friend bool operator>(const cons& me, const cons& other) { return othe r<me; } friend bool operator>(const cons& me, const cons& other) { return othe r<me; }
friend bool operator!=(const cons& me, const cons& other) { return !(me ==other); } friend bool operator!=(const cons& me, const cons& other) { return !(me ==other); }
friend bool operator>=(const cons& me, const cons& other) { return !(me <other); } friend bool operator>=(const cons& me, const cons& other) { return !(me <other); }
friend bool operator<=(const cons& me, const cons& other) { return !(me >other); } friend bool operator<=(const cons& me, const cons& other) { return !(me >other); }
template<typename HT1, typename TT1> template<typename __HT1, typename __TT1>
friend bool operator==(const cons<HT,TT>& me, const cons<HT1,TT1>& othe friend bool operator==(const cons<__HT,__TT>& me, const cons<__HT1,__TT
r) { 1>& other) {
return me.head == other.head && me.tail == other.tail; return me.head == other.head && me.tail == other.tail;
} }
template<typename HT1, typename TT1> template<typename __HT1, typename __TT1>
friend bool operator<(const cons<HT,TT>& me, const cons<HT1,TT1>& other friend bool operator<(const cons<__HT,__TT>& me, const cons<__HT1,__TT1
) { >& other) {
return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail); return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail);
} }
template<typename HT1, typename TT1> template<typename __HT1, typename __TT1>
friend bool operator>(const cons<HT,TT>& me, const cons<HT1,TT1>& other friend bool operator>(const cons<__HT,__TT>& me, const cons<__HT1,__TT1
) { return other<me; } >& other) { return other<me; }
template<typename HT1, typename TT1> template<typename __HT1, typename __TT1>
friend bool operator!=(const cons<HT,TT>& me, const cons<HT1,TT1>& othe friend bool operator!=(const cons<__HT,__TT>& me, const cons<__HT1,__TT
r) { return !(me==other); } 1>& other) { return !(me==other); }
template<typename HT1, typename TT1> template<typename __HT1, typename __TT1>
friend bool operator>=(const cons<HT,TT>& me, const cons<HT1,TT1>& othe friend bool operator>=(const cons<__HT,__TT>& me, const cons<__HT1,__TT
r) { return !(me<other); } 1>& other) { return !(me<other); }
template<typename HT1, typename TT1> template<typename __HT1, typename __TT1>
friend bool operator<=(const cons<HT,TT>& me, const cons<HT1,TT1>& othe friend bool operator<=(const cons<__HT,__TT>& me, const cons<__HT1,__TT
r) { return !(me>other); } 1>& other) { return !(me>other); }
}; // cons }; // cons
template <typename HT> template <typename __HT>
struct cons<HT,null_type> { struct cons<__HT,null_type> {
typedef HT head_type; typedef __HT head_type;
typedef null_type tail_type; typedef null_type tail_type;
head_type head; head_type head;
static const int length = 1; static const int length = 1;
// default constructor // default constructor
cons() : head() { /*std::cout << "default constructor 1\n";*/ } cons() : head() { /*std::cout << "default constructor 1\n";*/ }
cons(const null_type&, const null_type&, const null_type&, const null_t ype&, const null_type& __TBB_CONST_NULL_REF_PACK) : head() { /*std::cout << "default constructor 2\n";*/ } cons(const null_type&, const null_type&, const null_type&, const null_t ype&, const null_type& __TBB_CONST_NULL_REF_PACK) : head() { /*std::cout << "default constructor 2\n";*/ }
// non-default constructor // non-default constructor
template<typename T1> template<typename __T1>
cons(T1& t1, const null_type&, const null_type&, const null_type&, cons cons(__T1& t1, const null_type&, const null_type&, const null_type&, co
t null_type& __TBB_CONST_NULL_REF_PACK) : head(t1) { /*std::cout << "non-de nst null_type& __TBB_CONST_NULL_REF_PACK) : head(t1) { /*std::cout << "non-
fault a1, t1== " << t1 << "\n";*/} default a1, t1== " << t1 << "\n";*/}
cons(head_type& h, const null_type& = null_type() ) : head(h) { } cons(head_type& h, const null_type& = null_type() ) : head(h) { }
cons(const head_type& t0, const null_type&, const null_type&, const nul l_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t0) { } cons(const head_type& t0, const null_type&, const null_type&, const nul l_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t0) { }
// converting constructor // converting constructor
template<typename HT1> template<typename __HT1>
cons(HT1 h1, const null_type&, const null_type&, const null_type&, cons cons(__HT1 h1, const null_type&, const null_type&, const null_type&, co
t null_type& __TBB_CONST_NULL_REF_PACK) : head(h1) { } nst null_type& __TBB_CONST_NULL_REF_PACK) : head(h1) { }
// copy constructor // copy constructor
template<typename HT1> template<typename __HT1>
cons( const cons<HT1, null_type>& other) : head(other.head) { } cons( const cons<__HT1, null_type>& other) : head(other.head) { }
// assignment operator // assignment operator
cons& operator=(const cons& other) { head = other.head; return *this; } cons& operator=(const cons& other) { head = other.head; return *this; }
friend bool operator==(const cons& me, const cons& other) { return me.h ead == other.head; } friend bool operator==(const cons& me, const cons& other) { return me.h ead == other.head; }
friend bool operator<(const cons& me, const cons& other) { return me.he ad < other.head; } friend bool operator<(const cons& me, const cons& other) { return me.he ad < other.head; }
friend bool operator>(const cons& me, const cons& other) { return other <me; } friend bool operator>(const cons& me, const cons& other) { return other <me; }
friend bool operator!=(const cons& me, const cons& other) {return !(me= =other); } friend bool operator!=(const cons& me, const cons& other) {return !(me= =other); }
friend bool operator<=(const cons& me, const cons& other) {return !(me> other); } friend bool operator<=(const cons& me, const cons& other) {return !(me> other); }
friend bool operator>=(const cons& me, const cons& other) {return !(me< other); } friend bool operator>=(const cons& me, const cons& other) {return !(me< other); }
template<typename HT1> template<typename __HT1>
friend bool operator==(const cons<HT,null_type>& me, const cons<HT1,nul friend bool operator==(const cons<__HT,null_type>& me, const cons<__HT1
l_type>& other) { ,null_type>& other) {
return me.head == other.head; return me.head == other.head;
} }
template<typename HT1> template<typename __HT1>
friend bool operator<(const cons<HT,null_type>& me, const cons<HT1,null friend bool operator<(const cons<__HT,null_type>& me, const cons<__HT1,
_type>& other) { null_type>& other) {
return me.head < other.head; return me.head < other.head;
} }
template<typename HT1> template<typename __HT1>
friend bool operator>(const cons<HT,null_type>& me, const cons<HT1,null friend bool operator>(const cons<__HT,null_type>& me, const cons<__HT1,
_type>& other) { return other<me; } null_type>& other) { return other<me; }
template<typename HT1> template<typename __HT1>
friend bool operator!=(const cons<HT,null_type>& me, const cons<HT1,nul friend bool operator!=(const cons<__HT,null_type>& me, const cons<__HT1
l_type>& other) { return !(me==other); } ,null_type>& other) { return !(me==other); }
template<typename HT1> template<typename __HT1>
friend bool operator<=(const cons<HT,null_type>& me, const cons<HT1,nul friend bool operator<=(const cons<__HT,null_type>& me, const cons<__HT1
l_type>& other) { return !(me>other); } ,null_type>& other) { return !(me>other); }
template<typename HT1> template<typename __HT1>
friend bool operator>=(const cons<HT,null_type>& me, const cons<HT1,nul friend bool operator>=(const cons<__HT,null_type>& me, const cons<__HT1
l_type>& other) { return !(me<other); } ,null_type>& other) { return !(me<other); }
}; // cons }; // cons
template <> template <>
struct cons<null_type,null_type> { typedef null_type tail_type; static cons t int length = 0; }; struct cons<null_type,null_type> { typedef null_type tail_type; static cons t int length = 0; };
// wrapper for default constructor // wrapper for default constructor
template<typename T> template<typename __T>
inline const T wrap_dcons(T*) { return T(); } inline const __T wrap_dcons(__T*) { return __T(); }
} // namespace internal } // namespace internal
// tuple definition // tuple definition
template<typename T0, typename T1, typename T2, typename T3, typename T4 __ template<typename __T0, typename __T1, typename __T2, typename __T3, typena
TBB_TYPENAME_T_PACK > me __T4 __TBB_TYPENAME_T_PACK >
class tuple : public internal::tuple_traits<T0, T1, T2, T3, T4 __TBB_T_PACK class tuple : public internal::tuple_traits<__T0, __T1, __T2, __T3, __T4 __
>::U { TBB_T_PACK >::U {
// friends // friends
template <typename T> friend class tuple_size; template <typename __T> friend class tuple_size;
template<int N, typename T> friend struct tuple_element; template<int __N, typename __T> friend struct tuple_element;
// stl components // stl components
typedef tuple<T0,T1,T2,T3,T4 __TBB_T_PACK > value_type; typedef tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > value_type;
typedef value_type *pointer; typedef value_type *pointer;
typedef const value_type *const_pointer; typedef const value_type *const_pointer;
typedef value_type &reference; typedef value_type &reference;
typedef const value_type &const_reference; typedef const value_type &const_reference;
typedef size_t size_type; typedef size_t size_type;
typedef typename internal::tuple_traits<T0,T1,T2,T3, T4 __TBB_T_PACK >: :U my_cons; typedef typename internal::tuple_traits<__T0,__T1,__T2,__T3, __T4 __TBB _T_PACK >::U my_cons;
public: public:
tuple(const T0& t0=internal::wrap_dcons((T0*)NULL) tuple(const __T0& t0=internal::wrap_dcons((__T0*)NULL)
,const T1& t1=internal::wrap_dcons((T1*)NULL) ,const __T1& t1=internal::wrap_dcons((__T1*)NULL)
,const T2& t2=internal::wrap_dcons((T2*)NULL) ,const __T2& t2=internal::wrap_dcons((__T2*)NULL)
,const T3& t3=internal::wrap_dcons((T3*)NULL) ,const __T3& t3=internal::wrap_dcons((__T3*)NULL)
,const T4& t4=internal::wrap_dcons((T4*)NULL) ,const __T4& t4=internal::wrap_dcons((__T4*)NULL)
#if __TBB_VARIADIC_MAX >= 6 #if __TBB_VARIADIC_MAX >= 6
,const T5& t5=internal::wrap_dcons((T5*)NULL) ,const __T5& t5=internal::wrap_dcons((__T5*)NULL)
#if __TBB_VARIADIC_MAX >= 7 #if __TBB_VARIADIC_MAX >= 7
,const T6& t6=internal::wrap_dcons((T6*)NULL) ,const __T6& t6=internal::wrap_dcons((__T6*)NULL)
#if __TBB_VARIADIC_MAX >= 8 #if __TBB_VARIADIC_MAX >= 8
,const T7& t7=internal::wrap_dcons((T7*)NULL) ,const __T7& t7=internal::wrap_dcons((__T7*)NULL)
#if __TBB_VARIADIC_MAX >= 9 #if __TBB_VARIADIC_MAX >= 9
,const T8& t8=internal::wrap_dcons((T8*)NULL) ,const __T8& t8=internal::wrap_dcons((__T8*)NULL)
#if __TBB_VARIADIC_MAX >= 10 #if __TBB_VARIADIC_MAX >= 10
,const T9& t9=internal::wrap_dcons((T9*)NULL) ,const __T9& t9=internal::wrap_dcons((__T9*)NULL)
#endif #endif
#endif #endif
#endif #endif
#endif #endif
#endif #endif
) : ) :
my_cons(t0,t1,t2,t3,t4 __TBB_T_PARAM_LIST_PACK) { } my_cons(t0,t1,t2,t3,t4 __TBB_T_PARAM_LIST_PACK) { }
template<int N> template<int __N>
struct internal_tuple_element { struct internal_tuple_element {
typedef typename internal::component<N,my_cons>::type type; typedef typename internal::component<__N,my_cons>::type type;
}; };
template<int N> template<int __N>
typename internal_tuple_element<N>::type& get() { return internal::get_ typename internal_tuple_element<__N>::type& get() { return internal::ge
helper<N>::get(*this); } t_helper<__N>::get(*this); }
template<int N> template<int __N>
typename internal_tuple_element<N>::type const& get() const { return in typename internal_tuple_element<__N>::type const& get() const { return
ternal::get_helper<N>::get(*this); } internal::get_helper<__N>::get(*this); }
template<typename U1, typename U2> template<typename __U1, typename __U2>
tuple& operator=(const internal::cons<U1,U2>& other) { tuple& operator=(const internal::cons<__U1,__U2>& other) {
my_cons::operator=(other); my_cons::operator=(other);
return *this; return *this;
} }
template<typename U1, typename U2> template<typename __U1, typename __U2>
tuple& operator=(const std::pair<U1,U2>& other) { tuple& operator=(const std::pair<__U1,__U2>& other) {
// __TBB_ASSERT(tuple_size<value_type>::value == 2, "Invalid size f or pair to tuple assignment"); // __TBB_ASSERT(tuple_size<value_type>::value == 2, "Invalid size f or pair to tuple assignment");
this->head = other.first; this->head = other.first;
this->tail.head = other.second; this->tail.head = other.second;
return *this; return *this;
} }
friend bool operator==(const tuple& me, const tuple& other) {return sta tic_cast<const my_cons &>(me)==(other);} friend bool operator==(const tuple& me, const tuple& other) {return sta tic_cast<const my_cons &>(me)==(other);}
friend bool operator<(const tuple& me, const tuple& other) {return sta tic_cast<const my_cons &>(me)<(other);} friend bool operator<(const tuple& me, const tuple& other) {return sta tic_cast<const my_cons &>(me)<(other);}
friend bool operator>(const tuple& me, const tuple& other) {return sta tic_cast<const my_cons &>(me)>(other);} friend bool operator>(const tuple& me, const tuple& other) {return sta tic_cast<const my_cons &>(me)>(other);}
friend bool operator!=(const tuple& me, const tuple& other) {return sta tic_cast<const my_cons &>(me)!=(other);} friend bool operator!=(const tuple& me, const tuple& other) {return sta tic_cast<const my_cons &>(me)!=(other);}
skipping to change at line 435 skipping to change at line 435
}; // tuple }; // tuple
// empty tuple // empty tuple
template<> template<>
class tuple<null_type, null_type, null_type, null_type, null_type __TBB_NUL L_TYPE_PACK > : public null_type { class tuple<null_type, null_type, null_type, null_type, null_type __TBB_NUL L_TYPE_PACK > : public null_type {
}; };
// helper classes // helper classes
template < typename T> template < typename __T>
class tuple_size { class tuple_size {
public: public:
static const size_t value = 1 + tuple_size<typename T::tail_type>::valu e; static const size_t value = 1 + tuple_size<typename __T::tail_type>::va lue;
}; };
template <> template <>
class tuple_size<tuple<> > { class tuple_size<tuple<> > {
public: public:
static const size_t value = 0; static const size_t value = 0;
}; };
template <> template <>
class tuple_size<null_type> { class tuple_size<null_type> {
public: public:
static const size_t value = 0; static const size_t value = 0;
}; };
template<int N, typename T> template<int __N, typename __T>
struct tuple_element { struct tuple_element {
typedef typename internal::component<N, typename T::my_cons>::type type ; typedef typename internal::component<__N, typename __T::my_cons>::type type;
}; };
template<int N, typename T0, typename T1, typename T2, typename T3, typenam template<int __N, typename __T0, typename __T1, typename __T2, typename __T
e T4 __TBB_TYPENAME_T_PACK > 3, typename __T4 __TBB_TYPENAME_T_PACK >
inline static typename tuple_element<N,tuple<T0,T1,T2,T3,T4 __TBB_T_PACK > inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __T
>::type& BB_T_PACK > >::type&
get(tuple<T0,T1,T2,T3,T4 __TBB_T_PACK >& t) { return internal::get_help get(tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return internal
er<N>::get(t); } ::get_helper<__N>::get(t); }
template<int N, typename T0, typename T1, typename T2, typename T3, typenam template<int __N, typename __T0, typename __T1, typename __T2, typename __T
e T4 __TBB_TYPENAME_T_PACK > 3, typename __T4 __TBB_TYPENAME_T_PACK >
inline static typename tuple_element<N,tuple<T0,T1,T2,T3,T4 __TBB_T_PACK > inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __T
>::type const& BB_T_PACK > >::type const&
get(const tuple<T0,T1,T2,T3,T4 __TBB_T_PACK >& t) { return internal::ge get(const tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return in
t_helper<N>::get(t); } ternal::get_helper<__N>::get(t); }
} // interface5 } // interface5
} // tbb } // tbb
#if !__TBB_CPP11_TUPLE_PRESENT #if !__TBB_CPP11_TUPLE_PRESENT
namespace tbb { namespace tbb {
namespace flow { namespace flow {
using tbb::interface5::tuple; using tbb::interface5::tuple;
using tbb::interface5::tuple_size; using tbb::interface5::tuple_size;
using tbb::interface5::tuple_element; using tbb::interface5::tuple_element;
 End of changes. 77 change blocks. 
189 lines changed or deleted 193 lines changed or added


 windows_ia32.h   windows_ia32.h 
skipping to change at line 139 skipping to change at line 139
{ {
mov eax, addend mov eax, addend
mov edx, [operand] mov edx, [operand]
lock and [edx], eax lock and [edx], eax
} }
} }
#define __TBB_AtomicOR(P,V) __TBB_machine_OR(P,V) #define __TBB_AtomicOR(P,V) __TBB_machine_OR(P,V)
#define __TBB_AtomicAND(P,V) __TBB_machine_AND(P,V) #define __TBB_AtomicAND(P,V) __TBB_machine_AND(P,V)
//TODO: Check if it possible and profitable for IA-32 on (Linux and Windows ) //TODO: Check if it possible and profitable for IA-32 architecture on (Linu x and Windows)
//to use of 64-bit load/store via floating point registers together with fu ll fence //to use of 64-bit load/store via floating point registers together with fu ll fence
//for sequentially consistent load/store, instead of CAS. //for sequentially consistent load/store, instead of CAS.
#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 #define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1
#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 #define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1
#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 #define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1
#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
#pragma warning (pop) #pragma warning (pop)
#endif // warnings 4244, 4267 are back #endif // warnings 4244, 4267 are back
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/