_concurrent_unordered_impl.h   _concurrent_unordered_impl.h 
skipping to change at line 219 skipping to change at line 219
typedef typename allocator_type::value_type value_type; typedef typename allocator_type::value_type value_type;
typedef solist_iterator<self_type, const value_type> const_iterator; typedef solist_iterator<self_type, const value_type> const_iterator;
typedef solist_iterator<self_type, value_type> iterator; typedef solist_iterator<self_type, value_type> iterator;
typedef flist_iterator<self_type, const value_type> raw_const_iterator; typedef flist_iterator<self_type, const value_type> raw_const_iterator;
typedef flist_iterator<self_type, value_type> raw_iterator; typedef flist_iterator<self_type, value_type> raw_iterator;
// Node that holds the element in a split-ordered list // Node that holds the element in a split-ordered list
struct node : tbb::internal::no_assign struct node : tbb::internal::no_assign
{ {
private:
// for compilers that try to generate default constructors though t
hey are not needed.
node(); // VS 2008, 2010, 2012
public:
// Initialize the node with the given order key // Initialize the node with the given order key
void init(sokey_t order_key) { void init(sokey_t order_key) {
my_order_key = order_key; my_order_key = order_key;
my_next = NULL; my_next = NULL;
} }
// Return the order key (needed for hashing) // Return the order key (needed for hashing)
sokey_t get_order_key() const { // TODO: remove sokey_t get_order_key() const { // TODO: remove
return my_order_key; return my_order_key;
} }
 End of changes. 1 change blocks. 
0 lines changed or deleted 5 lines changed or added


