57 STATIC_ASSERT(4 == sizeof(D)); 58 return PrimitiveConversions::cast<D>( 59 _Atomic_add(PrimitiveConversions::cast<int32_t>(add_value), 60 reinterpret_cast<int32_t volatile*>(dest))); 61 } 62 63 // Not using add_using_helper; see comment for cmpxchg. 64 template<> 65 template<typename D, typename I> 66 inline D Atomic::PlatformAdd<8>::add_and_fetch(D volatile* dest, I add_value, 67 atomic_memory_order order) const { 68 STATIC_ASSERT(8 == sizeof(I)); 69 STATIC_ASSERT(8 == sizeof(D)); 70 return PrimitiveConversions::cast<D>( 71 _Atomic_add_long(PrimitiveConversions::cast<int64_t>(add_value), 72 reinterpret_cast<int64_t volatile*>(dest))); 73 } 74 75 template<> 76 template<typename T> 77 inline T Atomic::PlatformXchg<4>::operator()(T exchange_value, 78 T volatile* dest, 79 atomic_memory_order order) const { 80 STATIC_ASSERT(4 == sizeof(T)); 81 return PrimitiveConversions::cast<T>( 82 _Atomic_xchg(PrimitiveConversions::cast<int32_t>(exchange_value), 83 reinterpret_cast<int32_t volatile*>(dest))); 84 } 85 86 extern "C" int64_t _Atomic_xchg_long(int64_t exchange_value, volatile int64_t* dest); 87 88 template<> 89 template<typename T> 90 inline T Atomic::PlatformXchg<8>::operator()(T exchange_value, 91 T volatile* dest, 92 atomic_memory_order order) const { 93 STATIC_ASSERT(8 == sizeof(T)); 94 return PrimitiveConversions::cast<T>( 95 _Atomic_xchg_long(PrimitiveConversions::cast<int64_t>(exchange_value), 96 reinterpret_cast<int64_t volatile*>(dest))); 97 } 98 99 // Not using cmpxchg_using_helper here, because some configurations of 100 // Solaris compiler don't deal well with passing a "defined in .il" 101 // function as an argument. We *should* switch to using gcc-style 102 // inline assembly, but attempting to do so with Studio 12.4 ran into 103 // segfaults. 104 105 template<> 106 template<typename T> 107 inline T Atomic::PlatformCmpxchg<1>::operator()(T exchange_value, 108 T volatile* dest, 109 T compare_value, 110 atomic_memory_order order) const { 111 STATIC_ASSERT(1 == sizeof(T)); | 57 STATIC_ASSERT(4 == sizeof(D)); 58 return PrimitiveConversions::cast<D>( 59 _Atomic_add(PrimitiveConversions::cast<int32_t>(add_value), 60 reinterpret_cast<int32_t volatile*>(dest))); 61 } 62 63 // Not using add_using_helper; see comment for cmpxchg. 64 template<> 65 template<typename D, typename I> 66 inline D Atomic::PlatformAdd<8>::add_and_fetch(D volatile* dest, I add_value, 67 atomic_memory_order order) const { 68 STATIC_ASSERT(8 == sizeof(I)); 69 STATIC_ASSERT(8 == sizeof(D)); 70 return PrimitiveConversions::cast<D>( 71 _Atomic_add_long(PrimitiveConversions::cast<int64_t>(add_value), 72 reinterpret_cast<int64_t volatile*>(dest))); 73 } 74 75 template<> 76 template<typename T> 77 inline T Atomic::PlatformXchg<4>::operator()(T volatile* dest, 78 T exchange_value, 79 atomic_memory_order order) const { 80 STATIC_ASSERT(4 == sizeof(T)); 81 return PrimitiveConversions::cast<T>( 82 _Atomic_xchg(PrimitiveConversions::cast<int32_t>(exchange_value), 83 reinterpret_cast<int32_t volatile*>(dest))); 84 } 85 86 extern "C" int64_t _Atomic_xchg_long(int64_t exchange_value, volatile int64_t* dest); 87 88 template<> 89 template<typename T> 90 inline T Atomic::PlatformXchg<8>::operator()(T volatile* dest, 91 T exchange_value, 92 atomic_memory_order order) const { 93 STATIC_ASSERT(8 == sizeof(T)); 94 return PrimitiveConversions::cast<T>( 95 _Atomic_xchg_long(PrimitiveConversions::cast<int64_t>(exchange_value), 96 reinterpret_cast<int64_t volatile*>(dest))); 97 } 98 99 // Not using cmpxchg_using_helper here, because some configurations of 100 // Solaris compiler don't deal well with passing a "defined in .il" 101 // function as an argument. We *should* switch to using gcc-style 102 // inline assembly, but attempting to do so with Studio 12.4 ran into 103 // segfaults. 104 105 template<> 106 template<typename T> 107 inline T Atomic::PlatformCmpxchg<1>::operator()(T exchange_value, 108 T volatile* dest, 109 T compare_value, 110 atomic_memory_order order) const { 111 STATIC_ASSERT(1 == sizeof(T)); |