![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
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.