 enumerable_thread_specific.h   enumerable_thread_specific.h 
skipping to change at line 35 skipping to change at line 35
invalidate any other reasons why the executable file might be covered b y invalidate any other reasons why the executable file might be covered b y
the GNU General Public License. the GNU General Public License.
*/ */
#ifndef __TBB_enumerable_thread_specific_H #ifndef __TBB_enumerable_thread_specific_H
#define __TBB_enumerable_thread_specific_H #define __TBB_enumerable_thread_specific_H
#include "concurrent_vector.h" #include "concurrent_vector.h"
#include "tbb_thread.h" #include "tbb_thread.h"
#include "tbb_allocator.h" #include "tbb_allocator.h"
#include "tbb_profiling.h"
#include "cache_aligned_allocator.h" #include "cache_aligned_allocator.h"
#include "aligned_space.h" #include "aligned_space.h"
#include <string.h> // for memcpy #include <string.h> // for memcpy
#if _WIN32||_WIN64 #if _WIN32||_WIN64
#include "machine/windows_api.h" #include "machine/windows_api.h"
#else #else
#include <pthread.h> #include <pthread.h>
#endif #endif
namespace tbb { namespace tbb {
//! enum for selecting between single key and key-per-instance versions //! enum for selecting between single key and key-per-instance versions
enum ets_key_usage_type { ets_key_per_instance, ets_no_key }; enum ets_key_usage_type { ets_key_per_instance, ets_no_key };
namespace interface6 { namespace interface6 {
//! @cond //! @cond
namespace internal { namespace internal {
using namespace tbb::internal;
template<ets_key_usage_type ETS_key_type> template<ets_key_usage_type ETS_key_type>
class ets_base: tbb::internal::no_copy { class ets_base: tbb::internal::no_copy {
protected: protected:
#if _WIN32||_WIN64 #if _WIN32||_WIN64
typedef DWORD key_type; typedef DWORD key_type;
#else #else
typedef pthread_t key_type; typedef pthread_t key_type;
#endif #endif
#if __TBB_PROTECTED_NESTED_CLASS_BROKEN #if __TBB_PROTECTED_NESTED_CLASS_BROKEN
public: public:
skipping to change at line 130 skipping to change at line 133
static size_t hash( key_type k ) { static size_t hash( key_type k ) {
// Multiplicative hashing. Client should use *upper* bits. // Multiplicative hashing. Client should use *upper* bits.
// casts required for Mac gcc4.* compiler // casts required for Mac gcc4.* compiler
return uintptr_t(k)*tbb::internal::select_size_t_constant<0 x9E3779B9,0x9E3779B97F4A7C15ULL>::value; return uintptr_t(k)*tbb::internal::select_size_t_constant<0 x9E3779B9,0x9E3779B97F4A7C15ULL>::value;
} }
ets_base() {my_root=NULL; my_count=0;} ets_base() {my_root=NULL; my_count=0;}
virtual ~ets_base(); // g++ complains if this is not virtual.. . virtual ~ets_base(); // g++ complains if this is not virtual.. .
void* table_lookup( bool& exists ); void* table_lookup( bool& exists );
void table_clear(); void table_clear();
// table_find is used in copying ETS, so is not used in concurr
ent context. So
// we don't need itt annotations for it.
slot& table_find( key_type k ) { slot& table_find( key_type k ) {
size_t h = hash(k); size_t h = hash(k);
array* r = my_root; array* r = my_root;
size_t mask = r->mask(); size_t mask = r->mask();
for(size_t i = r->start(h);;i=(i+1)&mask) { for(size_t i = r->start(h);;i=(i+1)&mask) {
slot& s = r->at(i); slot& s = r->at(i);
if( s.empty() || s.match(k) ) if( s.empty() || s.match(k) )
return s; return s;
} }
} }
skipping to change at line 174 skipping to change at line 179
} }
template<ets_key_usage_type ETS_key_type> template<ets_key_usage_type ETS_key_type>
void* ets_base<ETS_key_type>::table_lookup( bool& exists ) { void* ets_base<ETS_key_type>::table_lookup( bool& exists ) {
const key_type k = key_of_current_thread(); const key_type k = key_of_current_thread();
__TBB_ASSERT(k!=0,NULL); __TBB_ASSERT(k!=0,NULL);
void* found; void* found;
size_t h = hash(k); size_t h = hash(k);
for( array* r=my_root; r; r=r->next ) { for( array* r=my_root; r; r=r->next ) {
call_itt_notify(acquired,r);
size_t mask=r->mask(); size_t mask=r->mask();
for(size_t i = r->start(h); ;i=(i+1)&mask) { for(size_t i = r->start(h); ;i=(i+1)&mask) {
slot& s = r->at(i); slot& s = r->at(i);
if( s.empty() ) break; if( s.empty() ) break;
if( s.match(k) ) { if( s.match(k) ) {
if( r==my_root ) { if( r==my_root ) {
// Success at top level // Success at top level
exists = true; exists = true;
return s.ptr; return s.ptr;
} else { } else {
// Success at some other level. Need to insert at top level. // Success at some other level. Need to insert at top level.
exists = true; exists = true;
found = s.ptr; found = s.ptr;
goto insert; goto insert;
} }
} }
} }
} }
// Key does not yet exist // Key does not yet exist. The density of slots in the table d
oes not exceed 0.5,
// for if this will occur a new table is allocated with double
the current table
// size, which is swapped in as the new root table. So an empt
y slot is guaranteed.
exists = false; exists = false;
found = create_local(); found = create_local();
{ {
size_t c = ++my_count; size_t c = ++my_count;
array* r = my_root; array* r = my_root;
call_itt_notify(acquired,r);
if( !r || c>r->size()/2 ) { if( !r || c>r->size()/2 ) {
size_t s = r ? r->lg_size : 2; size_t s = r ? r->lg_size : 2;
while( c>size_t(1)<<(s-1) ) ++s; while( c>size_t(1)<<(s-1) ) ++s;
array* a = allocate(s); array* a = allocate(s);
for(;;) { for(;;) {
a->next = my_root; a->next = r;
call_itt_notify(releasing,a);
array* new_r = my_root.compare_and_swap(a,r); array* new_r = my_root.compare_and_swap(a,r);
if( new_r==r ) break; if( new_r==r ) break;
call_itt_notify(acquired, new_r);
if( new_r->lg_size>=s ) { if( new_r->lg_size>=s ) {
// Another thread inserted an equal or bigger array, so our array is superfluous. // Another thread inserted an equal or bigger array, so our array is superfluous.
free(a); free(a);
break; break;
} }
r = new_r; r = new_r;
} }
} }
} }
insert: insert:
// Guaranteed to be room for it, and it is not present, so sear // Whether a slot has been found in an older table, or if it has be
ch for empty slot and grab it. en inserted at this level,
// it has already been accounted for in the total. Guaranteed to b
e room for it, and it is
// not present, so search for empty slot and use it.
array* ir = my_root; array* ir = my_root;
call_itt_notify(acquired, ir);
size_t mask = ir->mask(); size_t mask = ir->mask();
for(size_t i = ir->start(h);;i=(i+1)&mask) { for(size_t i = ir->start(h);;i=(i+1)&mask) {
slot& s = ir->at(i); slot& s = ir->at(i);
if( s.empty() ) { if( s.empty() ) {
if( s.claim(k) ) { if( s.claim(k) ) {
s.ptr = found; s.ptr = found;
return found; return found;
} }
} }
} }
 End of changes. 10 change blocks. 
4 lines changed or deleted 23 lines changed or added


 gcc_armv7.h   gcc_armv7.h 
skipping to change at line 62 skipping to change at line 62
#if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_B IG_ENDIAN__) #if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_B IG_ENDIAN__)
#define __TBB_ENDIANNESS __TBB_ENDIAN_BIG #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG
#elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__OR DER_LITTLE_ENDIAN__) #elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__OR DER_LITTLE_ENDIAN__)
#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
#elif defined(__BYTE_ORDER__) #elif defined(__BYTE_ORDER__)
#define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED
#else #else
#define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT
#endif #endif
#define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory")
#define __TBB_full_memory_fence() __asm__ __volatile__("dmb ish": : :"memor
y")
#define __TBB_control_consistency_helper() __TBB_compiler_fence() #define __TBB_control_consistency_helper() __TBB_compiler_fence()
#define __TBB_acquire_consistency_helper() __TBB_full_memory_fence()
#define __TBB_armv7_inner_shareable_barrier() __asm__ __volatile__("dmb ish #define __TBB_release_consistency_helper() __TBB_full_memory_fence()
": : :"memory")
#define __TBB_acquire_consistency_helper() __TBB_armv7_inner_shareable_barr
ier()
#define __TBB_release_consistency_helper() __TBB_armv7_inner_shareable_barr
ier()
#define __TBB_full_memory_fence() __TBB_armv7_inner_shareable_barrier()
//-------------------------------------------------- //--------------------------------------------------
// Compare and swap // Compare and swap
//-------------------------------------------------- //--------------------------------------------------
/** /**
* Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, retur ns *ptr * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, retur ns *ptr
* @param ptr pointer to value in memory to be swapped with value if *ptr== comparand * @param ptr pointer to value in memory to be swapped with value if *ptr== comparand
* @param value value to assign *ptr to if *ptr==comparand * @param value value to assign *ptr to if *ptr==comparand
* @param comparand value to compare with *ptr * @param comparand value to compare with *ptr
skipping to change at line 199 skipping to change at line 197
namespace internal { namespace internal {
template <typename T, size_t S> template <typename T, size_t S>
struct machine_load_store_relaxed { struct machine_load_store_relaxed {
static inline T load ( const volatile T& location ) { static inline T load ( const volatile T& location ) {
const T value = location; const T value = location;
/* /*
* An extra memory barrier is required for errata #761319 * An extra memory barrier is required for errata #761319
* Please see http://infocenter.arm.com/help/topic/com.arm.doc.u an0004a * Please see http://infocenter.arm.com/help/topic/com.arm.doc.u an0004a
*/ */
__TBB_armv7_inner_shareable_barrier(); __TBB_acquire_consistency_helper();
return value; return value;
} }
static inline void store ( volatile T& location, T value ) { static inline void store ( volatile T& location, T value ) {
location = value; location = value;
} }
}; };
}} // namespaces internal, tbb }} // namespaces internal, tbb
// Machine specific atomic operations // Machine specific atomic operations
#define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) #define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C)
#define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) #define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C)
#define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp4(P,V,C)
#define __TBB_Pause(V) __TBB_machine_pause(V) #define __TBB_Pause(V) __TBB_machine_pause(V)
// Use generics for some things // Use generics for some things
#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_PART_WORD_FETCH_STORE 1 #define __TBB_USE_GENERIC_PART_WORD_FETCH_STORE 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_DWORD_LOAD_STORE 1 #define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1
#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
 End of changes. 4 change blocks. 
11 lines changed or deleted 6 lines changed or added


