| _aggregator_impl.h | | _aggregator_impl.h | |
| | | | |
| skipping to change at line 33 | | skipping to change at line 33 | |
| file does not by itself cause the resulting executable to be covered by | | file does not by itself cause the resulting executable to be covered by | |
| the GNU General Public License. This exception does not however | | the GNU General Public License. This exception does not however | |
| 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__aggregator_impl_H | | #ifndef __TBB__aggregator_impl_H | |
| #define __TBB__aggregator_impl_H | | #define __TBB__aggregator_impl_H | |
| | | | |
| #include "../atomic.h" | | #include "../atomic.h" | |
|
| | | #if !__TBBMALLOC_BUILD | |
| #include "../tbb_profiling.h" | | #include "../tbb_profiling.h" | |
|
| | | #endif | |
| | | | |
| namespace tbb { | | namespace tbb { | |
| namespace interface6 { | | namespace interface6 { | |
| namespace internal { | | namespace internal { | |
| | | | |
| using namespace tbb::internal; | | using namespace tbb::internal; | |
| | | | |
| //! aggregated_operation base class | | //! aggregated_operation base class | |
| template <typename Derived> | | template <typename Derived> | |
| class aggregated_operation { | | class aggregated_operation { | |
| | | | |
| skipping to change at line 56 | | skipping to change at line 58 | |
| Derived *next; | | Derived *next; | |
| aggregated_operation() : status(0), next(NULL) {} | | aggregated_operation() : status(0), next(NULL) {} | |
| }; | | }; | |
| | | | |
| //! Aggregator base class | | //! Aggregator base class | |
| /** An aggregator for collecting operations coming from multiple sources an
d executing | | /** An aggregator for collecting operations coming from multiple sources an
d executing | |
| them serially on a single thread. operation_type must be derived from | | them serially on a single thread. operation_type must be derived from | |
| aggregated_operation. The parameter handler_type is a functor that will
be passed the | | aggregated_operation. The parameter handler_type is a functor that will
be passed the | |
| list of operations and is expected to handle each operation appropriate
ly, setting the | | list of operations and is expected to handle each operation appropriate
ly, setting the | |
| status of each operation to non-zero.*/ | | status of each operation to non-zero.*/ | |
|
| template < typename handler_type, typename operation_type > | | template < typename operation_type > | |
| class aggregator { | | class aggregator_generic { | |
| public: | | public: | |
| aggregator() : handler_busy(false) { pending_operations = NULL; } | | aggregator_generic() : handler_busy(false) { pending_operations = NULL; | |
| explicit aggregator(handler_type h) : handler_busy(false), handle_opera | | } | |
| tions(h) { | | | |
| pending_operations = NULL; | | | |
| } | | | |
| | | | |
| void initialize_handler(handler_type h) { handle_operations = h; } | | | |
| | | | |
| //! Place operation in list | | //! Place operation in list | |
| /** Place operation in list and either handle list or wait for operatio
n to | | /** Place operation in list and either handle list or wait for operatio
n to | |
|
| complete. */ | | complete. | |
| void execute(operation_type *op) { | | long_life_time specifies life time of an operation inserting in an | |
| | | aggregator. | |
| | | "Long" (long_life_time == true) life time operation can be accessed | |
| | | even after executing it. | |
| | | "Short" (long_life_time == false) life time operations can be destr | |
| | | oyed | |
| | | during executing so any access to it after executing is invalid.*/ | |
| | | template < typename handler_type > | |
| | | void execute(operation_type *op, handler_type &handle_operations, bool | |
| | | long_life_time = true) { | |
| operation_type *res; | | operation_type *res; | |
|
| | | // op->status should be read before inserting the operation in the | |
| | | // aggregator queue since it can become invalid after executing a | |
| | | // handler (if the operation has 'short' life time.) | |
| | | const uintptr_t status = op->status; | |
| | | | |
| // ITT note: &(op->status) tag is used to cover accesses to this op
node. This | | // ITT note: &(op->status) tag is used to cover accesses to this op
node. This | |
| // thread has created the operation, and now releases it so that th
e handler | | // thread has created the operation, and now releases it so that th
e handler | |
| // thread may handle the associated operation w/o triggering a race
condition; | | // thread may handle the associated operation w/o triggering a race
condition; | |
| // thus this tag will be acquired just before the operation is hand
led in the | | // thus this tag will be acquired just before the operation is hand
led in the | |
| // handle_operations functor. | | // handle_operations functor. | |
| call_itt_notify(releasing, &(op->status)); | | call_itt_notify(releasing, &(op->status)); | |
|
| // insert the operation in the queue | | // insert the operation in the queue. | |
| do { | | do { | |
| // ITT may flag the following line as a race; it is a false pos
itive: | | // ITT may flag the following line as a race; it is a false pos
itive: | |
| // This is an atomic read; we don't provide itt_hide_load_word
for atomics | | // This is an atomic read; we don't provide itt_hide_load_word
for atomics | |
| op->next = res = pending_operations; // NOT A RACE | | op->next = res = pending_operations; // NOT A RACE | |
| } while (pending_operations.compare_and_swap(op, res) != res); | | } while (pending_operations.compare_and_swap(op, res) != res); | |
|
| if (!res) { // first in the list; handle the operations | | if (!res) { // first in the list; handle the operations. | |
| // ITT note: &pending_operations tag covers access to the handl
er_busy flag, | | // ITT note: &pending_operations tag covers access to the handl
er_busy flag, | |
| // which this waiting handler thread will try to set before ent
ering | | // which this waiting handler thread will try to set before ent
ering | |
| // handle_operations. | | // handle_operations. | |
| call_itt_notify(acquired, &pending_operations); | | call_itt_notify(acquired, &pending_operations); | |
|
| start_handle_operations(); | | start_handle_operations(handle_operations); | |
| __TBB_ASSERT(op->status, NULL); | | // The operation with 'short' life time can already be destroye | |
| | | d. | |
| | | if (long_life_time) | |
| | | __TBB_ASSERT(op->status, NULL); | |
| } | | } | |
|
| else { // not first; wait for op to be ready | | // not first; wait for op to be ready. | |
| | | else if (!status) { // operation is blocking here. | |
| | | __TBB_ASSERT(long_life_time, "The blocking operation cannot hav | |
| | | e 'short' life time. Since it can already be destroyed."); | |
| call_itt_notify(prepare, &(op->status)); | | call_itt_notify(prepare, &(op->status)); | |
| spin_wait_while_eq(op->status, uintptr_t(0)); | | spin_wait_while_eq(op->status, uintptr_t(0)); | |
| itt_load_word_with_acquire(op->status); | | itt_load_word_with_acquire(op->status); | |
| } | | } | |
| } | | } | |
| | | | |
| private: | | private: | |
| //! An atomically updated list (aka mailbox) of pending operations | | //! An atomically updated list (aka mailbox) of pending operations | |
| atomic<operation_type *> pending_operations; | | atomic<operation_type *> pending_operations; | |
| //! Controls thread access to handle_operations | | //! Controls thread access to handle_operations | |
| uintptr_t handler_busy; | | uintptr_t handler_busy; | |
|
| handler_type handle_operations; | | | |
| | | | |
| //! Trigger the handling of operations when the handler is free | | //! Trigger the handling of operations when the handler is free | |
|
| void start_handle_operations() { | | template < typename handler_type > | |
| | | void start_handle_operations( handler_type &handle_operations ) { | |
| operation_type *op_list; | | operation_type *op_list; | |
| | | | |
| // ITT note: &handler_busy tag covers access to pending_operations
as it is passed | | // ITT note: &handler_busy tag covers access to pending_operations
as it is passed | |
| // between active and waiting handlers. Below, the waiting handler
waits until | | // between active and waiting handlers. Below, the waiting handler
waits until | |
| // the active handler releases, and the waiting handler acquires &h
andler_busy as | | // the active handler releases, and the waiting handler acquires &h
andler_busy as | |
| // it becomes the active_handler. The release point is at the end o
f this | | // it becomes the active_handler. The release point is at the end o
f this | |
| // function, when all operations in pending_operations have been ha
ndled by the | | // function, when all operations in pending_operations have been ha
ndled by the | |
| // owner of this aggregator. | | // owner of this aggregator. | |
| call_itt_notify(prepare, &handler_busy); | | call_itt_notify(prepare, &handler_busy); | |
| // get the handler_busy: | | // get the handler_busy: | |
| | | | |
| skipping to change at line 140 | | skipping to change at line 151 | |
| op_list = pending_operations.fetch_and_store(NULL); | | op_list = pending_operations.fetch_and_store(NULL); | |
| | | | |
| // handle all the operations | | // handle all the operations | |
| handle_operations(op_list); | | handle_operations(op_list); | |
| | | | |
| // release the handler | | // release the handler | |
| itt_store_word_with_release(handler_busy, uintptr_t(0)); | | itt_store_word_with_release(handler_busy, uintptr_t(0)); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| | | template < typename handler_type, typename operation_type > | |
| | | class aggregator : public aggregator_generic<operation_type> { | |
| | | handler_type handle_operations; | |
| | | public: | |
| | | aggregator() {} | |
| | | explicit aggregator(handler_type h) : handle_operations(h) {} | |
| | | | |
| | | void initialize_handler(handler_type h) { handle_operations = h; } | |
| | | | |
| | | void execute(operation_type *op) { | |
| | | aggregator_generic<operation_type>::execute(op, handle_operations); | |
| | | } | |
| | | }; | |
| | | | |
| // the most-compatible friend declaration (vs, gcc, icc) is | | // the most-compatible friend declaration (vs, gcc, icc) is | |
| // template<class U, class V> friend class aggregating_functor; | | // template<class U, class V> friend class aggregating_functor; | |
| template<typename aggregating_class, typename operation_list> | | template<typename aggregating_class, typename operation_list> | |
| class aggregating_functor { | | class aggregating_functor { | |
| aggregating_class *fi; | | aggregating_class *fi; | |
| public: | | public: | |
| aggregating_functor() {} | | aggregating_functor() {} | |
| aggregating_functor(aggregating_class *fi_) : fi(fi_) {} | | aggregating_functor(aggregating_class *fi_) : fi(fi_) {} | |
| void operator()(operation_list* op_list) { fi->handle_operations(op_lis
t); } | | void operator()(operation_list* op_list) { fi->handle_operations(op_lis
t); } | |
| }; | | }; | |
| | | | |
| } // namespace internal | | } // namespace internal | |
| } // namespace interface6 | | } // namespace interface6 | |
| | | | |
| namespace internal { | | namespace internal { | |
| using interface6::internal::aggregated_operation; | | using interface6::internal::aggregated_operation; | |
|
| | | using interface6::internal::aggregator_generic; | |
| using interface6::internal::aggregator; | | using interface6::internal::aggregator; | |
| using interface6::internal::aggregating_functor; | | using interface6::internal::aggregating_functor; | |
| } // namespace internal | | } // namespace internal | |
| | | | |
| } // namespace tbb | | } // namespace tbb | |
| | | | |
| #endif // __TBB__aggregator_impl_H | | #endif // __TBB__aggregator_impl_H | |
| | | | |
End of changes. 13 change blocks. |
| 19 lines changed or deleted | | 50 lines changed or added | |
|
| tbb_config.h | | tbb_config.h | |
| | | | |
| skipping to change at line 210 | | skipping to change at line 210 | |
| | | | |
| #if __INTEL_COMPILER >= 1200 | | #if __INTEL_COMPILER >= 1200 | |
| /** built-in C++11 style atomics available in ICC since 12.0 **/ | | /** built-in C++11 style atomics available in ICC since 12.0 **/ | |
| #define __TBB_ICC_BUILTIN_ATOMICS_PRESENT 1 | | #define __TBB_ICC_BUILTIN_ATOMICS_PRESENT 1 | |
| #endif | | #endif | |
| | | | |
| #if __MIC__ || __MIC2__ | | #if __MIC__ || __MIC2__ | |
| #define __TBB_DEFINE_MIC 1 | | #define __TBB_DEFINE_MIC 1 | |
| #endif | | #endif | |
| | | | |
|
| #define __TBB_TSX_INTRINSICS_PRESENT ( (__TBB_GCC_VERSION>=40800) || (_MSC_
VER>=1700) || (__INTEL_COMPILER>=1300) ) && !__TBB_DEFINE_MIC | | #define __TBB_TSX_INTRINSICS_PRESENT ( (__TBB_GCC_VERSION>=40800) || (_MSC_
VER>=1700) || (__INTEL_COMPILER>=1300) ) && !__TBB_DEFINE_MIC && !__ANDROID
__ | |
| | | | |
| /** User controlled TBB features & modes **/ | | /** User controlled TBB features & modes **/ | |
| | | | |
| #ifndef TBB_USE_DEBUG | | #ifndef TBB_USE_DEBUG | |
| #ifdef TBB_DO_ASSERT | | #ifdef TBB_DO_ASSERT | |
| #define TBB_USE_DEBUG TBB_DO_ASSERT | | #define TBB_USE_DEBUG TBB_DO_ASSERT | |
| #else | | #else | |
| #ifdef _DEBUG | | #ifdef _DEBUG | |
| #define TBB_USE_DEBUG _DEBUG | | #define TBB_USE_DEBUG _DEBUG | |
| #else | | #else | |
| | | | |
| skipping to change at line 267 | | skipping to change at line 267 | |
| #if __TBB_DEFINE_MIC | | #if __TBB_DEFINE_MIC | |
| #define TBB_USE_EXCEPTIONS 0 | | #define TBB_USE_EXCEPTIONS 0 | |
| #else | | #else | |
| #define TBB_USE_EXCEPTIONS 1 | | #define TBB_USE_EXCEPTIONS 1 | |
| #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++11 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 macros for each file? | | //TODO: consider introducing separate macros for each file? | |
| //prevent injection of corresponding tbb names into std:: namespace
if native headers are present | | //prevent injection of corresponding tbb names into std:: namespace
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 | |
|
| | | #elif _MSC_VER>=1700 | |
| | | #define TBB_IMPLEMENT_CPP0X 0 | |
| | | #elif __STDCPP_THREADS__ | |
| | | #define TBB_IMPLEMENT_CPP0X 0 | |
| #else | | #else | |
| #define TBB_IMPLEMENT_CPP0X 1 | | #define TBB_IMPLEMENT_CPP0X 1 | |
| #endif | | #endif | |
| #endif /* TBB_IMPLEMENT_CPP0X */ | | #endif /* TBB_IMPLEMENT_CPP0X */ | |
| | | | |
| /* TBB_USE_CAPTURED_EXCEPTION should be explicitly set to either 0 or 1, as
it is used as C++ const */ | | /* TBB_USE_CAPTURED_EXCEPTION should be explicitly set to either 0 or 1, as
it is used as C++ const */ | |
| #ifndef TBB_USE_CAPTURED_EXCEPTION | | #ifndef TBB_USE_CAPTURED_EXCEPTION | |
| /** IA-64 architecture pre-built TBB binaries do not support exception_
ptr. **/ | | /** IA-64 architecture pre-built TBB binaries do not support exception_
ptr. **/ | |
| #if __TBB_EXCEPTION_PTR_PRESENT && !defined(__ia64__) | | #if __TBB_EXCEPTION_PTR_PRESENT && !defined(__ia64__) | |
| #define TBB_USE_CAPTURED_EXCEPTION 0 | | #define TBB_USE_CAPTURED_EXCEPTION 0 | |
| | | | |
End of changes. 3 change blocks. |
| 2 lines changed or deleted | | 6 lines changed or added | |
|
| tbb_machine.h | | tbb_machine.h | |
| | | | |
| skipping to change at line 180 | | skipping to change at line 180 | |
| template<> struct atomic_selector<8> { | | template<> struct atomic_selector<8> { | |
| typedef int64_t word; | | typedef int64_t word; | |
| inline static word fetch_store ( volatile void* location, word value ); | | inline static word fetch_store ( volatile void* location, word value ); | |
| }; | | }; | |
| | | | |
| }} //< namespaces internal @endcond, tbb | | }} //< namespaces internal @endcond, tbb | |
| | | | |
| #define __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(M)
\ | | #define __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(M)
\ | |
| inline void __TBB_machine_generic_store8##M(volatile void *ptr, int64_t
value) { \ | | inline void __TBB_machine_generic_store8##M(volatile void *ptr, int64_t
value) { \ | |
| for(;;) {
\ | | for(;;) {
\ | |
|
| int64_t result = *(int64_t *)ptr;
\ | | int64_t result = *(volatile int64_t *)ptr;
\ | |
| if( __TBB_machine_cmpswp8##M(ptr,value,result)==result ) break;
\ | | if( __TBB_machine_cmpswp8##M(ptr,value,result)==result ) break;
\ | |
| }
\ | | }
\ | |
| }
\ | | }
\ | |
| | | | |
| #define __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(M)
\ | | #define __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(M)
\ | |
| inline int64_t __TBB_machine_generic_load8##M(const volatile void *ptr)
{ \ | | inline int64_t __TBB_machine_generic_load8##M(const volatile void *ptr)
{ \ | |
| /* Comparand and new value may be anything, they only must be equal
, and */ \ | | /* Comparand and new value may be anything, they only must be equal
, and */ \ | |
| /* the value should have a low probability to be actually found in
'location'.*/ \ | | /* the value should have a low probability to be actually found in
'location'.*/ \ | |
| const int64_t anyvalue = 2305843009213693951LL;
\ | | const int64_t anyvalue = 2305843009213693951LL;
\ | |
| return __TBB_machine_cmpswp8##M(const_cast<volatile void *>(ptr),an
yvalue,anyvalue); \ | | return __TBB_machine_cmpswp8##M(const_cast<volatile void *>(ptr),an
yvalue,anyvalue); \ | |
| | | | |
| skipping to change at line 481 | | skipping to change at line 481 | |
| else continue; // CAS failed bu
t the bits of interest were not changed | | else continue; // CAS failed bu
t the bits of interest were not changed | |
| } | | } | |
| } | | } | |
| #endif // __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED | | #endif // __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED | |
| ///////////////////////////////////////////////////////////////////////////
///// | | ///////////////////////////////////////////////////////////////////////////
///// | |
| | | | |
| template<size_t S, typename T> | | template<size_t S, typename T> | |
| inline T __TBB_CompareAndSwapGeneric (volatile void *ptr, T value, T compar
and ); | | inline T __TBB_CompareAndSwapGeneric (volatile void *ptr, T value, T compar
and ); | |
| | | | |
| template<> | | template<> | |
|
| inline uint8_t __TBB_CompareAndSwapGeneric <1,uint8_t> (volatile void *ptr,
uint8_t value, uint8_t comparand ) { | | inline int8_t __TBB_CompareAndSwapGeneric <1,int8_t> (volatile void *ptr, i
nt8_t value, int8_t comparand ) { | |
| #if __TBB_USE_GENERIC_PART_WORD_CAS | | #if __TBB_USE_GENERIC_PART_WORD_CAS | |
|
| return __TBB_MaskedCompareAndSwap<uint8_t>((volatile uint8_t *)ptr,valu
e,comparand); | | return __TBB_MaskedCompareAndSwap<int8_t>((volatile int8_t *)ptr,value,
comparand); | |
| #else | | #else | |
| return __TBB_machine_cmpswp1(ptr,value,comparand); | | return __TBB_machine_cmpswp1(ptr,value,comparand); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| template<> | | template<> | |
|
| inline uint16_t __TBB_CompareAndSwapGeneric <2,uint16_t> (volatile void *pt
r, uint16_t value, uint16_t comparand ) { | | inline int16_t __TBB_CompareAndSwapGeneric <2,int16_t> (volatile void *ptr,
int16_t value, int16_t comparand ) { | |
| #if __TBB_USE_GENERIC_PART_WORD_CAS | | #if __TBB_USE_GENERIC_PART_WORD_CAS | |
|
| return __TBB_MaskedCompareAndSwap<uint16_t>((volatile uint16_t *)ptr,va
lue,comparand); | | return __TBB_MaskedCompareAndSwap<int16_t>((volatile int16_t *)ptr,valu
e,comparand); | |
| #else | | #else | |
| return __TBB_machine_cmpswp2(ptr,value,comparand); | | return __TBB_machine_cmpswp2(ptr,value,comparand); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| template<> | | template<> | |
|
| inline uint32_t __TBB_CompareAndSwapGeneric <4,uint32_t> (volatile void *pt
r, uint32_t value, uint32_t comparand ) { | | inline int32_t __TBB_CompareAndSwapGeneric <4,int32_t> (volatile void *ptr,
int32_t value, int32_t comparand ) { | |
| // Cast shuts up /Wp64 warning | | // Cast shuts up /Wp64 warning | |
|
| return (uint32_t)__TBB_machine_cmpswp4(ptr,value,comparand); | | return (int32_t)__TBB_machine_cmpswp4(ptr,value,comparand); | |
| } | | } | |
| | | | |
| #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 int64_t __TBB_CompareAndSwapGeneric <8,int64_t> (volatile void *ptr,
int64_t value, int64_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) { | |
| T result; | | T result; | |
| for( atomic_backoff b;;b.pause() ) { | | 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. | |
| | | | |
| skipping to change at line 536 | | skipping to change at line 536 | |
| for( atomic_backoff b;;b.pause() ) { | | 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; | |
| } | | } | |
| 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, | | #define __TBB_machine_cmpswp1 tbb::internal::__TBB_CompareAndSwapGeneric<1, | |
| uint8_t> | | int8_t> | |
| #define __TBB_machine_cmpswp2 tbb::internal::__TBB_CompareAndSwapGeneric<2, | | #define __TBB_machine_cmpswp2 tbb::internal::__TBB_CompareAndSwapGeneric<2, | |
| uint16_t> | | int16_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 | |
|
| #define __TBB_machine_fetchadd1 tbb::internal::__TBB_FetchAndAddGeneric<1,u | | #define __TBB_machine_fetchadd1 tbb::internal::__TBB_FetchAndAddGeneric<1,i | |
| int8_t> | | nt8_t> | |
| #define __TBB_machine_fetchadd2 tbb::internal::__TBB_FetchAndAddGeneric<2,u | | #define __TBB_machine_fetchadd2 tbb::internal::__TBB_FetchAndAddGeneric<2,i | |
| int16_t> | | nt16_t> | |
| #endif | | #endif | |
| | | | |
| #if __TBB_USE_GENERIC_FETCH_ADD | | #if __TBB_USE_GENERIC_FETCH_ADD | |
|
| #define __TBB_machine_fetchadd4 tbb::internal::__TBB_FetchAndAddGeneric<4,u
int32_t> | | #define __TBB_machine_fetchadd4 tbb::internal::__TBB_FetchAndAddGeneric<4,i
nt32_t> | |
| #endif | | #endif | |
| | | | |
| #if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_DWORD_FETCH_ADD | | #if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_DWORD_FETCH_ADD | |
|
| #define __TBB_machine_fetchadd8 tbb::internal::__TBB_FetchAndAddGeneric<8,u
int64_t> | | #define __TBB_machine_fetchadd8 tbb::internal::__TBB_FetchAndAddGeneric<8,i
nt64_t> | |
| #endif | | #endif | |
| | | | |
| #if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_PART_WORD_FETCH_STOR
E | | #if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_PART_WORD_FETCH_STOR
E | |
|
| #define __TBB_machine_fetchstore1 tbb::internal::__TBB_FetchAndStoreGeneric | | #define __TBB_machine_fetchstore1 tbb::internal::__TBB_FetchAndStoreGeneric | |
| <1,uint8_t> | | <1,int8_t> | |
| #define __TBB_machine_fetchstore2 tbb::internal::__TBB_FetchAndStoreGeneric | | #define __TBB_machine_fetchstore2 tbb::internal::__TBB_FetchAndStoreGeneric | |
| <2,uint16_t> | | <2,int16_t> | |
| #endif | | #endif | |
| | | | |
| #if __TBB_USE_GENERIC_FETCH_STORE | | #if __TBB_USE_GENERIC_FETCH_STORE | |
|
| #define __TBB_machine_fetchstore4 tbb::internal::__TBB_FetchAndStoreGeneric
<4,uint32_t> | | #define __TBB_machine_fetchstore4 tbb::internal::__TBB_FetchAndStoreGeneric
<4,int32_t> | |
| #endif | | #endif | |
| | | | |
| #if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_DWORD_FETCH_STORE | | #if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_DWORD_FETCH_STORE | |
|
| #define __TBB_machine_fetchstore8 tbb::internal::__TBB_FetchAndStoreGeneric
<8,uint64_t> | | #define __TBB_machine_fetchstore8 tbb::internal::__TBB_FetchAndStoreGeneric
<8,int64_t> | |
| #endif | | #endif | |
| | | | |
| #if __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE | | #if __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE | |
| #define __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(S)
\ | | #define __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(S)
\ | |
| atomic_selector<S>::word atomic_selector<S>::fetch_store ( volatile voi
d* location, word value ) { \ | | atomic_selector<S>::word atomic_selector<S>::fetch_store ( volatile voi
d* location, word value ) { \ | |
| return __TBB_machine_fetchstore##S( location, value );
\ | | return __TBB_machine_fetchstore##S( location, value );
\ | |
| } | | } | |
| | | | |
| __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(1) | | __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(1) | |
| __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(2) | | __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(2) | |
| | | | |
End of changes. 15 change blocks. |
| 24 lines changed or deleted | | 24 lines changed or added | |
|