1 /*************************************************************************************************** 2 3 Zyan Core Library (Zyan-C) 4 5 Original Author : Florian Bernd 6 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in all 15 * copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 25 ***************************************************************************************************/ 26 27 #ifndef ZYCORE_ATOMIC_GNU_H 28 #define ZYCORE_ATOMIC_GNU_H 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #include <Zycore/Defines.h> 35 #include <Zycore/Types.h> 36 37 /* ============================================================================================== */ 38 /* Functions */ 39 /* ============================================================================================== */ 40 41 #if defined(ZYAN_CLANG) || defined(ZYAN_GCC) || defined(ZYAN_ICC) 42 43 /* ---------------------------------------------------------------------------------------------- */ 44 /* Pointer sized */ 45 /* ---------------------------------------------------------------------------------------------- */ 46 47 ZYAN_INLINE ZyanUPointer ZyanAtomicCompareExchange(ZyanAtomicPointer* destination, 48 ZyanUPointer comparand, ZyanUPointer value) 49 { 50 return (ZyanUPointer)(__sync_val_compare_and_swap( 51 &destination->value, (void*)comparand, (void*)value, &destination->value)); 52 } 53 54 ZYAN_INLINE ZyanUPointer ZyanAtomicIncrement(ZyanAtomicPointer* destination) 55 { 56 return (ZyanUPointer)(__sync_fetch_and_add(&destination->value, (void*)1, 57 &destination->value)) + 1; 58 } 59 60 ZYAN_INLINE ZyanUPointer ZyanAtomicDecrement(ZyanAtomicPointer* destination) 61 { 62 return (ZyanUPointer)(__sync_sub_and_fetch(&destination->value, (void*)1, &destination->value)); 63 } 64 65 /* ---------------------------------------------------------------------------------------------- */ 66 /* 32-bit */ 67 /* ---------------------------------------------------------------------------------------------- */ 68 69 ZYAN_INLINE ZyanU32 ZyanAtomicCompareExchange32(ZyanAtomic32* destination, 70 ZyanU32 comparand, ZyanU32 value) 71 { 72 return (ZyanU32)(__sync_val_compare_and_swap(&destination->value, comparand, value, 73 &destination->value)); 74 } 75 76 ZYAN_INLINE ZyanU32 ZyanAtomicIncrement32(ZyanAtomic32* destination) 77 { 78 return (ZyanU32)(__sync_fetch_and_add(&destination->value, 1, &destination->value)) + 1; 79 } 80 81 ZYAN_INLINE ZyanU32 ZyanAtomicDecrement32(ZyanAtomic32* destination) 82 { 83 return (ZyanU32)(__sync_sub_and_fetch(&destination->value, 1, &destination->value)); 84 } 85 86 /* ---------------------------------------------------------------------------------------------- */ 87 /* 64-bit */ 88 /* ---------------------------------------------------------------------------------------------- */ 89 90 ZYAN_INLINE ZyanU64 ZyanAtomicCompareExchange64(ZyanAtomic64* destination, 91 ZyanU64 comparand, ZyanU64 value) 92 { 93 return (ZyanU64)(__sync_val_compare_and_swap(&destination->value, comparand, value, 94 &destination->value)); 95 } 96 97 ZYAN_INLINE ZyanU64 ZyanAtomicIncrement64(ZyanAtomic64* destination) 98 { 99 return (ZyanU64)(__sync_fetch_and_add(&destination->value, 1, &destination->value)) + 1; 100 } 101 102 ZYAN_INLINE ZyanU64 ZyanAtomicDecrement64(ZyanAtomic64* destination) 103 { 104 return (ZyanU64)(__sync_sub_and_fetch(&destination->value, 1, &destination->value)); 105 } 106 107 /* ---------------------------------------------------------------------------------------------- */ 108 109 #endif 110 111 /* ============================================================================================== */ 112 113 #ifdef __cplusplus 114 } 115 #endif 116 117 #endif /* ZYCORE_ATOMIC_GNU_H */ 118