 icc_generic.h   icc_generic.h 
skipping to change at line 93 skipping to change at line 93
return value; return value;
} }
//The overload below is needed to have explicit conversion of pointer t o void* in argument list. //The overload below is needed to have explicit conversion of pointer t o void* in argument list.
//compiler bug? //compiler bug?
//TODO: add according broken macro and recheck with ICC 13.0 if the ove rload is still needed //TODO: add according broken macro and recheck with ICC 13.0 if the ove rload is still needed
template <typename T> template <typename T>
void* convert_argument(T* value){ void* convert_argument(T* value){
return (void*)value; return (void*)value;
} }
} }
//TODO: code bellow is a bit repetitive, consider simplifying it //TODO: code below is a bit repetitive, consider simplifying it
template <typename T, size_t S> template <typename T, size_t S>
struct machine_load_store { struct machine_load_store {
static T load_with_acquire ( const volatile T& location ) { static T load_with_acquire ( const volatile T& location ) {
return __atomic_load_explicit(&location, memory_order_acquire); return __atomic_load_explicit(&location, memory_order_acquire);
} }
static void store_with_release ( volatile T &location, T value ) { static void store_with_release ( volatile T &location, T value ) {
__atomic_store_explicit(&location, icc_intrinsics_port::convert_arg ument(value), memory_order_release); __atomic_store_explicit(&location, icc_intrinsics_port::convert_arg ument(value), memory_order_release);
} }
}; };
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 linux_ia32.h   linux_ia32.h 
skipping to change at line 96 skipping to change at line 96
__TBB_MACHINE_DEFINE_ATOMICS(2,int16_t,"","=r") __TBB_MACHINE_DEFINE_ATOMICS(2,int16_t,"","=r")
__TBB_MACHINE_DEFINE_ATOMICS(4,int32_t,"l","=r") __TBB_MACHINE_DEFINE_ATOMICS(4,int32_t,"l","=r")
#if __INTEL_COMPILER #if __INTEL_COMPILER
#pragma warning( push ) #pragma warning( push )
// reference to EBX in a function requiring stack alignment // reference to EBX in a function requiring stack alignment
#pragma warning( disable: 998 ) #pragma warning( disable: 998 )
#endif #endif
static inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t va lue, int64_t comparand ) { static inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t va lue, int64_t comparand ) {
#if __TBB_GCC_BUILTIN_ATOMICS_PRESENT //TODO: remove the extra part of condition once __TBB_GCC_BUILTIN_ATOMICS_P
RESENT is lowered to gcc version 4.1.2
#if __TBB_GCC_BUILTIN_ATOMICS_PRESENT || __TBB_GCC_VERSION >= 40304
return __sync_val_compare_and_swap( reinterpret_cast<volatile int64_t*> (ptr), comparand, value ); return __sync_val_compare_and_swap( reinterpret_cast<volatile int64_t*> (ptr), comparand, value );
#else /* !__TBB_GCC_BUILTIN_ATOMICS_PRESENT */ #else /* !__TBB_GCC_BUILTIN_ATOMICS_PRESENT */
//TODO: look like ICC 13.0 has some issues with this code, investigate it more deeply //TODO: look like ICC 13.0 has some issues with this code, investigate it more deeply
int64_t result; int64_t result;
union { union {
int64_t i64; int64_t i64;
int32_t i32[2]; int32_t i32[2];
}; };
i64 = value; i64 = value;
#if __PIC__ #if __PIC__
 End of changes. 1 change blocks. 
1 lines changed or deleted 3 lines changed or added


 msvc_armv7.h   msvc_armv7.h 
skipping to change at line 42 skipping to change at line 42
#define __TBB_msvc_armv7_H #define __TBB_msvc_armv7_H
#include <intrin.h> #include <intrin.h>
#include <float.h> #include <float.h>
#define __TBB_WORDSIZE 4 #define __TBB_WORDSIZE 4
#define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED
#define __TBB_compiler_fence() __dmb(_ARM_BARRIER_SY) #if defined(TBB_WIN32_USE_CL_BUILTINS)
// We can test this on _M_IX86
#pragma intrinsic(_ReadWriteBarrier)
#pragma intrinsic(_mm_mfence)
#define __TBB_compiler_fence() _ReadWriteBarrier()
#define __TBB_full_memory_fence() _mm_mfence()
#define __TBB_control_consistency_helper() __TBB_compiler_fence() #define __TBB_control_consistency_helper() __TBB_compiler_fence()
#define __TBB_acquire_consistency_helper() __TBB_compiler_fence()
#define __TBB_armv7_inner_shareable_barrier() __dmb(_ARM_BARRIER_ISH) #define __TBB_release_consistency_helper() __TBB_compiler_fence()
#define __TBB_acquire_consistency_helper() __TBB_armv7_inner_shareable_barr #else
ier() //Now __dmb(_ARM_BARRIER_SY) is used for both compiler and memory fences
#define __TBB_release_consistency_helper() __TBB_armv7_inner_shareable_barr //This might be changed later after testing
ier() #define __TBB_compiler_fence() __dmb(_ARM_BARRIER_SY)
#define __TBB_full_memory_fence() __TBB_armv7_inner_shareable_barrier() #define __TBB_full_memory_fence() __dmb(_ARM_BARRIER_SY)
#define __TBB_control_consistency_helper() __TBB_compiler_fence()
#define __TBB_acquire_consistency_helper() __TBB_full_memory_fence()
#define __TBB_release_consistency_helper() __TBB_full_memory_fence()
#endif
//-------------------------------------------------- //--------------------------------------------------
// Compare and swap // Compare and swap
//-------------------------------------------------- //--------------------------------------------------
/** /**
* Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, retur ns *ptr * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, retur ns *ptr
* @param ptr pointer to value in memory to be swapped with value if *ptr== comparand * @param ptr pointer to value in memory to be swapped with value if *ptr== comparand
* @param value value to assign *ptr to if *ptr==comparand * @param value value to assign *ptr to if *ptr==comparand
* @param comparand value to compare with *ptr * @param comparand value to compare with *ptr
* @return value originally in memory at ptr, regardless of success * @return value originally in memory at ptr, regardless of success
*/ */
#define __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(S,T,F) \ #define __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(S,T,F) \
inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) { \ inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) { \
return _InterlockedCompareExchange##F(reinterpret_cast<volatile T *> (ptr),comparand,value); \ return _InterlockedCompareExchange##F(reinterpret_cast<volatile T *>(pt r),value,comparand); \
} \ } \
#define __TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(S,T,F) \ #define __TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(S,T,F) \
inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) { \ inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) { \
return _InterlockedAdd##F(reinterpret_cast<volatile T *>(ptr),value) ; \ return _InterlockedExchangeAdd##F(reinterpret_cast<volatile T *>(ptr),v alue); \
} \ } \
__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(1,char,8) __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(1,char,8)
__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(2,short,16) __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(2,short,16)
__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(4,long,) __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(4,long,)
__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(8,__int64,64) __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(8,__int64,64)
__TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(4,long,) __TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(4,long,)
#if defined(TBB_WIN32_USE_CL_BUILTINS)
// No _InterlockedExchangeAdd64 intrinsic on _M_IX86
#define __TBB_64BIT_ATOMICS 0
#else
__TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(8,__int64,64) __TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(8,__int64,64)
#endif
inline void __TBB_machine_pause (int32_t delay ) inline void __TBB_machine_pause (int32_t delay )
{ {
while(delay>0) while(delay>0)
{ {
__TBB_compiler_fence(); __TBB_compiler_fence();
delay--; delay--;
} }
} }
namespace tbb { namespace tbb {
namespace internal { namespace internal {
template <typename T, size_t S> template <typename T, size_t S>
struct machine_load_store_relaxed { struct machine_load_store_relaxed {
static inline T load ( const volatile T& location ) { static inline T load ( const volatile T& location ) {
const T value = location; const T value = location;
/* /*
* An extra memory barrier is required for errata #761319 * An extra memory barrier is required for errata #761319
* Please see http://infocenter.arm.com/help/topic/com.arm.doc.u * Please see http://infocenter.arm.com/help/topic/com.arm.d
an0004a oc.uan0004a
*/ */
__TBB_armv7_inner_shareable_barrier(); __TBB_acquire_consistency_helper();
return value; return value;
} }
static inline void store ( volatile T& location, T value ) { static inline void store ( volatile T& location, T value ) {
location = value; location = value;
} }
}; };
}} // namespaces internal, tbb }} // namespaces internal, tbb
// Machine specific atomic operations // Machine specific atomic operations
#define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) #define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C)
#define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) #define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C)
#define __TBB_Pause(V) __TBB_machine_pause(V) #define __TBB_Pause(V) __TBB_machine_pause(V)
// Use generics for some things // Use generics for some things
#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1
#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1
#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 #define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1
#define __TBB_USE_GENERIC_PART_WORD_FETCH_STORE 1 #define __TBB_USE_GENERIC_PART_WORD_FETCH_STORE 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_DWORD_LOAD_STORE 1 #define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1
#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 #define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
#if defined(TBB_WIN32_USE_CL_BUILTINS)
#if !__TBB_WIN8UI_SUPPORT
extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void );
#define __TBB_Yield() SwitchToThread()
#else
#include<thread>
#define __TBB_Yield() std::this_thread::yield()
#endif
#else
#define __TBB_Yield() __yield() #define __TBB_Yield() __yield()
#endif
// API to retrieve/update FPU control setting not implemented // API to retrieve/update FPU control setting
#define __TBB_CPU_CTL_ENV_PRESENT 1 #define __TBB_CPU_CTL_ENV_PRESENT 1
typedef unsigned int __TBB_cpu_ctl_env_t; typedef unsigned int __TBB_cpu_ctl_env_t;
inline void __TBB_get_cpu_ctl_env ( __TBB_cpu_ctl_env_t* ctl ) { inline void __TBB_get_cpu_ctl_env ( __TBB_cpu_ctl_env_t* ctl ) {
*ctl = _control87(0, 0); *ctl = _control87(0, 0);
} }
inline void __TBB_set_cpu_ctl_env ( const __TBB_cpu_ctl_env_t* ctl ) { inline void __TBB_set_cpu_ctl_env ( const __TBB_cpu_ctl_env_t* ctl ) {
_control87( *ctl, ~0U ); _control87( *ctl, ~0U );
} }
 End of changes. 14 change blocks. 
34 lines changed or deleted 58 lines changed or added


