Shadowrun: Awakened 29 September 2011 - Build 871
tbb_machine.h
Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2010 Intel Corporation.  All Rights Reserved.
00003 
00004     This file is part of Threading Building Blocks.
00005 
00006     Threading Building Blocks is free software; you can redistribute it
00007     and/or modify it under the terms of the GNU General Public License
00008     version 2 as published by the Free Software Foundation.
00009 
00010     Threading Building Blocks is distributed in the hope that it will be
00011     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00012     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with Threading Building Blocks; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019     As a special exception, you may use this file as part of a free software
00020     library without restriction.  Specifically, if other files instantiate
00021     templates or use macros or inline functions from this file, or you compile
00022     this file and link it with other files to produce an executable, this
00023     file does not by itself cause the resulting executable to be covered by
00024     the GNU General Public License.  This exception does not however
00025     invalidate any other reasons why the executable file might be covered by
00026     the GNU General Public License.
00027 */
00028 
00029 #ifndef __TBB_machine_H
00030 #define __TBB_machine_H
00031 
00032 #include "tbb_stddef.h"
00033 
00034 #if _WIN32||_WIN64
00035 
00036 #ifdef _MANAGED
00037 #pragma managed(push, off)
00038 #endif
00039 
00040 #if __MINGW32__
00041 #include "machine/linux_ia32.h"
00042 extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void );
00043 #define __TBB_Yield()  SwitchToThread()
00044 #elif defined(_M_IX86)
00045 #include "machine/windows_ia32.h"
00046 #elif defined(_M_AMD64) 
00047 #include "machine/windows_intel64.h"
00048 #elif _XBOX 
00049 #include "machine/xbox360_ppc.h"
00050 #else
00051 #error Unsupported platform
00052 #endif
00053 
00054 #ifdef _MANAGED
00055 #pragma managed(pop)
00056 #endif
00057 
00058 #elif __linux__ || __FreeBSD__
00059 
00060 #if __i386__
00061 #include "machine/linux_ia32.h"
00062 #elif __x86_64__
00063 #include "machine/linux_intel64.h"
00064 #elif __ia64__
00065 #include "machine/linux_ia64.h"
00066 #endif
00067 
00068 #elif __APPLE__
00069 
00070 #if __i386__
00071 #include "machine/linux_ia32.h"
00072 #elif __x86_64__
00073 #include "machine/linux_intel64.h"
00074 #elif __POWERPC__
00075 #include "machine/mac_ppc.h"
00076 #endif
00077 
00078 #elif _AIX
00079 
00080 #include "machine/ibm_aix51.h"
00081 
00082 #elif __sun || __SUNPRO_CC
00083 
00084 #define __asm__ asm 
00085 #define __volatile__ volatile
00086 #if __i386  || __i386__
00087 #include "machine/linux_ia32.h"
00088 #elif __x86_64__
00089 #include "machine/linux_intel64.h"
00090 #elif __sparc
00091 #include "machine/sunos_sparc.h"
00092 #endif
00093 
00094 #endif
00095 
00096 #if    !defined(__TBB_CompareAndSwap4) \
00097     || !defined(__TBB_CompareAndSwap8) \
00098     || !defined(__TBB_Yield)           \
00099     || !defined(__TBB_release_consistency_helper)
00100 #error Minimal requirements for tbb_machine.h not satisfied 
00101 #endif
00102 
00103 #ifndef __TBB_load_with_acquire
00104 
00105     template<typename T>
00106     inline T __TBB_load_with_acquire(const volatile T& location) {
00107         T temp = location;
00108         __TBB_release_consistency_helper();
00109         return temp;
00110     }
00111 #endif
00112 
00113 #ifndef __TBB_store_with_release
00114 
00115     template<typename T, typename V>
00116     inline void __TBB_store_with_release(volatile T& location, V value) {
00117         __TBB_release_consistency_helper();
00118         location = T(value); 
00119     }
00120 #endif
00121 
00122 #ifndef __TBB_Pause
00123     inline void __TBB_Pause(int32_t) {
00124         __TBB_Yield();
00125     }
00126 #endif
00127 
00128 namespace tbb {
00129 namespace internal {
00130 
00132 
00133 class atomic_backoff {
00135 
00137     static const int32_t LOOPS_BEFORE_YIELD = 16;
00138     int32_t count;
00139 public:
00140     atomic_backoff() : count(1) {}
00141 
00143     void pause() {
00144         if( count<=LOOPS_BEFORE_YIELD ) {
00145             __TBB_Pause(count);
00146             // Pause twice as long the next time.
00147             count*=2;
00148         } else {
00149             // Pause is so long that we might as well yield CPU to scheduler.
00150             __TBB_Yield();
00151         }
00152     }
00153 
00154     // pause for a few times and then return false immediately.
00155     bool bounded_pause() {
00156         if( count<=LOOPS_BEFORE_YIELD ) {
00157             __TBB_Pause(count);
00158             // Pause twice as long the next time.
00159             count*=2;
00160             return true;
00161         } else {
00162             return false;
00163         }
00164     }
00165 
00166     void reset() {
00167         count = 1;
00168     }
00169 };
00170 
00172 
00173 template<typename T, typename U>
00174 void spin_wait_while_eq( const volatile T& location, U value ) {
00175     atomic_backoff backoff;
00176     while( location==value ) backoff.pause();
00177 }
00178 
00180 
00181 template<typename T, typename U>
00182 void spin_wait_until_eq( const volatile T& location, const U value ) {
00183     atomic_backoff backoff;
00184     while( location!=value ) backoff.pause();
00185 }
00186 
00187 // T should be unsigned, otherwise sign propagation will break correctness of bit manipulations.
00188 // S should be either 1 or 2, for the mask calculation to work correctly.
00189 // Together, these rules limit applicability of Masked CAS to unsigned char and unsigned short.
00190 template<size_t S, typename T>
00191 inline T __TBB_MaskedCompareAndSwap (volatile T *ptr, T value, T comparand ) {
00192     volatile uint32_t * base = (uint32_t*)( (uintptr_t)ptr & ~(uintptr_t)0x3 );
00193 #if __TBB_BIG_ENDIAN
00194     const uint8_t bitoffset = uint8_t( 8*( 4-S - (uintptr_t(ptr) & 0x3) ) );
00195 #else
00196     const uint8_t bitoffset = uint8_t( 8*((uintptr_t)ptr & 0x3) );
00197 #endif
00198     const uint32_t mask = ( (1<<(S*8)) - 1 )<<bitoffset;
00199     atomic_backoff b;
00200     uint32_t result;
00201     for(;;) {
00202         result = *base; // reload the base value which might change during the pause
00203         uint32_t old_value = ( result & ~mask ) | ( comparand << bitoffset );
00204         uint32_t new_value = ( result & ~mask ) | ( value << bitoffset );
00205         // __TBB_CompareAndSwap4 presumed to have full fence. 
00206         result = __TBB_CompareAndSwap4( base, new_value, old_value );
00207         if(  result==old_value               // CAS succeeded
00208           || ((result^old_value)&mask)!=0 )  // CAS failed and the bits of interest have changed
00209             break;
00210         else                                 // CAS failed but the bits of interest left unchanged
00211             b.pause();
00212     }
00213     return T((result & mask) >> bitoffset);
00214 }
00215 
00216 template<size_t S, typename T>
00217 inline T __TBB_CompareAndSwapGeneric (volatile void *ptr, T value, T comparand ) { 
00218     return __TBB_CompareAndSwapW((T *)ptr,value,comparand);
00219 }
00220 
00221 template<>
00222 inline uint8_t __TBB_CompareAndSwapGeneric <1,uint8_t> (volatile void *ptr, uint8_t value, uint8_t comparand ) {
00223 #ifdef __TBB_CompareAndSwap1
00224     return __TBB_CompareAndSwap1(ptr,value,comparand);
00225 #else
00226     return __TBB_MaskedCompareAndSwap<1,uint8_t>((volatile uint8_t *)ptr,value,comparand);
00227 #endif
00228 }
00229 
00230 template<>
00231 inline uint16_t __TBB_CompareAndSwapGeneric <2,uint16_t> (volatile void *ptr, uint16_t value, uint16_t comparand ) {
00232 #ifdef __TBB_CompareAndSwap2
00233     return __TBB_CompareAndSwap2(ptr,value,comparand);
00234 #else
00235     return __TBB_MaskedCompareAndSwap<2,uint16_t>((volatile uint16_t *)ptr,value,comparand);
00236 #endif
00237 }
00238 
00239 template<>
00240 inline uint32_t __TBB_CompareAndSwapGeneric <4,uint32_t> (volatile void *ptr, uint32_t value, uint32_t comparand ) { 
00241     return __TBB_CompareAndSwap4(ptr,value,comparand);
00242 }
00243 
00244 template<>
00245 inline uint64_t __TBB_CompareAndSwapGeneric <8,uint64_t> (volatile void *ptr, uint64_t value, uint64_t comparand ) { 
00246     return __TBB_CompareAndSwap8(ptr,value,comparand);
00247 }
00248 
00249 template<size_t S, typename T>
00250 inline T __TBB_FetchAndAddGeneric (volatile void *ptr, T addend) {
00251     atomic_backoff b;
00252     T result;
00253     for(;;) {
00254         result = *reinterpret_cast<volatile T *>(ptr);
00255         // __TBB_CompareAndSwapGeneric presumed to have full fence. 
00256         if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, result+addend, result )==result ) 
00257             break;
00258         b.pause();
00259     }
00260     return result;
00261 }
00262 
00263 template<size_t S, typename T>
00264 inline T __TBB_FetchAndStoreGeneric (volatile void *ptr, T value) {
00265     atomic_backoff b;
00266     T result;
00267     for(;;) {
00268         result = *reinterpret_cast<volatile T *>(ptr);
00269         // __TBB_CompareAndSwapGeneric presumed to have full fence.
00270         if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, value, result )==result ) 
00271             break;
00272         b.pause();
00273     }
00274     return result;
00275 }
00276 
00277 // Macro __TBB_TypeWithAlignmentAtLeastAsStrict(T) should be a type with alignment at least as 
00278 // strict as type T.  Type type should have a trivial default constructor and destructor, so that
00279 // arrays of that type can be declared without initializers.  
00280 // It is correct (but perhaps a waste of space) if __TBB_TypeWithAlignmentAtLeastAsStrict(T) expands
00281 // to a type bigger than T.
00282 // The default definition here works on machines where integers are naturally aligned and the
00283 // strictest alignment is 16.
00284 #ifndef __TBB_TypeWithAlignmentAtLeastAsStrict
00285 
00286 #if __GNUC__ || __SUNPRO_CC
00287 struct __TBB_machine_type_with_strictest_alignment {
00288     int member[4];
00289 } __attribute__((aligned(16)));
00290 #elif _MSC_VER
00291 __declspec(align(16)) struct __TBB_machine_type_with_strictest_alignment {
00292     int member[4];
00293 };
00294 #else
00295 #error Must define __TBB_TypeWithAlignmentAtLeastAsStrict(T) or __TBB_machine_type_with_strictest_alignment
00296 #endif
00297 
00298 template<size_t N> struct type_with_alignment {__TBB_machine_type_with_strictest_alignment member;};
00299 template<> struct type_with_alignment<1> { char member; };
00300 template<> struct type_with_alignment<2> { uint16_t member; };
00301 template<> struct type_with_alignment<4> { uint32_t member; };
00302 template<> struct type_with_alignment<8> { uint64_t member; };
00303 
00304 #if _MSC_VER||defined(__GNUC__)&&__GNUC__==3 && __GNUC_MINOR__<=2  
00305 
00306 
00308 template<size_t Size, typename T> 
00309 struct work_around_alignment_bug {
00310 #if _MSC_VER
00311     static const size_t alignment = __alignof(T);
00312 #else
00313     static const size_t alignment = __alignof__(T);
00314 #endif
00315 };
00316 #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment<tbb::internal::work_around_alignment_bug<sizeof(T),T>::alignment>
00317 #elif __GNUC__ || __SUNPRO_CC
00318 #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment<__alignof__(T)>
00319 #else
00320 #define __TBB_TypeWithAlignmentAtLeastAsStrict(T) __TBB_machine_type_with_strictest_alignment
00321 #endif
00322 #endif  /* ____TBB_TypeWithAlignmentAtLeastAsStrict */
00323 
00324 // Template class here is to avoid instantiation of the static data for modules that don't use it
00325 template<typename T>
00326 struct reverse {
00327     static const T byte_table[256];
00328 };
00329 // An efficient implementation of the reverse function utilizes a 2^8 lookup table holding the bit-reversed
00330 // values of [0..2^8 - 1]. Those values can also be computed on the fly at a slightly higher cost.
00331 template<typename T>
00332 const T reverse<T>::byte_table[256] = {
00333     0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
00334     0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
00335     0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
00336     0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
00337     0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
00338     0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
00339     0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
00340     0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
00341     0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
00342     0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
00343     0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
00344     0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
00345     0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
00346     0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
00347     0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
00348     0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
00349 };
00350 
00351 } // namespace internal
00352 } // namespace tbb
00353 
00354 #ifndef __TBB_CompareAndSwap1
00355 #define __TBB_CompareAndSwap1 tbb::internal::__TBB_CompareAndSwapGeneric<1,uint8_t>
00356 #endif
00357 
00358 #ifndef __TBB_CompareAndSwap2 
00359 #define __TBB_CompareAndSwap2 tbb::internal::__TBB_CompareAndSwapGeneric<2,uint16_t>
00360 #endif
00361 
00362 #ifndef __TBB_CompareAndSwapW
00363 #define __TBB_CompareAndSwapW tbb::internal::__TBB_CompareAndSwapGeneric<sizeof(ptrdiff_t),ptrdiff_t>
00364 #endif
00365 
00366 #ifndef __TBB_FetchAndAdd1
00367 #define __TBB_FetchAndAdd1 tbb::internal::__TBB_FetchAndAddGeneric<1,uint8_t>
00368 #endif
00369 
00370 #ifndef __TBB_FetchAndAdd2
00371 #define __TBB_FetchAndAdd2 tbb::internal::__TBB_FetchAndAddGeneric<2,uint16_t>
00372 #endif
00373 
00374 #ifndef __TBB_FetchAndAdd4
00375 #define __TBB_FetchAndAdd4 tbb::internal::__TBB_FetchAndAddGeneric<4,uint32_t>
00376 #endif
00377 
00378 #ifndef __TBB_FetchAndAdd8
00379 #define __TBB_FetchAndAdd8 tbb::internal::__TBB_FetchAndAddGeneric<8,uint64_t>
00380 #endif
00381 
00382 #ifndef __TBB_FetchAndAddW
00383 #define __TBB_FetchAndAddW tbb::internal::__TBB_FetchAndAddGeneric<sizeof(ptrdiff_t),ptrdiff_t>
00384 #endif
00385 
00386 #ifndef __TBB_FetchAndStore1
00387 #define __TBB_FetchAndStore1 tbb::internal::__TBB_FetchAndStoreGeneric<1,uint8_t>
00388 #endif
00389 
00390 #ifndef __TBB_FetchAndStore2
00391 #define __TBB_FetchAndStore2 tbb::internal::__TBB_FetchAndStoreGeneric<2,uint16_t>
00392 #endif
00393 
00394 #ifndef __TBB_FetchAndStore4
00395 #define __TBB_FetchAndStore4 tbb::internal::__TBB_FetchAndStoreGeneric<4,uint32_t>
00396 #endif
00397 
00398 #ifndef __TBB_FetchAndStore8
00399 #define __TBB_FetchAndStore8 tbb::internal::__TBB_FetchAndStoreGeneric<8,uint64_t>
00400 #endif
00401 
00402 #ifndef __TBB_FetchAndStoreW
00403 #define __TBB_FetchAndStoreW tbb::internal::__TBB_FetchAndStoreGeneric<sizeof(ptrdiff_t),ptrdiff_t>
00404 #endif
00405 
00406 #if __TBB_DECL_FENCED_ATOMICS
00407 
00408 #ifndef __TBB_CompareAndSwap1__TBB_full_fence
00409 #define __TBB_CompareAndSwap1__TBB_full_fence __TBB_CompareAndSwap1
00410 #endif 
00411 #ifndef __TBB_CompareAndSwap1acquire
00412 #define __TBB_CompareAndSwap1acquire __TBB_CompareAndSwap1__TBB_full_fence
00413 #endif 
00414 #ifndef __TBB_CompareAndSwap1release
00415 #define __TBB_CompareAndSwap1release __TBB_CompareAndSwap1__TBB_full_fence
00416 #endif 
00417 
00418 #ifndef __TBB_CompareAndSwap2__TBB_full_fence
00419 #define __TBB_CompareAndSwap2__TBB_full_fence __TBB_CompareAndSwap2
00420 #endif
00421 #ifndef __TBB_CompareAndSwap2acquire
00422 #define __TBB_CompareAndSwap2acquire __TBB_CompareAndSwap2__TBB_full_fence
00423 #endif
00424 #ifndef __TBB_CompareAndSwap2release
00425 #define __TBB_CompareAndSwap2release __TBB_CompareAndSwap2__TBB_full_fence
00426 #endif
00427 
00428 #ifndef __TBB_CompareAndSwap4__TBB_full_fence
00429 #define __TBB_CompareAndSwap4__TBB_full_fence __TBB_CompareAndSwap4
00430 #endif 
00431 #ifndef __TBB_CompareAndSwap4acquire
00432 #define __TBB_CompareAndSwap4acquire __TBB_CompareAndSwap4__TBB_full_fence
00433 #endif 
00434 #ifndef __TBB_CompareAndSwap4release
00435 #define __TBB_CompareAndSwap4release __TBB_CompareAndSwap4__TBB_full_fence
00436 #endif 
00437 
00438 #ifndef __TBB_CompareAndSwap8__TBB_full_fence
00439 #define __TBB_CompareAndSwap8__TBB_full_fence __TBB_CompareAndSwap8
00440 #endif
00441 #ifndef __TBB_CompareAndSwap8acquire
00442 #define __TBB_CompareAndSwap8acquire __TBB_CompareAndSwap8__TBB_full_fence
00443 #endif
00444 #ifndef __TBB_CompareAndSwap8release
00445 #define __TBB_CompareAndSwap8release __TBB_CompareAndSwap8__TBB_full_fence
00446 #endif
00447 
00448 #ifndef __TBB_FetchAndAdd1__TBB_full_fence
00449 #define __TBB_FetchAndAdd1__TBB_full_fence __TBB_FetchAndAdd1
00450 #endif
00451 #ifndef __TBB_FetchAndAdd1acquire
00452 #define __TBB_FetchAndAdd1acquire __TBB_FetchAndAdd1__TBB_full_fence
00453 #endif
00454 #ifndef __TBB_FetchAndAdd1release
00455 #define __TBB_FetchAndAdd1release __TBB_FetchAndAdd1__TBB_full_fence
00456 #endif
00457 
00458 #ifndef __TBB_FetchAndAdd2__TBB_full_fence
00459 #define __TBB_FetchAndAdd2__TBB_full_fence __TBB_FetchAndAdd2
00460 #endif
00461 #ifndef __TBB_FetchAndAdd2acquire
00462 #define __TBB_FetchAndAdd2acquire __TBB_FetchAndAdd2__TBB_full_fence
00463 #endif
00464 #ifndef __TBB_FetchAndAdd2release
00465 #define __TBB_FetchAndAdd2release __TBB_FetchAndAdd2__TBB_full_fence
00466 #endif
00467 
00468 #ifndef __TBB_FetchAndAdd4__TBB_full_fence
00469 #define __TBB_FetchAndAdd4__TBB_full_fence __TBB_FetchAndAdd4
00470 #endif
00471 #ifndef __TBB_FetchAndAdd4acquire
00472 #define __TBB_FetchAndAdd4acquire __TBB_FetchAndAdd4__TBB_full_fence
00473 #endif
00474 #ifndef __TBB_FetchAndAdd4release
00475 #define __TBB_FetchAndAdd4release __TBB_FetchAndAdd4__TBB_full_fence
00476 #endif
00477 
00478 #ifndef __TBB_FetchAndAdd8__TBB_full_fence
00479 #define __TBB_FetchAndAdd8__TBB_full_fence __TBB_FetchAndAdd8
00480 #endif
00481 #ifndef __TBB_FetchAndAdd8acquire
00482 #define __TBB_FetchAndAdd8acquire __TBB_FetchAndAdd8__TBB_full_fence
00483 #endif
00484 #ifndef __TBB_FetchAndAdd8release
00485 #define __TBB_FetchAndAdd8release __TBB_FetchAndAdd8__TBB_full_fence
00486 #endif
00487 
00488 #ifndef __TBB_FetchAndStore1__TBB_full_fence
00489 #define __TBB_FetchAndStore1__TBB_full_fence __TBB_FetchAndStore1
00490 #endif
00491 #ifndef __TBB_FetchAndStore1acquire
00492 #define __TBB_FetchAndStore1acquire __TBB_FetchAndStore1__TBB_full_fence
00493 #endif
00494 #ifndef __TBB_FetchAndStore1release
00495 #define __TBB_FetchAndStore1release __TBB_FetchAndStore1__TBB_full_fence
00496 #endif
00497 
00498 #ifndef __TBB_FetchAndStore2__TBB_full_fence
00499 #define __TBB_FetchAndStore2__TBB_full_fence __TBB_FetchAndStore2
00500 #endif
00501 #ifndef __TBB_FetchAndStore2acquire
00502 #define __TBB_FetchAndStore2acquire __TBB_FetchAndStore2__TBB_full_fence
00503 #endif
00504 #ifndef __TBB_FetchAndStore2release
00505 #define __TBB_FetchAndStore2release __TBB_FetchAndStore2__TBB_full_fence
00506 #endif
00507 
00508 #ifndef __TBB_FetchAndStore4__TBB_full_fence
00509 #define __TBB_FetchAndStore4__TBB_full_fence __TBB_FetchAndStore4
00510 #endif
00511 #ifndef __TBB_FetchAndStore4acquire
00512 #define __TBB_FetchAndStore4acquire __TBB_FetchAndStore4__TBB_full_fence
00513 #endif
00514 #ifndef __TBB_FetchAndStore4release
00515 #define __TBB_FetchAndStore4release __TBB_FetchAndStore4__TBB_full_fence
00516 #endif
00517 
00518 #ifndef __TBB_FetchAndStore8__TBB_full_fence
00519 #define __TBB_FetchAndStore8__TBB_full_fence __TBB_FetchAndStore8
00520 #endif
00521 #ifndef __TBB_FetchAndStore8acquire
00522 #define __TBB_FetchAndStore8acquire __TBB_FetchAndStore8__TBB_full_fence
00523 #endif
00524 #ifndef __TBB_FetchAndStore8release
00525 #define __TBB_FetchAndStore8release __TBB_FetchAndStore8__TBB_full_fence
00526 #endif
00527 
00528 #endif // __TBB_DECL_FENCED_ATOMICS
00529 
00530 // Special atomic functions
00531 #ifndef __TBB_FetchAndAddWrelease
00532 #define __TBB_FetchAndAddWrelease __TBB_FetchAndAddW
00533 #endif
00534 
00535 #ifndef __TBB_FetchAndIncrementWacquire
00536 #define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1)
00537 #endif
00538 
00539 #ifndef __TBB_FetchAndDecrementWrelease
00540 #define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,(-1))
00541 #endif
00542 
00543 #if __TBB_WORDSIZE==4
00544 // On 32-bit platforms, "atomic.h" requires definition of __TBB_Store8 and __TBB_Load8
00545 #ifndef __TBB_Store8
00546 inline void __TBB_Store8 (volatile void *ptr, int64_t value) {
00547     tbb::internal::atomic_backoff b;
00548     for(;;) {
00549         int64_t result = *(int64_t *)ptr;
00550         if( __TBB_CompareAndSwap8(ptr,value,result)==result ) break;
00551         b.pause();
00552     }
00553 }
00554 #endif
00555 
00556 #ifndef __TBB_Load8
00557 inline int64_t __TBB_Load8 (const volatile void *ptr) {
00558     int64_t result = *(int64_t *)ptr;
00559     result = __TBB_CompareAndSwap8((volatile void *)ptr,result,result);
00560     return result;
00561 }
00562 #endif
00563 #endif /* __TBB_WORDSIZE==4 */
00564 
00565 #ifndef __TBB_Log2
00566 inline intptr_t __TBB_Log2( uintptr_t x ) {
00567     if( x==0 ) return -1;
00568     intptr_t result = 0;
00569     uintptr_t tmp;
00570 #if __TBB_WORDSIZE>=8
00571     if( (tmp = x>>32) ) { x=tmp; result += 32; }
00572 #endif
00573     if( (tmp = x>>16) ) { x=tmp; result += 16; }
00574     if( (tmp = x>>8) )  { x=tmp; result += 8; }
00575     if( (tmp = x>>4) )  { x=tmp; result += 4; }
00576     if( (tmp = x>>2) )  { x=tmp; result += 2; }
00577     return (x&2)? result+1: result;
00578 }
00579 #endif
00580 
00581 #ifndef __TBB_AtomicOR
00582 inline void __TBB_AtomicOR( volatile void *operand, uintptr_t addend ) {
00583     tbb::internal::atomic_backoff b;
00584     for(;;) {
00585         uintptr_t tmp = *(volatile uintptr_t *)operand;
00586         uintptr_t result = __TBB_CompareAndSwapW(operand, tmp|addend, tmp);
00587         if( result==tmp ) break;
00588         b.pause();
00589     }
00590 }
00591 #endif
00592 
00593 #ifndef __TBB_AtomicAND
00594 inline void __TBB_AtomicAND( volatile void *operand, uintptr_t addend ) {
00595     tbb::internal::atomic_backoff b;
00596     for(;;) {
00597         uintptr_t tmp = *(volatile uintptr_t *)operand;
00598         uintptr_t result = __TBB_CompareAndSwapW(operand, tmp&addend, tmp);
00599         if( result==tmp ) break;
00600         b.pause();
00601     }
00602 }
00603 #endif
00604 
00605 #ifndef __TBB_TryLockByte
00606 inline bool __TBB_TryLockByte( unsigned char &flag ) {
00607     return __TBB_CompareAndSwap1(&flag,1,0)==0;
00608 }
00609 #endif
00610 
00611 #ifndef __TBB_LockByte
00612 inline uintptr_t __TBB_LockByte( unsigned char& flag ) {
00613     if ( !__TBB_TryLockByte(flag) ) {
00614         tbb::internal::atomic_backoff b;
00615         do {
00616             b.pause();
00617         } while ( !__TBB_TryLockByte(flag) );
00618     }
00619     return 0;
00620 }
00621 #endif
00622 
00623 #ifndef __TBB_ReverseByte
00624 inline unsigned char __TBB_ReverseByte(unsigned char src) {
00625     return tbb::internal::reverse<unsigned char>::byte_table[src];
00626 }
00627 #endif
00628 
00629 template<typename T>
00630 T __TBB_ReverseBits(T src)
00631 {
00632     T dst;
00633     unsigned char *original = (unsigned char *) &src;
00634     unsigned char *reversed = (unsigned char *) &dst;
00635 
00636     for( int i = sizeof(T)-1; i >= 0; i-- )
00637         reversed[i] = __TBB_ReverseByte( original[sizeof(T)-i-1] );
00638 
00639     return dst;
00640 }
00641 
00642 #endif /* __TBB_machine_H */

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net