2 Copyright 2005-2010 Intel Corporation. All Rights Reserved.
4 This file is part of Threading Building Blocks.
6 Threading Building Blocks is free software; you can redistribute it
7 and/or modify it under the terms of the GNU General Public License
8 version 2 as published by the Free Software Foundation.
10 Threading Building Blocks is distributed in the hope that it will be
11 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with Threading Building Blocks; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 As a special exception, you may use this file as part of a free software
20 library without restriction. Specifically, if other files instantiate
21 templates or use macros or inline functions from this file, or you compile
22 this file and link it with other files to produce an executable, this
23 file does not by itself cause the resulting executable to be covered by
24 the GNU General Public License. This exception does not however
25 invalidate any other reasons why the executable file might be covered by
26 the GNU General Public License.
29 #ifndef __TBB_machine_H
30 #define __TBB_machine_H
32 #include "tbb_stddef.h"
37 #pragma managed(push, off)
41 #include "machine/linux_ia32.h"
42 extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void );
43 #define __TBB_Yield() SwitchToThread()
44 #elif defined(_M_IX86)
45 #include "machine/windows_ia32.h"
46 #elif defined(_M_AMD64)
47 #include "machine/windows_intel64.h"
49 #include "machine/xbox360_ppc.h"
51 #error Unsupported platform
58 #elif __linux__ || __FreeBSD__
61 #include "machine/linux_ia32.h"
63 #include "machine/linux_intel64.h"
65 #include "machine/linux_ia64.h"
71 #include "machine/linux_ia32.h"
73 #include "machine/linux_intel64.h"
75 #include "machine/mac_ppc.h"
80 #include "machine/ibm_aix51.h"
82 #elif __sun || __SUNPRO_CC
85 #define __volatile__ volatile
86 #if __i386 || __i386__
87 #include "machine/linux_ia32.h"
89 #include "machine/linux_intel64.h"
91 #include "machine/sunos_sparc.h"
96 #if !defined(__TBB_CompareAndSwap4) \
97 || !defined(__TBB_CompareAndSwap8) \
98 || !defined(__TBB_Yield) \
99 || !defined(__TBB_release_consistency_helper)
100 #error Minimal requirements for tbb_machine.h not satisfied
103 #ifndef __TBB_load_with_acquire
104 //! Load with acquire semantics; i.e., no following memory operation can move above the load.
106 inline T __TBB_load_with_acquire(const volatile T& location) {
108 __TBB_release_consistency_helper();
113 #ifndef __TBB_store_with_release
114 //! Store with release semantics; i.e., no prior memory operation can move below the store.
115 template<typename T, typename V>
116 inline void __TBB_store_with_release(volatile T& location, V value) {
117 __TBB_release_consistency_helper();
123 inline void __TBB_Pause(int32_t) {
131 //! Class that implements exponential backoff.
132 /** See implementation of spin_wait_while_eq for an example. */
133 class atomic_backoff {
134 //! Time delay, in units of "pause" instructions.
135 /** Should be equal to approximately the number of "pause" instructions
136 that take the same time as an context switch. */
137 static const int32_t LOOPS_BEFORE_YIELD = 16;
140 atomic_backoff() : count(1) {}
142 //! Pause for a while.
144 if( count<=LOOPS_BEFORE_YIELD ) {
146 // Pause twice as long the next time.
149 // Pause is so long that we might as well yield CPU to scheduler.
154 // pause for a few times and then return false immediately.
155 bool bounded_pause() {
156 if( count<=LOOPS_BEFORE_YIELD ) {
158 // Pause twice as long the next time.
171 //! Spin WHILE the value of the variable is equal to a given value
172 /** T and U should be comparable types. */
173 template<typename T, typename U>
174 void spin_wait_while_eq( const volatile T& location, U value ) {
175 atomic_backoff backoff;
176 while( location==value ) backoff.pause();
179 //! Spin UNTIL the value of the variable is equal to a given value
180 /** T and U should be comparable types. */
181 template<typename T, typename U>
182 void spin_wait_until_eq( const volatile T& location, const U value ) {
183 atomic_backoff backoff;
184 while( location!=value ) backoff.pause();
187 // T should be unsigned, otherwise sign propagation will break correctness of bit manipulations.
188 // S should be either 1 or 2, for the mask calculation to work correctly.
189 // Together, these rules limit applicability of Masked CAS to unsigned char and unsigned short.
190 template<size_t S, typename T>
191 inline T __TBB_MaskedCompareAndSwap (volatile T *ptr, T value, T comparand ) {
192 volatile uint32_t * base = (uint32_t*)( (uintptr_t)ptr & ~(uintptr_t)0x3 );
194 const uint8_t bitoffset = uint8_t( 8*( 4-S - (uintptr_t(ptr) & 0x3) ) );
196 const uint8_t bitoffset = uint8_t( 8*((uintptr_t)ptr & 0x3) );
198 const uint32_t mask = ( (1<<(S*8)) - 1 )<<bitoffset;
202 result = *base; // reload the base value which might change during the pause
203 uint32_t old_value = ( result & ~mask ) | ( comparand << bitoffset );
204 uint32_t new_value = ( result & ~mask ) | ( value << bitoffset );
205 // __TBB_CompareAndSwap4 presumed to have full fence.
206 result = __TBB_CompareAndSwap4( base, new_value, old_value );
207 if( result==old_value // CAS succeeded
208 || ((result^old_value)&mask)!=0 ) // CAS failed and the bits of interest have changed
210 else // CAS failed but the bits of interest left unchanged
213 return T((result & mask) >> bitoffset);
216 template<size_t S, typename T>
217 inline T __TBB_CompareAndSwapGeneric (volatile void *ptr, T value, T comparand ) {
218 return __TBB_CompareAndSwapW((T *)ptr,value,comparand);
222 inline uint8_t __TBB_CompareAndSwapGeneric <1,uint8_t> (volatile void *ptr, uint8_t value, uint8_t comparand ) {
223 #ifdef __TBB_CompareAndSwap1
224 return __TBB_CompareAndSwap1(ptr,value,comparand);
226 return __TBB_MaskedCompareAndSwap<1,uint8_t>((volatile uint8_t *)ptr,value,comparand);
231 inline uint16_t __TBB_CompareAndSwapGeneric <2,uint16_t> (volatile void *ptr, uint16_t value, uint16_t comparand ) {
232 #ifdef __TBB_CompareAndSwap2
233 return __TBB_CompareAndSwap2(ptr,value,comparand);
235 return __TBB_MaskedCompareAndSwap<2,uint16_t>((volatile uint16_t *)ptr,value,comparand);
240 inline uint32_t __TBB_CompareAndSwapGeneric <4,uint32_t> (volatile void *ptr, uint32_t value, uint32_t comparand ) {
241 return __TBB_CompareAndSwap4(ptr,value,comparand);
245 inline uint64_t __TBB_CompareAndSwapGeneric <8,uint64_t> (volatile void *ptr, uint64_t value, uint64_t comparand ) {
246 return __TBB_CompareAndSwap8(ptr,value,comparand);
249 template<size_t S, typename T>
250 inline T __TBB_FetchAndAddGeneric (volatile void *ptr, T addend) {
254 result = *reinterpret_cast<volatile T *>(ptr);
255 // __TBB_CompareAndSwapGeneric presumed to have full fence.
256 if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, result+addend, result )==result )
263 template<size_t S, typename T>
264 inline T __TBB_FetchAndStoreGeneric (volatile void *ptr, T value) {
268 result = *reinterpret_cast<volatile T *>(ptr);
269 // __TBB_CompareAndSwapGeneric presumed to have full fence.
270 if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, value, result )==result )
277 // Macro __TBB_TypeWithAlignmentAtLeastAsStrict(T) should be a type with alignment at least as
278 // strict as type T. Type type should have a trivial default constructor and destructor, so that
279 // arrays of that type can be declared without initializers.
280 // It is correct (but perhaps a waste of space) if __TBB_TypeWithAlignmentAtLeastAsStrict(T) expands
281 // to a type bigger than T.
282 // The default definition here works on machines where integers are naturally aligned and the
283 // strictest alignment is 16.
284 #ifndef __TBB_TypeWithAlignmentAtLeastAsStrict
286 #if __GNUC__ || __SUNPRO_CC
287 struct __TBB_machine_type_with_strictest_alignment {
289 } __attribute__((aligned(16)));
291 __declspec(align(16)) struct __TBB_machine_type_with_strictest_alignment {
295 #error Must define __TBB_TypeWithAlignmentAtLeastAsStrict(T) or __TBB_machine_type_with_strictest_alignment
298 template<size_t N> struct type_with_alignment {__TBB_machine_type_with_strictest_alignment member;};
299 template<> struct type_with_alignment<1> { char member; };
300 template<> struct type_with_alignment<2> { uint16_t member; };
301 template<> struct type_with_alignment<4> { uint32_t member; };
302 template<> struct type_with_alignment<8> { uint64_t member; };
304 #if _MSC_VER||defined(__GNUC__)&&__GNUC__==3 && __GNUC_MINOR__<=2
305 //! Work around for bug in GNU 3.2 and MSVC compilers.
306 /** Bug is that compiler sometimes returns 0 for __alignof(T) when T has not yet been instantiated.
307 The work-around forces instantiation by forcing computation of sizeof(T) before __alignof(T). */
308 template<size_t Size, typename T>
309 struct work_around_alignment_bug {
311 static const size_t alignment = __alignof(T);
313 static const size_t alignment = __alignof__(T);
316 #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment<tbb::internal::work_around_alignment_bug<sizeof(T),T>::alignment>
317 #elif __GNUC__ || __SUNPRO_CC
318 #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment<__alignof__(T)>
320 #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) __TBB_machine_type_with_strictest_alignment
322 #endif /* ____TBB_TypeWithAlignmentAtLeastAsStrict */
324 // Template class here is to avoid instantiation of the static data for modules that don't use it
327 static const T byte_table[256];
329 // An efficient implementation of the reverse function utilizes a 2^8 lookup table holding the bit-reversed
330 // values of [0..2^8 - 1]. Those values can also be computed on the fly at a slightly higher cost.
332 const T reverse<T>::byte_table[256] = {
333 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
334 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
335 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
336 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
337 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
338 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
339 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
340 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
341 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
342 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
343 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
344 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
345 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
346 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
347 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
348 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
351 } // namespace internal
354 #ifndef __TBB_CompareAndSwap1
355 #define __TBB_CompareAndSwap1 tbb::internal::__TBB_CompareAndSwapGeneric<1,uint8_t>
358 #ifndef __TBB_CompareAndSwap2
359 #define __TBB_CompareAndSwap2 tbb::internal::__TBB_CompareAndSwapGeneric<2,uint16_t>
362 #ifndef __TBB_CompareAndSwapW
363 #define __TBB_CompareAndSwapW tbb::internal::__TBB_CompareAndSwapGeneric<sizeof(ptrdiff_t),ptrdiff_t>
366 #ifndef __TBB_FetchAndAdd1
367 #define __TBB_FetchAndAdd1 tbb::internal::__TBB_FetchAndAddGeneric<1,uint8_t>
370 #ifndef __TBB_FetchAndAdd2
371 #define __TBB_FetchAndAdd2 tbb::internal::__TBB_FetchAndAddGeneric<2,uint16_t>
374 #ifndef __TBB_FetchAndAdd4
375 #define __TBB_FetchAndAdd4 tbb::internal::__TBB_FetchAndAddGeneric<4,uint32_t>
378 #ifndef __TBB_FetchAndAdd8
379 #define __TBB_FetchAndAdd8 tbb::internal::__TBB_FetchAndAddGeneric<8,uint64_t>
382 #ifndef __TBB_FetchAndAddW
383 #define __TBB_FetchAndAddW tbb::internal::__TBB_FetchAndAddGeneric<sizeof(ptrdiff_t),ptrdiff_t>
386 #ifndef __TBB_FetchAndStore1
387 #define __TBB_FetchAndStore1 tbb::internal::__TBB_FetchAndStoreGeneric<1,uint8_t>
390 #ifndef __TBB_FetchAndStore2
391 #define __TBB_FetchAndStore2 tbb::internal::__TBB_FetchAndStoreGeneric<2,uint16_t>
394 #ifndef __TBB_FetchAndStore4
395 #define __TBB_FetchAndStore4 tbb::internal::__TBB_FetchAndStoreGeneric<4,uint32_t>
398 #ifndef __TBB_FetchAndStore8
399 #define __TBB_FetchAndStore8 tbb::internal::__TBB_FetchAndStoreGeneric<8,uint64_t>
402 #ifndef __TBB_FetchAndStoreW
403 #define __TBB_FetchAndStoreW tbb::internal::__TBB_FetchAndStoreGeneric<sizeof(ptrdiff_t),ptrdiff_t>
406 #if __TBB_DECL_FENCED_ATOMICS
408 #ifndef __TBB_CompareAndSwap1__TBB_full_fence
409 #define __TBB_CompareAndSwap1__TBB_full_fence __TBB_CompareAndSwap1
411 #ifndef __TBB_CompareAndSwap1acquire
412 #define __TBB_CompareAndSwap1acquire __TBB_CompareAndSwap1__TBB_full_fence
414 #ifndef __TBB_CompareAndSwap1release
415 #define __TBB_CompareAndSwap1release __TBB_CompareAndSwap1__TBB_full_fence
418 #ifndef __TBB_CompareAndSwap2__TBB_full_fence
419 #define __TBB_CompareAndSwap2__TBB_full_fence __TBB_CompareAndSwap2
421 #ifndef __TBB_CompareAndSwap2acquire
422 #define __TBB_CompareAndSwap2acquire __TBB_CompareAndSwap2__TBB_full_fence
424 #ifndef __TBB_CompareAndSwap2release
425 #define __TBB_CompareAndSwap2release __TBB_CompareAndSwap2__TBB_full_fence
428 #ifndef __TBB_CompareAndSwap4__TBB_full_fence
429 #define __TBB_CompareAndSwap4__TBB_full_fence __TBB_CompareAndSwap4
431 #ifndef __TBB_CompareAndSwap4acquire
432 #define __TBB_CompareAndSwap4acquire __TBB_CompareAndSwap4__TBB_full_fence
434 #ifndef __TBB_CompareAndSwap4release
435 #define __TBB_CompareAndSwap4release __TBB_CompareAndSwap4__TBB_full_fence
438 #ifndef __TBB_CompareAndSwap8__TBB_full_fence
439 #define __TBB_CompareAndSwap8__TBB_full_fence __TBB_CompareAndSwap8
441 #ifndef __TBB_CompareAndSwap8acquire
442 #define __TBB_CompareAndSwap8acquire __TBB_CompareAndSwap8__TBB_full_fence
444 #ifndef __TBB_CompareAndSwap8release
445 #define __TBB_CompareAndSwap8release __TBB_CompareAndSwap8__TBB_full_fence
448 #ifndef __TBB_FetchAndAdd1__TBB_full_fence
449 #define __TBB_FetchAndAdd1__TBB_full_fence __TBB_FetchAndAdd1
451 #ifndef __TBB_FetchAndAdd1acquire
452 #define __TBB_FetchAndAdd1acquire __TBB_FetchAndAdd1__TBB_full_fence
454 #ifndef __TBB_FetchAndAdd1release
455 #define __TBB_FetchAndAdd1release __TBB_FetchAndAdd1__TBB_full_fence
458 #ifndef __TBB_FetchAndAdd2__TBB_full_fence
459 #define __TBB_FetchAndAdd2__TBB_full_fence __TBB_FetchAndAdd2
461 #ifndef __TBB_FetchAndAdd2acquire
462 #define __TBB_FetchAndAdd2acquire __TBB_FetchAndAdd2__TBB_full_fence
464 #ifndef __TBB_FetchAndAdd2release
465 #define __TBB_FetchAndAdd2release __TBB_FetchAndAdd2__TBB_full_fence
468 #ifndef __TBB_FetchAndAdd4__TBB_full_fence
469 #define __TBB_FetchAndAdd4__TBB_full_fence __TBB_FetchAndAdd4
471 #ifndef __TBB_FetchAndAdd4acquire
472 #define __TBB_FetchAndAdd4acquire __TBB_FetchAndAdd4__TBB_full_fence
474 #ifndef __TBB_FetchAndAdd4release
475 #define __TBB_FetchAndAdd4release __TBB_FetchAndAdd4__TBB_full_fence
478 #ifndef __TBB_FetchAndAdd8__TBB_full_fence
479 #define __TBB_FetchAndAdd8__TBB_full_fence __TBB_FetchAndAdd8
481 #ifndef __TBB_FetchAndAdd8acquire
482 #define __TBB_FetchAndAdd8acquire __TBB_FetchAndAdd8__TBB_full_fence
484 #ifndef __TBB_FetchAndAdd8release
485 #define __TBB_FetchAndAdd8release __TBB_FetchAndAdd8__TBB_full_fence
488 #ifndef __TBB_FetchAndStore1__TBB_full_fence
489 #define __TBB_FetchAndStore1__TBB_full_fence __TBB_FetchAndStore1
491 #ifndef __TBB_FetchAndStore1acquire
492 #define __TBB_FetchAndStore1acquire __TBB_FetchAndStore1__TBB_full_fence
494 #ifndef __TBB_FetchAndStore1release
495 #define __TBB_FetchAndStore1release __TBB_FetchAndStore1__TBB_full_fence
498 #ifndef __TBB_FetchAndStore2__TBB_full_fence
499 #define __TBB_FetchAndStore2__TBB_full_fence __TBB_FetchAndStore2
501 #ifndef __TBB_FetchAndStore2acquire
502 #define __TBB_FetchAndStore2acquire __TBB_FetchAndStore2__TBB_full_fence
504 #ifndef __TBB_FetchAndStore2release
505 #define __TBB_FetchAndStore2release __TBB_FetchAndStore2__TBB_full_fence
508 #ifndef __TBB_FetchAndStore4__TBB_full_fence
509 #define __TBB_FetchAndStore4__TBB_full_fence __TBB_FetchAndStore4
511 #ifndef __TBB_FetchAndStore4acquire
512 #define __TBB_FetchAndStore4acquire __TBB_FetchAndStore4__TBB_full_fence
514 #ifndef __TBB_FetchAndStore4release
515 #define __TBB_FetchAndStore4release __TBB_FetchAndStore4__TBB_full_fence
518 #ifndef __TBB_FetchAndStore8__TBB_full_fence
519 #define __TBB_FetchAndStore8__TBB_full_fence __TBB_FetchAndStore8
521 #ifndef __TBB_FetchAndStore8acquire
522 #define __TBB_FetchAndStore8acquire __TBB_FetchAndStore8__TBB_full_fence
524 #ifndef __TBB_FetchAndStore8release
525 #define __TBB_FetchAndStore8release __TBB_FetchAndStore8__TBB_full_fence
528 #endif // __TBB_DECL_FENCED_ATOMICS
530 // Special atomic functions
531 #ifndef __TBB_FetchAndAddWrelease
532 #define __TBB_FetchAndAddWrelease __TBB_FetchAndAddW
535 #ifndef __TBB_FetchAndIncrementWacquire
536 #define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1)
539 #ifndef __TBB_FetchAndDecrementWrelease
540 #define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,(-1))
543 #if __TBB_WORDSIZE==4
544 // On 32-bit platforms, "atomic.h" requires definition of __TBB_Store8 and __TBB_Load8
546 inline void __TBB_Store8 (volatile void *ptr, int64_t value) {
547 tbb::internal::atomic_backoff b;
549 int64_t result = *(int64_t *)ptr;
550 if( __TBB_CompareAndSwap8(ptr,value,result)==result ) break;
557 inline int64_t __TBB_Load8 (const volatile void *ptr) {
558 int64_t result = *(int64_t *)ptr;
559 result = __TBB_CompareAndSwap8((volatile void *)ptr,result,result);
563 #endif /* __TBB_WORDSIZE==4 */
566 inline intptr_t __TBB_Log2( uintptr_t x ) {
567 if( x==0 ) return -1;
570 #if __TBB_WORDSIZE>=8
571 if( (tmp = x>>32) ) { x=tmp; result += 32; }
573 if( (tmp = x>>16) ) { x=tmp; result += 16; }
574 if( (tmp = x>>8) ) { x=tmp; result += 8; }
575 if( (tmp = x>>4) ) { x=tmp; result += 4; }
576 if( (tmp = x>>2) ) { x=tmp; result += 2; }
577 return (x&2)? result+1: result;
581 #ifndef __TBB_AtomicOR
582 inline void __TBB_AtomicOR( volatile void *operand, uintptr_t addend ) {
583 tbb::internal::atomic_backoff b;
585 uintptr_t tmp = *(volatile uintptr_t *)operand;
586 uintptr_t result = __TBB_CompareAndSwapW(operand, tmp|addend, tmp);
587 if( result==tmp ) break;
593 #ifndef __TBB_AtomicAND
594 inline void __TBB_AtomicAND( volatile void *operand, uintptr_t addend ) {
595 tbb::internal::atomic_backoff b;
597 uintptr_t tmp = *(volatile uintptr_t *)operand;
598 uintptr_t result = __TBB_CompareAndSwapW(operand, tmp&addend, tmp);
599 if( result==tmp ) break;
605 #ifndef __TBB_TryLockByte
606 inline bool __TBB_TryLockByte( unsigned char &flag ) {
607 return __TBB_CompareAndSwap1(&flag,1,0)==0;
611 #ifndef __TBB_LockByte
612 inline uintptr_t __TBB_LockByte( unsigned char& flag ) {
613 if ( !__TBB_TryLockByte(flag) ) {
614 tbb::internal::atomic_backoff b;
617 } while ( !__TBB_TryLockByte(flag) );
623 #ifndef __TBB_ReverseByte
624 inline unsigned char __TBB_ReverseByte(unsigned char src) {
625 return tbb::internal::reverse<unsigned char>::byte_table[src];
630 T __TBB_ReverseBits(T src)
633 unsigned char *original = (unsigned char *) &src;
634 unsigned char *reversed = (unsigned char *) &dst;
636 for( int i = sizeof(T)-1; i >= 0; i-- )
637 reversed[i] = __TBB_ReverseByte( original[sizeof(T)-i-1] );
642 #endif /* __TBB_machine_H */