 spin_mutex.h   spin_mutex.h 
skipping to change at line 89 skipping to change at line 89
void __TBB_EXPORTED_METHOD internal_release(); void __TBB_EXPORTED_METHOD internal_release();
friend class spin_mutex; friend class spin_mutex;
public: public:
//! Construct without acquiring a mutex. //! Construct without acquiring a mutex.
scoped_lock() : my_mutex(NULL), my_unlock_value(0) {} scoped_lock() : my_mutex(NULL), my_unlock_value(0) {}
//! Construct and acquire lock on a mutex. //! Construct and acquire lock on a mutex.
scoped_lock( spin_mutex& m ) : my_unlock_value(0) { scoped_lock( spin_mutex& m ) : my_unlock_value(0) {
internal::suppress_unused_warning(my_unlock_value);
#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
my_mutex=NULL; my_mutex=NULL;
internal_acquire(m); internal_acquire(m);
#else #else
__TBB_LockByte(m.flag); __TBB_LockByte(m.flag);
my_mutex=&m; my_mutex=&m;
#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/
} }
//! Acquire lock. //! Acquire lock.
 End of changes. 1 change blocks. 
0 lines changed or deleted 1 lines changed or added


 tbb_config.h   tbb_config.h 
skipping to change at line 248 skipping to change at line 248
#endif #endif
#elif TBB_USE_EXCEPTIONS && __TBB_DEFINE_MIC #elif TBB_USE_EXCEPTIONS && __TBB_DEFINE_MIC
#error Please do not set TBB_USE_EXCEPTIONS macro or set it to 0. #error Please do not set TBB_USE_EXCEPTIONS macro or set it to 0.
#endif #endif
#ifndef TBB_IMPLEMENT_CPP0X #ifndef TBB_IMPLEMENT_CPP0X
/** By default, use C++0x classes if available **/ /** By default, use C++0x classes if available **/
#if __GNUC__==4 && __GNUC_MINOR__>=4 && __GXX_EXPERIMENTAL_CXX0X__ #if __GNUC__==4 && __GNUC_MINOR__>=4 && __GXX_EXPERIMENTAL_CXX0X__
#define TBB_IMPLEMENT_CPP0X 0 #define TBB_IMPLEMENT_CPP0X 0
#elif __clang__ && __cplusplus >= 201103L #elif __clang__ && __cplusplus >= 201103L
//TODO: consider introducing separate macroses for each file? //TODO: consider introducing separate macros for each file?
//prevent injection of according tbb names into std:: namespace if //prevent injection of corresponding tbb names into std:: namespace
native headers are present if native headers are present
#if __has_include(<thread>) || __has_include(<condition_variable>) #if __has_include(<thread>) || __has_include(<condition_variable>)
#define TBB_IMPLEMENT_CPP0X 0 #define TBB_IMPLEMENT_CPP0X 0
#else #else
#define TBB_IMPLEMENT_CPP0X 1 #define TBB_IMPLEMENT_CPP0X 1
#endif #endif
#else #else
#define TBB_IMPLEMENT_CPP0X 1 #define TBB_IMPLEMENT_CPP0X 1
#endif #endif
#endif /* TBB_IMPLEMENT_CPP0X */ #endif /* TBB_IMPLEMENT_CPP0X */
 End of changes. 1 change blocks. 
3 lines changed or deleted 3 lines changed or added


