Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-24 09:17:09

0001 // Created on: 2007-09-04
0002 // Created by: Andrey BETENEV
0003 // Copyright (c) 2007-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 //! @file
0017 //! Implementation of some atomic operations (elementary operations
0018 //! with data that cannot be interrupted by parallel threads in the
0019 //! multithread process) on various platforms
0020 //!
0021 //! By the moment, only operations necessary for reference counter
0022 //! in Standard_Transient objects are implemented.
0023 //!
0024 //! This is preferred to use fixed size types "int32_t" / "int64_t" for
0025 //! correct function declarations however we leave "int" assuming it is 32bits for now.
0026 
0027 #ifndef _Standard_Atomic_HeaderFile
0028 #define _Standard_Atomic_HeaderFile
0029 
0030 #include <Standard_Macro.hxx>
0031 #include <atomic>
0032 
0033 //! Increments atomically integer variable pointed by theValue
0034 //! and returns resulting incremented value.
0035 Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
0036 inline int Standard_Atomic_Increment(volatile int* theValue);
0037 
0038 //! Decrements atomically integer variable pointed by theValue
0039 //! and returns resulting decremented value.
0040 Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
0041 inline int Standard_Atomic_Decrement(volatile int* theValue);
0042 
0043 //! Perform an atomic compare and swap.
0044 //! That is, if the current value of *theValue is theOldValue, then write theNewValue into
0045 //! *theValue.
0046 //! @param theValue    pointer to variable to modify
0047 //! @param theOldValue expected value to perform modification
0048 //! @param theNewValue new value to set in case if *theValue was equal to theOldValue
0049 //! @return TRUE if theNewValue has been set to *theValue
0050 Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
0051 inline bool Standard_Atomic_CompareAndSwap(volatile int* theValue,
0052                                            int           theOldValue,
0053                                            int           theNewValue);
0054 
0055 // Platform-dependent implementation
0056 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(__EMSCRIPTEN__)
0057 // gcc explicitly defines the macros __GCC_HAVE_SYNC_COMPARE_AND_SWAP_*
0058 // starting with version 4.4+, although built-in functions
0059 // are available since 4.1.x. However unless __GCC_HAVE_SYNC_COMPARE_AND_SWAP_*
0060 // are defined, linking may fail without specifying -march option when
0061 // building for 32bit architecture on 64bit (using -m32 option). To avoid
0062 // making -march mandatory, check for __GCC_HAVE_SYNC_COMPARE_AND_SWAP_* is
0063 // enforced.
0064 
0065 Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
0066 int Standard_Atomic_Increment(volatile int* theValue)
0067 {
0068   return __sync_add_and_fetch(theValue, 1);
0069 }
0070 
0071 Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
0072 int Standard_Atomic_Decrement(volatile int* theValue)
0073 {
0074   return __sync_sub_and_fetch(theValue, 1);
0075 }
0076 
0077 Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
0078 bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int theNewValue)
0079 {
0080   return __sync_val_compare_and_swap(theValue, theOldValue, theNewValue) == theOldValue;
0081 }
0082 
0083 #elif defined(_WIN32)
0084 extern "C"
0085 {
0086   long _InterlockedIncrement(volatile long* lpAddend);
0087   long _InterlockedDecrement(volatile long* lpAddend);
0088   long _InterlockedCompareExchange(long volatile* Destination, long Exchange, long Comparand);
0089 }
0090 
0091   #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
0092     // force intrinsic instead of WinAPI calls
0093     #pragma intrinsic(_InterlockedIncrement)
0094     #pragma intrinsic(_InterlockedDecrement)
0095     #pragma intrinsic(_InterlockedCompareExchange)
0096   #endif
0097 
0098 // WinAPI function or MSVC intrinsic
0099 // Note that we safely cast int* to long*, as they have same size and endian-ness
0100 
0101 Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
0102 int Standard_Atomic_Increment(volatile int* theValue)
0103 {
0104   return _InterlockedIncrement(reinterpret_cast<volatile long*>(theValue));
0105 }
0106 
0107 Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
0108 int Standard_Atomic_Decrement(volatile int* theValue)
0109 {
0110   return _InterlockedDecrement(reinterpret_cast<volatile long*>(theValue));
0111 }
0112 
0113 Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
0114 bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int theNewValue)
0115 {
0116   return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(theValue),
0117                                      theNewValue,
0118                                      theOldValue)
0119          == theOldValue;
0120 }
0121 
0122 #elif defined(__APPLE__)
0123   // use atomic operations provided by MacOS
0124 
0125   #include <libkern/OSAtomic.h>
0126 
0127 Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
0128 int Standard_Atomic_Increment(volatile int* theValue)
0129 {
0130   return OSAtomicIncrement32Barrier(theValue);
0131 }
0132 
0133 Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
0134 int Standard_Atomic_Decrement(volatile int* theValue)
0135 {
0136   return OSAtomicDecrement32Barrier(theValue);
0137 }
0138 
0139 Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
0140 bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int theNewValue)
0141 {
0142   return OSAtomicCompareAndSwapInt(theOldValue, theNewValue, theValue);
0143 }
0144 
0145 #elif defined(__ANDROID__)
0146 
0147   // Atomic operations that were exported by the C library didn't
0148   // provide any memory barriers, which created potential issues on
0149   // multi-core devices. Starting from ndk version r7b they are defined as
0150   // inlined calls to GCC sync builtins, which always provide a full barrier.
0151   // It is strongly recommended to use newer versions of ndk.
0152   #include <sys/atomics.h>
0153 
0154 Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
0155 int Standard_Atomic_Increment(volatile int* theValue)
0156 {
0157   return __atomic_inc(theValue) + 1; // analog of __sync_fetch_and_add
0158 }
0159 
0160 Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
0161 int Standard_Atomic_Decrement(volatile int* theValue)
0162 {
0163   return __atomic_dec(theValue) - 1; // analog of __sync_fetch_and_sub
0164 }
0165 
0166 Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
0167 bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int theNewValue)
0168 {
0169   return __atomic_cmpxchg(theOldValue, theNewValue, theValue) == 0;
0170 }
0171 
0172 #else
0173 
0174   #ifndef IGNORE_NO_ATOMICS
0175     #error "Atomic operation isn't implemented for current platform!"
0176   #endif
0177 Standard_DEPRECATED("Standard_Atomic_Increment will be removed in OCCT 8.0.0")
0178 int Standard_Atomic_Increment(volatile int* theValue)
0179 {
0180   return ++(*theValue);
0181 }
0182 
0183 Standard_DEPRECATED("Standard_Atomic_Decrement will be removed in OCCT 8.0.0")
0184 int Standard_Atomic_Decrement(volatile int* theValue)
0185 {
0186   return --(*theValue);
0187 }
0188 
0189 Standard_DEPRECATED("Standard_Atomic_CompareAndSwap will be removed in OCCT 8.0.0")
0190 bool Standard_Atomic_CompareAndSwap(volatile int* theValue, int theOldValue, int theNewValue)
0191 {
0192   if (*theValue == theOldValue)
0193   {
0194     *theValue = theNewValue;
0195     return true;
0196   }
0197   return false;
0198 }
0199 
0200 #endif
0201 
0202 #endif //_Standard_Atomic_HeaderFile