21 #ifndef __TBB_machine_H 22 #define __TBB_machine_H 117 #include "tbb_stddef.h" 128 template <
typename T, std::
size_t S>
129 struct machine_load_store;
131 template <
typename T, std::
size_t S>
132 struct machine_load_store_relaxed;
134 template <
typename T, std::
size_t S>
135 struct machine_load_store_seq_cst;
140 template<
size_t S>
struct atomic_selector;
142 template<>
struct atomic_selector<1> {
144 inline static word fetch_store (
volatile void* location, word value );
147 template<>
struct atomic_selector<2> {
148 typedef int16_t word;
149 inline static word fetch_store (
volatile void* location, word value );
152 template<>
struct atomic_selector<4> {
153 #if _MSC_VER && !_WIN64 155 typedef intptr_t word;
157 typedef int32_t word;
159 inline static word fetch_store (
volatile void* location, word value );
162 template<>
struct atomic_selector<8> {
163 typedef int64_t word;
164 inline static word fetch_store (
volatile void* location, word value );
169 #define __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(M) \ 170 inline void __TBB_machine_generic_store8##M(volatile void *ptr, int64_t value) { \ 172 int64_t result = *(volatile int64_t *)ptr; \ 173 if( __TBB_machine_cmpswp8##M(ptr,value,result)==result ) break; \ 177 #define __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(M) \ 178 inline int64_t __TBB_machine_generic_load8##M(const volatile void *ptr) { \ 181 const int64_t anyvalue = 2305843009213693951LL; \ 182 return __TBB_machine_cmpswp8##M(const_cast<volatile void *>(ptr),anyvalue,anyvalue); \ 186 #define __TBB_ENDIAN_UNSUPPORTED -1 187 #define __TBB_ENDIAN_LITTLE 0 188 #define __TBB_ENDIAN_BIG 1 189 #define __TBB_ENDIAN_DETECT 2 194 #pragma managed(push, off) 197 #if __MINGW64__ || __MINGW32__ 198 extern "C" __declspec(dllimport) int __stdcall SwitchToThread(
void );
199 #define __TBB_Yield() SwitchToThread() 200 #if (TBB_USE_GCC_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT) 201 #include "machine/gcc_generic.h" 203 #include "machine/linux_intel64.h" 205 #include "machine/linux_ia32.h" 207 #elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) 208 #include "machine/icc_generic.h" 209 #elif defined(_M_IX86) && !defined(__TBB_WIN32_USE_CL_BUILTINS) 210 #include "machine/windows_ia32.h" 211 #elif defined(_M_X64) 212 #include "machine/windows_intel64.h" 214 #include "machine/xbox360_ppc.h" 215 #elif defined(_M_ARM) || defined(__TBB_WIN32_USE_CL_BUILTINS) 216 #include "machine/msvc_armv7.h" 223 #elif __TBB_DEFINE_MIC 225 #include "machine/mic_common.h" 226 #if (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) 227 #include "machine/icc_generic.h" 229 #include "machine/linux_intel64.h" 232 #elif __linux__ || __FreeBSD__ || __NetBSD__ 234 #if (TBB_USE_GCC_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT) 235 #include "machine/gcc_generic.h" 236 #elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) 237 #include "machine/icc_generic.h" 239 #include "machine/linux_ia32.h" 241 #include "machine/linux_intel64.h" 243 #include "machine/linux_ia64.h" 245 #include "machine/mac_ppc.h" 247 #include "machine/gcc_armv7.h" 248 #elif __TBB_GCC_BUILTIN_ATOMICS_PRESENT 249 #include "machine/gcc_generic.h" 251 #include "machine/linux_common.h" 255 #if (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) 256 #include "machine/icc_generic.h" 258 #include "machine/linux_ia32.h" 260 #include "machine/linux_intel64.h" 262 #include "machine/mac_ppc.h" 264 #include "machine/macos_common.h" 268 #include "machine/ibm_aix51.h" 270 #elif __sun || __SUNPRO_CC 273 #define __volatile__ volatile 275 #if __i386 || __i386__ 276 #include "machine/linux_ia32.h" 278 #include "machine/linux_intel64.h" 280 #include "machine/sunos_sparc.h" 284 #define __TBB_Yield() sched_yield() 288 #ifndef __TBB_64BIT_ATOMICS 289 #define __TBB_64BIT_ATOMICS 1 295 #if __TBB_USE_FENCED_ATOMICS 296 #define __TBB_machine_cmpswp1 __TBB_machine_cmpswp1full_fence 297 #define __TBB_machine_cmpswp2 __TBB_machine_cmpswp2full_fence 298 #define __TBB_machine_cmpswp4 __TBB_machine_cmpswp4full_fence 299 #define __TBB_machine_cmpswp8 __TBB_machine_cmpswp8full_fence 301 #if __TBB_WORDSIZE==8 302 #define __TBB_machine_fetchadd8 __TBB_machine_fetchadd8full_fence 303 #define __TBB_machine_fetchstore8 __TBB_machine_fetchstore8full_fence 304 #define __TBB_FetchAndAddWrelease(P,V) __TBB_machine_fetchadd8release(P,V) 305 #define __TBB_FetchAndIncrementWacquire(P) __TBB_machine_fetchadd8acquire(P,1) 306 #define __TBB_FetchAndDecrementWrelease(P) __TBB_machine_fetchadd8release(P,(-1)) 308 #define __TBB_machine_fetchadd4 __TBB_machine_fetchadd4full_fence 309 #define __TBB_machine_fetchstore4 __TBB_machine_fetchstore4full_fence 310 #define __TBB_FetchAndAddWrelease(P,V) __TBB_machine_fetchadd4release(P,V) 311 #define __TBB_FetchAndIncrementWacquire(P) __TBB_machine_fetchadd4acquire(P,1) 312 #define __TBB_FetchAndDecrementWrelease(P) __TBB_machine_fetchadd4release(P,(-1)) 315 #define __TBB_FetchAndAddWrelease(P,V) __TBB_FetchAndAddW(P,V) 316 #define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1) 317 #define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,(-1)) 320 #if __TBB_WORDSIZE==4 321 #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp4(P,V,C) 322 #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd4(P,V) 323 #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore4(P,V) 324 #elif __TBB_WORDSIZE==8 325 #if __TBB_USE_GENERIC_DWORD_LOAD_STORE || __TBB_USE_GENERIC_DWORD_FETCH_ADD || __TBB_USE_GENERIC_DWORD_FETCH_STORE 326 #error These macros should only be used on 32-bit platforms. 329 #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp8(P,V,C) 330 #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd8(P,V) 331 #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore8(P,V) 333 #error Unsupported machine word size. 337 inline void __TBB_Pause(int32_t) {
345 inline void atomic_fence () { __TBB_full_memory_fence(); }
351 class atomic_backoff : no_copy {
355 static const int32_t LOOPS_BEFORE_YIELD = 16;
361 atomic_backoff() : count(1) {}
363 atomic_backoff(
bool ) : count(1) { pause(); }
367 if( count<=LOOPS_BEFORE_YIELD ) {
378 bool bounded_pause() {
380 if( count<LOOPS_BEFORE_YIELD ) {
396 template<
typename T,
typename U>
397 void spin_wait_while_eq(
const volatile T& location, U value ) {
398 atomic_backoff backoff;
399 while( location==value ) backoff.pause();
404 template<
typename T,
typename U>
405 void spin_wait_until_eq(
const volatile T& location,
const U value ) {
406 atomic_backoff backoff;
407 while( location!=value ) backoff.pause();
410 template <
typename predicate_type>
411 void spin_wait_while(predicate_type condition){
412 atomic_backoff backoff;
413 while( condition() ) backoff.pause();
419 #ifndef __TBB_ENDIANNESS 420 #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT 423 #if __TBB_USE_GENERIC_PART_WORD_CAS && __TBB_ENDIANNESS==__TBB_ENDIAN_UNSUPPORTED 424 #error Generic implementation of part-word CAS may not be used with __TBB_ENDIAN_UNSUPPORTED 427 #if __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED 438 inline T __TBB_MaskedCompareAndSwap (
volatile T *
const ptr,
const T value,
const T comparand ) {
439 struct endianness{
static bool is_big_endian(){
440 #if __TBB_ENDIANNESS==__TBB_ENDIAN_DETECT 441 const uint32_t probe = 0x03020100;
442 return (((
const char*)(&probe))[0]==0x03);
443 #elif __TBB_ENDIANNESS==__TBB_ENDIAN_BIG || __TBB_ENDIANNESS==__TBB_ENDIAN_LITTLE 444 return __TBB_ENDIANNESS==__TBB_ENDIAN_BIG;
446 #error Unexpected value of __TBB_ENDIANNESS 450 const uint32_t byte_offset = (uint32_t) ((uintptr_t)ptr & 0x3);
451 volatile uint32_t *
const aligned_ptr = (uint32_t*)((uintptr_t)ptr - byte_offset );
454 const uint32_t bits_to_shift = 8*(endianness::is_big_endian() ? (4 -
sizeof(T) - (byte_offset)) : byte_offset);
455 const uint32_t mask = (((uint32_t)1<<(
sizeof(T)*8)) - 1 )<<bits_to_shift;
457 const uint32_t shifted_comparand = ((uint32_t)comparand << bits_to_shift)&mask;
458 const uint32_t shifted_value = ((uint32_t)value << bits_to_shift)&mask;
460 for( atomic_backoff b;;b.pause() ) {
461 const uint32_t surroundings = *aligned_ptr & ~mask ;
462 const uint32_t big_comparand = surroundings | shifted_comparand ;
463 const uint32_t big_value = surroundings | shifted_value ;
466 const uint32_t big_result = (uint32_t)__TBB_machine_cmpswp4( aligned_ptr, big_value, big_comparand );
467 if( big_result == big_comparand
468 || ((big_result ^ big_comparand) & mask) != 0)
470 return T((big_result & mask) >> bits_to_shift);
475 #endif // __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED 478 template<
size_t S,
typename T>
479 inline T __TBB_CompareAndSwapGeneric (
volatile void *ptr, T value, T comparand );
482 inline int8_t __TBB_CompareAndSwapGeneric <1,int8_t> (
volatile void *ptr, int8_t value, int8_t comparand ) {
483 #if __TBB_USE_GENERIC_PART_WORD_CAS 484 return __TBB_MaskedCompareAndSwap<int8_t>((
volatile int8_t *)ptr,value,comparand);
486 return __TBB_machine_cmpswp1(ptr,value,comparand);
491 inline int16_t __TBB_CompareAndSwapGeneric <2,int16_t> (
volatile void *ptr, int16_t value, int16_t comparand ) {
492 #if __TBB_USE_GENERIC_PART_WORD_CAS 493 return __TBB_MaskedCompareAndSwap<int16_t>((
volatile int16_t *)ptr,value,comparand);
495 return __TBB_machine_cmpswp2(ptr,value,comparand);
500 inline int32_t __TBB_CompareAndSwapGeneric <4,int32_t> (
volatile void *ptr, int32_t value, int32_t comparand ) {
502 return (int32_t)__TBB_machine_cmpswp4(ptr,value,comparand);
505 #if __TBB_64BIT_ATOMICS 507 inline int64_t __TBB_CompareAndSwapGeneric <8,int64_t> (
volatile void *ptr, int64_t value, int64_t comparand ) {
508 return __TBB_machine_cmpswp8(ptr,value,comparand);
512 template<
size_t S,
typename T>
513 inline T __TBB_FetchAndAddGeneric (
volatile void *ptr, T addend) {
515 for( atomic_backoff b;;b.pause() ) {
516 result = *
reinterpret_cast<volatile T *
>(ptr);
518 if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, result+addend, result )==result )
524 template<
size_t S,
typename T>
525 inline T __TBB_FetchAndStoreGeneric (
volatile void *ptr, T value) {
527 for( atomic_backoff b;;b.pause() ) {
528 result = *
reinterpret_cast<volatile T *
>(ptr);
530 if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, value, result )==result )
536 #if __TBB_USE_GENERIC_PART_WORD_CAS 537 #define __TBB_machine_cmpswp1 tbb::internal::__TBB_CompareAndSwapGeneric<1,int8_t> 538 #define __TBB_machine_cmpswp2 tbb::internal::__TBB_CompareAndSwapGeneric<2,int16_t> 541 #if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 542 #define __TBB_machine_fetchadd1 tbb::internal::__TBB_FetchAndAddGeneric<1,int8_t> 543 #define __TBB_machine_fetchadd2 tbb::internal::__TBB_FetchAndAddGeneric<2,int16_t> 546 #if __TBB_USE_GENERIC_FETCH_ADD 547 #define __TBB_machine_fetchadd4 tbb::internal::__TBB_FetchAndAddGeneric<4,int32_t> 550 #if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_DWORD_FETCH_ADD 551 #define __TBB_machine_fetchadd8 tbb::internal::__TBB_FetchAndAddGeneric<8,int64_t> 554 #if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_PART_WORD_FETCH_STORE 555 #define __TBB_machine_fetchstore1 tbb::internal::__TBB_FetchAndStoreGeneric<1,int8_t> 556 #define __TBB_machine_fetchstore2 tbb::internal::__TBB_FetchAndStoreGeneric<2,int16_t> 559 #if __TBB_USE_GENERIC_FETCH_STORE 560 #define __TBB_machine_fetchstore4 tbb::internal::__TBB_FetchAndStoreGeneric<4,int32_t> 563 #if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_DWORD_FETCH_STORE 564 #define __TBB_machine_fetchstore8 tbb::internal::__TBB_FetchAndStoreGeneric<8,int64_t> 567 #if __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 568 #define __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(S) \ 569 atomic_selector<S>::word atomic_selector<S>::fetch_store ( volatile void* location, word value ) { \ 570 return __TBB_machine_fetchstore##S( location, value ); \ 573 __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(1)
574 __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(2)
575 __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(4)
576 __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(8)
578 #undef __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE 581 #if __TBB_USE_GENERIC_DWORD_LOAD_STORE 583 #if ! __TBB_USE_FENCED_ATOMICS 586 #define __TBB_machine_cmpswp8full_fence __TBB_machine_cmpswp8 588 __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(
full_fence)
589 __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(
full_fence)
591 #if ! __TBB_USE_FENCED_ATOMICS 592 #undef __TBB_machine_cmpswp8full_fence 595 #define __TBB_machine_store8 tbb::internal::__TBB_machine_generic_store8full_fence 596 #define __TBB_machine_load8 tbb::internal::__TBB_machine_generic_load8full_fence 599 #if __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 610 template <
typename T,
size_t S>
611 struct machine_load_store {
612 static T load_with_acquire (
const volatile T& location ) {
613 T to_return = location;
614 __TBB_acquire_consistency_helper();
617 static void store_with_release (
volatile T &location, T value ) {
618 __TBB_release_consistency_helper();
624 #if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS 625 template <
typename T>
626 struct machine_load_store<T,8> {
627 static T load_with_acquire (
const volatile T& location ) {
628 return (T)__TBB_machine_load8( (
const volatile void*)&location );
630 static void store_with_release (
volatile T& location, T value ) {
631 __TBB_machine_store8( (
volatile void*)&location, (int64_t)value );
637 #if __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 638 template <
typename T,
size_t S>
639 struct machine_load_store_seq_cst {
640 static T load (
const volatile T& location ) {
641 __TBB_full_memory_fence();
642 return machine_load_store<T,S>::load_with_acquire( location );
644 #if __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 645 static void store (
volatile T &location, T value ) {
646 atomic_selector<S>::fetch_store( (
volatile void*)&location, (
typename atomic_selector<S>::word)value );
649 static void store (
volatile T &location, T value ) {
650 machine_load_store<T,S>::store_with_release( location, value );
651 __TBB_full_memory_fence();
656 #if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS 659 template <
typename T>
660 struct machine_load_store_seq_cst<T,8> {
661 static T load (
const volatile T& location ) {
664 const int64_t anyvalue = 2305843009213693951LL;
665 return __TBB_machine_cmpswp8( (
volatile void*)const_cast<volatile T*>(&location), anyvalue, anyvalue );
667 static void store (
volatile T &location, T value ) {
668 int64_t result = (
volatile int64_t&)location;
669 while ( __TBB_machine_cmpswp8((
volatile void*)&location, (int64_t)value, result) != result )
670 result = (
volatile int64_t&)location;
676 #if __TBB_USE_GENERIC_RELAXED_LOAD_STORE 681 template <
typename T,
size_t S>
682 struct machine_load_store_relaxed {
683 static inline T load (
const volatile T& location ) {
686 static inline void store (
volatile T& location, T value ) {
691 #if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS 692 template <
typename T>
693 struct machine_load_store_relaxed<T,8> {
694 static inline T load (
const volatile T& location ) {
695 return (T)__TBB_machine_load8( (
const volatile void*)&location );
697 static inline void store (
volatile T& location, T value ) {
698 __TBB_machine_store8( (
volatile void*)&location, (int64_t)value );
704 #undef __TBB_WORDSIZE //this macro is forbidden to use outside of atomic machinery 707 inline T __TBB_load_with_acquire(
const volatile T &location) {
708 return machine_load_store<T,sizeof(T)>::load_with_acquire( location );
710 template<
typename T,
typename V>
711 inline void __TBB_store_with_release(
volatile T& location, V value) {
712 machine_load_store<T,sizeof(T)>::store_with_release( location, T(value) );
715 inline void __TBB_store_with_release(
volatile size_t& location,
size_t value) {
716 machine_load_store<size_t,sizeof(size_t)>::store_with_release( location, value );
720 inline T __TBB_load_full_fence(
const volatile T &location) {
721 return machine_load_store_seq_cst<T,sizeof(T)>::load( location );
723 template<
typename T,
typename V>
724 inline void __TBB_store_full_fence(
volatile T& location, V value) {
725 machine_load_store_seq_cst<T,sizeof(T)>::store( location, T(value) );
728 inline void __TBB_store_full_fence(
volatile size_t& location,
size_t value) {
729 machine_load_store_seq_cst<size_t,sizeof(size_t)>::store( location, value );
733 inline T __TBB_load_relaxed (
const volatile T& location) {
734 return machine_load_store_relaxed<T,sizeof(T)>::load(
const_cast<T&
>(location) );
736 template<
typename T,
typename V>
737 inline void __TBB_store_relaxed (
volatile T& location, V value ) {
738 machine_load_store_relaxed<T,sizeof(T)>::store(
const_cast<T&
>(location), T(value) );
741 inline void __TBB_store_relaxed (
volatile size_t& location,
size_t value ) {
742 machine_load_store_relaxed<size_t,sizeof(size_t)>::store(
const_cast<size_t&
>(location), value );
752 #ifndef __TBB_TypeWithAlignmentAtLeastAsStrict 754 #if __TBB_ATTRIBUTE_ALIGNED_PRESENT 756 #define __TBB_DefineTypeWithAlignment(PowerOf2) \ 757 struct __TBB_machine_type_with_alignment_##PowerOf2 { \ 758 uint32_t member[PowerOf2/sizeof(uint32_t)]; \ 759 } __attribute__((aligned(PowerOf2))); 760 #define __TBB_alignof(T) __alignof__(T) 762 #elif __TBB_DECLSPEC_ALIGN_PRESENT 764 #define __TBB_DefineTypeWithAlignment(PowerOf2) \ 765 __declspec(align(PowerOf2)) \ 766 struct __TBB_machine_type_with_alignment_##PowerOf2 { \ 767 uint32_t member[PowerOf2/sizeof(uint32_t)]; \ 769 #define __TBB_alignof(T) __alignof(T) 772 #error Must define __TBB_TypeWithAlignmentAtLeastAsStrict(T) 777 __TBB_DefineTypeWithAlignment(16)
778 __TBB_DefineTypeWithAlignment(32)
779 __TBB_DefineTypeWithAlignment(64)
781 typedef __TBB_machine_type_with_alignment_64 __TBB_machine_type_with_strictest_alignment;
784 template<
size_t N> struct type_with_alignment;
787 template<> struct type_with_alignment<1> {
char member; };
788 template<>
struct type_with_alignment<2> { uint16_t member; };
789 template<>
struct type_with_alignment<4> { uint32_t member; };
790 template<>
struct type_with_alignment<8> { uint64_t member; };
791 template<>
struct type_with_alignment<16> {__TBB_machine_type_with_alignment_16 member; };
792 template<>
struct type_with_alignment<32> {__TBB_machine_type_with_alignment_32 member; };
793 template<>
struct type_with_alignment<64> {__TBB_machine_type_with_alignment_64 member; };
795 #if __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN 799 template<
size_t Size,
typename T>
800 struct work_around_alignment_bug {
801 static const size_t alignment = __TBB_alignof(T);
803 #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment<tbb::internal::work_around_alignment_bug<sizeof(T),T>::alignment> 805 #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment<__TBB_alignof(T)> 813 static const T byte_table[256];
818 const T reverse<T>::byte_table[256] = {
819 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
820 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
821 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
822 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
823 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
824 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
825 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
826 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
827 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
828 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
829 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
830 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
831 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
832 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
833 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
834 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
841 using tbb::internal::__TBB_load_with_acquire;
842 using tbb::internal::__TBB_store_with_release;
845 #define __TBB_load_acquire __TBB_load_with_acquire 846 #define __TBB_store_release __TBB_store_with_release 849 inline intptr_t __TBB_Log2( uintptr_t x ) {
850 if( x==0 )
return -1;
855 if(
sizeof(x)>4 && (tmp_ = ((uint64_t)x)>>32) ) { x=tmp_; result += 32; }
857 if( uintptr_t tmp = x>>16 ) { x=tmp; result += 16; }
858 if( uintptr_t tmp = x>>8 ) { x=tmp; result += 8; }
859 if( uintptr_t tmp = x>>4 ) { x=tmp; result += 4; }
860 if( uintptr_t tmp = x>>2 ) { x=tmp; result += 2; }
862 return (x&2)? result+1: result;
866 #ifndef __TBB_AtomicOR 867 inline void __TBB_AtomicOR(
volatile void *operand, uintptr_t addend ) {
868 for( tbb::internal::atomic_backoff b;;b.pause() ) {
869 uintptr_t tmp = *(
volatile uintptr_t *)operand;
870 uintptr_t result = __TBB_CompareAndSwapW(operand, tmp|addend, tmp);
871 if( result==tmp )
break;
876 #ifndef __TBB_AtomicAND 877 inline void __TBB_AtomicAND(
volatile void *operand, uintptr_t addend ) {
878 for( tbb::internal::atomic_backoff b;;b.pause() ) {
879 uintptr_t tmp = *(
volatile uintptr_t *)operand;
880 uintptr_t result = __TBB_CompareAndSwapW(operand, tmp&addend, tmp);
881 if( result==tmp )
break;
886 #if __TBB_PREFETCHING 887 #ifndef __TBB_cl_prefetch 888 #error This platform does not define cache management primitives required for __TBB_PREFETCHING 891 #ifndef __TBB_cl_evict 892 #define __TBB_cl_evict(p) 897 typedef unsigned char __TBB_Flag;
899 typedef __TBB_atomic __TBB_Flag __TBB_atomic_flag;
901 #ifndef __TBB_TryLockByte 902 inline bool __TBB_TryLockByte( __TBB_atomic_flag &flag ) {
903 return __TBB_machine_cmpswp1(&flag,1,0)==0;
907 #ifndef __TBB_LockByte 908 inline __TBB_Flag __TBB_LockByte( __TBB_atomic_flag& flag ) {
909 tbb::internal::atomic_backoff backoff;
910 while( !__TBB_TryLockByte(flag) ) backoff.pause();
915 #ifndef __TBB_UnlockByte 916 #define __TBB_UnlockByte(addr) __TBB_store_with_release((addr),0) 920 #if ( __TBB_x86_32 || __TBB_x86_64 ) 921 inline void __TBB_TryLockByteElidedCancel() { __TBB_machine_try_lock_elided_cancel(); }
923 inline bool __TBB_TryLockByteElided( __TBB_atomic_flag& flag ) {
924 bool res = __TBB_machine_try_lock_elided( &flag )!=0;
928 if( !res ) __TBB_TryLockByteElidedCancel();
932 inline void __TBB_LockByteElided( __TBB_atomic_flag& flag )
935 tbb::internal::spin_wait_while_eq( flag, 1 );
936 if( __TBB_machine_try_lock_elided( &flag ) )
940 __TBB_TryLockByteElidedCancel();
944 inline void __TBB_UnlockByteElided( __TBB_atomic_flag& flag ) {
945 __TBB_machine_unlock_elided( &flag );
949 #ifndef __TBB_ReverseByte 950 inline unsigned char __TBB_ReverseByte(
unsigned char src) {
951 return tbb::internal::reverse<unsigned char>::byte_table[src];
956 T __TBB_ReverseBits(T src) {
958 unsigned char *original = (
unsigned char *) &src;
959 unsigned char *reversed = (
unsigned char *) &dst;
961 for(
int i =
sizeof(T)-1; i >= 0; i-- )
962 reversed[i] = __TBB_ReverseByte( original[
sizeof(T)-i-1] );
Sequential consistency.
Definition: atomic.h:45
Definition: _flow_graph_async_msg_impl.h:32
The namespace tbb contains all components of the library.
Definition: parallel_for.h:44