 tbb_exception.h   tbb_exception.h 
skipping to change at line 164 skipping to change at line 164
TBB provides two implementations of this interface: tbb::captured_excep tion and TBB provides two implementations of this interface: tbb::captured_excep tion and
template class tbb::movable_exception. See their declarations for more info. **/ template class tbb::movable_exception. See their declarations for more info. **/
class tbb_exception : public std::exception class tbb_exception : public std::exception
{ {
/** No operator new is provided because the TBB usage model assumes dyn amic /** No operator new is provided because the TBB usage model assumes dyn amic
creation of the TBB exception objects only by means of applying mov e() creation of the TBB exception objects only by means of applying mov e()
operation on an exception thrown out of TBB scheduler. **/ operation on an exception thrown out of TBB scheduler. **/
void* operator new ( size_t ); void* operator new ( size_t );
public: public:
#if __clang__
// At -O3 or even -O2 optimization level, Clang may fully throw away an
empty destructor
// of tbb_exception from destructors of derived classes. As a result, i
t does not create
// vtable for tbb_exception, which is a required part of TBB binary int
erface.
// Making the destructor non-empty (with just a semicolon) prevents tha
t optimization.
~tbb_exception() throw() { /* keep the semicolon! */ ; }
#endif
//! Creates and returns pointer to the deep copy of this exception obje ct. //! Creates and returns pointer to the deep copy of this exception obje ct.
/** Move semantics is allowed. **/ /** Move semantics is allowed. **/
virtual tbb_exception* move () throw() = 0; virtual tbb_exception* move () throw() = 0;
//! Destroys objects created by the move() method. //! Destroys objects created by the move() method.
/** Frees memory and calls destructor for this exception object. /** Frees memory and calls destructor for this exception object.
Can and must be used only on objects created by the move method. ** / Can and must be used only on objects created by the move method. ** /
virtual void destroy () throw() = 0; virtual void destroy () throw() = 0;
//! Throws this exception object. //! Throws this exception object.
 End of changes. 1 change blocks. 
0 lines changed or deleted 12 lines changed or added


 tbb_machine.h   tbb_machine.h 
skipping to change at line 217 skipping to change at line 217
#define __TBB_Yield() SwitchToThread() #define __TBB_Yield() SwitchToThread()
#if (TBB_USE_GCC_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT) #if (TBB_USE_GCC_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT)
#include "machine/gcc_generic.h" #include "machine/gcc_generic.h"
#elif __MINGW64__ #elif __MINGW64__
#include "machine/linux_intel64.h" #include "machine/linux_intel64.h"
#elif __MINGW32__ #elif __MINGW32__
#include "machine/linux_ia32.h" #include "machine/linux_ia32.h"
#endif #endif
#elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) #elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT)
#include "machine/icc_generic.h" #include "machine/icc_generic.h"
#elif defined(_M_IX86) #elif defined(_M_IX86) && !defined(__TBB_WIN32_USE_CL_BUILTINS)
#include "machine/windows_ia32.h" #include "machine/windows_ia32.h"
#elif defined(_M_X64) #elif defined(_M_X64)
#include "machine/windows_intel64.h" #include "machine/windows_intel64.h"
#elif _XBOX #elif defined(_XBOX)
#include "machine/xbox360_ppc.h" #include "machine/xbox360_ppc.h"
#elif _M_ARM #elif defined(_M_ARM) || defined(__TBB_WIN32_USE_CL_BUILTINS)
#include "machine/msvc_armv7.h" #include "machine/msvc_armv7.h"
#endif #endif
#ifdef _MANAGED #ifdef _MANAGED
#pragma managed(pop) #pragma managed(pop)
#endif #endif
#elif __TBB_DEFINE_MIC #elif __TBB_DEFINE_MIC
#include "machine/mic_common.h" #include "machine/mic_common.h"
skipping to change at line 851 skipping to change at line 851
// Mapping historically used names to the ones expected by atomic_load_stor e_traits // Mapping historically used names to the ones expected by atomic_load_stor e_traits
#define __TBB_load_acquire __TBB_load_with_acquire #define __TBB_load_acquire __TBB_load_with_acquire
#define __TBB_store_release __TBB_store_with_release #define __TBB_store_release __TBB_store_with_release
#ifndef __TBB_Log2 #ifndef __TBB_Log2
inline intptr_t __TBB_Log2( uintptr_t x ) { inline intptr_t __TBB_Log2( uintptr_t x ) {
if( x==0 ) return -1; if( x==0 ) return -1;
intptr_t result = 0; intptr_t result = 0;
#ifndef _M_ARM #if !defined(_M_ARM)
uintptr_t tmp; uintptr_t tmp;
if( sizeof(x)>4 && (tmp = ((uint64_t)x)>>32) ) { x=tmp; result += 32 ; } if( sizeof(x)>4 && (tmp = ((uint64_t)x)>>32) ) { x=tmp; result += 32; }
#endif #endif
if( uintptr_t tmp = x>>16 ) { x=tmp; result += 16; } if( uintptr_t tmp = x>>16 ) { x=tmp; result += 16; }
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
 End of changes. 5 change blocks. 
5 lines changed or deleted 5 lines changed or added


 tbb_stddef.h   tbb_stddef.h 
skipping to change at line 390 skipping to change at line 390
//! A function to determine if "arg is a multiplication of a number and a p ower of 2". //! A function to determine if "arg is a multiplication of a number and a p ower of 2".
// 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.
template<typename T>
void suppress_unused_warning( const T& ) {}
// 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
//! @endcond //! @endcond
 End of changes. 1 change blocks. 
0 lines changed or deleted 5 lines changed or added


 tick_count.h   tick_count.h 
skipping to change at line 82 skipping to change at line 82
//! Subtract two intervals. //! Subtract two intervals.
friend interval_t operator-( const interval_t& i, const interval_t& j ) { friend interval_t operator-( const interval_t& i, const interval_t& j ) {
return interval_t(i.value-j.value); return interval_t(i.value-j.value);
} }
//! Accumulation operator //! Accumulation operator
interval_t& operator+=( const interval_t& i ) {value += i.value; re turn *this;} interval_t& operator+=( const interval_t& i ) {value += i.value; re turn *this;}
//! Subtraction operator //! Subtraction operator
interval_t& operator-=( const interval_t& i ) {value -= i.value; re turn *this;} interval_t& operator-=( const interval_t& i ) {value -= i.value; re turn *this;}
private:
static long long ticks_per_second(){
#if _WIN32||_WIN64
LARGE_INTEGER qpfreq;
int rval = QueryPerformanceFrequency(&qpfreq);
__TBB_ASSERT_EX(rval, "QueryPerformanceFrequency returned zero"
);
return static_cast<long long>(qpfreq.QuadPart);
#elif __linux__
return static_cast<long long>(1E9);
#else /* generic Unix */
return static_cast<long long>(1E6);
#endif /* (choice of OS) */
}
}; };
//! Construct an absolute timestamp initialized to zero. //! Construct an absolute timestamp initialized to zero.
tick_count() : my_count(0) {}; tick_count() : my_count(0) {};
//! Return current time. //! Return current time.
static tick_count now(); static tick_count now();
//! Subtract two timestamps to get the time interval between //! Subtract two timestamps to get the time interval between
friend interval_t operator-( const tick_count& t1, const tick_count& t0 ); friend interval_t operator-( const tick_count& t1, const tick_count& t0 );
//! Return the resolution of the clock in seconds per tick.
static double resolution() { return 1.0 / interval_t::ticks_per_second(
); }
private: private:
long long my_count; long long my_count;
}; };
inline tick_count tick_count::now() { inline tick_count tick_count::now() {
tick_count result; tick_count result;
#if _WIN32||_WIN64 #if _WIN32||_WIN64
LARGE_INTEGER qpcnt; LARGE_INTEGER qpcnt;
QueryPerformanceCounter(&qpcnt); int rval = QueryPerformanceCounter(&qpcnt);
__TBB_ASSERT_EX(rval, "QueryPerformanceCounter failed");
result.my_count = qpcnt.QuadPart; result.my_count = qpcnt.QuadPart;
#elif __linux__ #elif __linux__
struct timespec ts; struct timespec ts;
#if TBB_USE_ASSERT int status = clock_gettime( CLOCK_REALTIME, &ts );
int status = __TBB_ASSERT_EX( status==0, "CLOCK_REALTIME not supported" );
#endif /* TBB_USE_ASSERT */
clock_gettime( CLOCK_REALTIME, &ts );
__TBB_ASSERT( status==0, "CLOCK_REALTIME not supported" );
result.my_count = static_cast<long long>(1000000000UL)*static_cast<long long>(ts.tv_sec) + static_cast<long long>(ts.tv_nsec); result.my_count = static_cast<long long>(1000000000UL)*static_cast<long long>(ts.tv_sec) + static_cast<long long>(ts.tv_nsec);
#else /* generic Unix */ #else /* generic Unix */
struct timeval tv; struct timeval tv;
#if TBB_USE_ASSERT int status = gettimeofday(&tv, NULL);
int status = __TBB_ASSERT_EX( status==0, "gettimeofday failed" );
#endif /* TBB_USE_ASSERT */
gettimeofday(&tv, NULL);
__TBB_ASSERT( status==0, "gettimeofday failed" );
result.my_count = static_cast<long long>(1000000)*static_cast<long long >(tv.tv_sec) + static_cast<long long>(tv.tv_usec); result.my_count = static_cast<long long>(1000000)*static_cast<long long >(tv.tv_sec) + static_cast<long long>(tv.tv_usec);
#endif /*(choice of OS) */ #endif /*(choice of OS) */
return result; return result;
} }
inline tick_count::interval_t::interval_t( double sec ) inline tick_count::interval_t::interval_t( double sec ) {
{ value = static_cast<long long>(sec*interval_t::ticks_per_second());
#if _WIN32||_WIN64
LARGE_INTEGER qpfreq;
QueryPerformanceFrequency(&qpfreq);
value = static_cast<long long>(sec*qpfreq.QuadPart);
#elif __linux__
value = static_cast<long long>(sec*1E9);
#else /* generic Unix */
value = static_cast<long long>(sec*1E6);
#endif /* (choice of OS) */
} }
inline tick_count::interval_t operator-( const tick_count& t1, const tick_c ount& t0 ) { inline tick_count::interval_t operator-( const tick_count& t1, const tick_c ount& t0 ) {
return tick_count::interval_t( t1.my_count-t0.my_count ); return tick_count::interval_t( t1.my_count-t0.my_count );
} }
inline double tick_count::interval_t::seconds() const { inline double tick_count::interval_t::seconds() const {
#if _WIN32||_WIN64 return value*tick_count::resolution();
LARGE_INTEGER qpfreq;
QueryPerformanceFrequency(&qpfreq);
return value/(double)qpfreq.QuadPart;
#elif __linux__
return value*1E-9;
#else /* generic Unix */
return value*1E-6;
#endif /* (choice of OS) */
} }
} // namespace tbb } // namespace tbb
#endif /* __TBB_tick_count_H */ #endif /* __TBB_tick_count_H */
 End of changes. 7 change blocks. 
31 lines changed or deleted 27 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/