1 #ifndef _DEATOMIC_H 2 #define _DEATOMIC_H 3 /*------------------------------------------------------------------------- 4 * drawElements Thread Library 5 * --------------------------- 6 * 7 * Copyright 2014 The Android Open Source Project 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Atomic operations. 24 *//*--------------------------------------------------------------------*/ 25 26 #include "deDefs.h" 27 28 #if (DE_COMPILER == DE_COMPILER_MSC) 29 # include <intrin.h> 30 #endif 31 32 DE_BEGIN_EXTERN_C 33 34 /*--------------------------------------------------------------------*//*! 35 * \brief Atomic increment and fetch. 36 * \param dstAddr Destination address. 37 * \return Incremented value. 38 *//*--------------------------------------------------------------------*/ 39 DE_INLINE deInt32 deAtomicIncrement32 (deInt32 volatile* dstAddr) 40 { 41 #if (DE_COMPILER == DE_COMPILER_MSC) 42 return _InterlockedIncrement((long volatile*)dstAddr); 43 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG) 44 return __sync_add_and_fetch(dstAddr, 1); 45 #else 46 # error "Implement deAtomicIncrement32()" 47 #endif 48 } 49 50 /*--------------------------------------------------------------------*//*! 51 * \brief Atomic decrement and fetch. 52 * \param dstAddr Destination address. 53 * \return Decremented value. 54 *//*--------------------------------------------------------------------*/ 55 DE_INLINE deInt32 deAtomicDecrement32 (deInt32 volatile* dstAddr) 56 { 57 #if (DE_COMPILER == DE_COMPILER_MSC) 58 return _InterlockedDecrement((long volatile*)dstAddr); 59 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG) 60 return __sync_sub_and_fetch(dstAddr, 1); 61 #else 62 # error "Implement deAtomicDecrement32()" 63 #endif 64 } 65 66 /*--------------------------------------------------------------------*//*! 67 * \brief Atomic compare and exchange (CAS). 68 * \param dstAddr Destination address. 69 * \param compare Old value. 70 * \param exchange New value. 71 * \return compare value if CAS passes, *dstAddr value otherwise 72 * 73 * Performs standard Compare-And-Swap with 32b data. Dst value is compared 74 * to compare value and if that comparison passes, value is replaced with 75 * exchange value. 76 * 77 * If CAS succeeds, compare value is returned. Otherwise value stored in 78 * dstAddr is returned. 79 *//*--------------------------------------------------------------------*/ 80 DE_INLINE deUint32 deAtomicCompareExchange32 (deUint32 volatile* dstAddr, deUint32 compare, deUint32 exchange) 81 { 82 #if (DE_COMPILER == DE_COMPILER_MSC) 83 return _InterlockedCompareExchange((long volatile*)dstAddr, exchange, compare); 84 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG) 85 return __sync_val_compare_and_swap(dstAddr, compare, exchange); 86 #else 87 # error "Implement deAtomicCompareExchange32()" 88 #endif 89 } 90 91 /*--------------------------------------------------------------------*//*! 92 * \brief Issue hardware memory read-write fence. 93 *//*--------------------------------------------------------------------*/ 94 #if (DE_COMPILER == DE_COMPILER_MSC) 95 void deMemoryReadWriteFence (void); 96 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG) 97 DE_INLINE void deMemoryReadWriteFence (void) 98 { 99 __sync_synchronize(); 100 } 101 #else 102 # error "Implement deMemoryReadWriteFence()" 103 #endif 104 105 DE_END_EXTERN_C 106 107 #endif /* _DEATOMIC_H */ 108