7 #ifndef _TAGGED_PTR_CLASS_HEADER_
8 #define _TAGGED_PTR_CLASS_HEADER_
11 #define A_UTILS_HAS_ATOMIC_OPERATORS
13 #pragma intrinsic (_InterlockedCompareExchange)
14 #pragma intrinsic (_InterlockedCompareExchange64)
15 #pragma intrinsic (_ReadWriteBarrier)
17 #if defined(__i386) || defined(__x86_64)
18 #define A_UTILS_HAS_ATOMIC_OPERATORS
31 template <
class BasicType>
32 inline tBool atomic_compare_exchange(
volatile BasicType* pAddress,
const BasicType& nNewValue,
const BasicType& nExpectedValue)
34 BasicType nResult = _InterlockedCompareExchange((
long*)pAddress, nNewValue, nExpectedValue);
35 return (nResult == nExpectedValue);
41 inline tBool atomic_compare_exchange<tUInt64>(
volatile tUInt64* pAddress,
const tUInt64& nNewValue,
const tUInt64& nExpectedValue)
43 tUInt64 nResult = _InterlockedCompareExchange64((
tInt64*)pAddress, nNewValue, nExpectedValue);
44 return (nResult == nExpectedValue);
50 template <
class BasicType>
51 inline tBool atomic_compare_exchange(
volatile BasicType* pAddress,
const BasicType& nNewValue,
const BasicType& nExpectedValue)
53 return __sync_bool_compare_and_swap(pAddress, nExpectedValue, nNewValue);
72 #if defined(__GNUC__) && ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && \
73 (__GNUC_MINOR__ >= 1)))
75 #elif defined(__GNUC__) && defined (__i386__)
76 asm volatile(
"lock; addl $0,0(%%esp)":::
"memory");
78 # warning "no memory barrier implemented for this platform"
85 #if (defined(WIN32) && !defined(WIN64)) || \
86 defined(A_UTILS_FORCE_TAGGED_POINTER_USE) || \
88 (defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)) || \
89 (!defined(__x86_64__) && \
91 (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) && !defined(A_UTILS_FORCE_NO_TAGGED_POINTER_USE)) || \
92 (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 1))) && !defined(A_UTILS_FORCE_NO_TAGGED_POINTER_USE)) \
98 #define A_UTILS_CAS_ALIGNMENT __declspec(align(8))
101 #define A_UTILS_CAS_ALIGNMENT __attribute__((aligned(16)))
103 #define A_UTILS_CAS_ALIGNMENT __attribute__((aligned(8)))
113 #define A_UTILS_TAGGED_POINTER_AVALIABLE
129 class A_UTILS_CAS_ALIGNMENT tagged_ptr
133 typedef int tCompareAndSwapType __attribute__ ((mode (TI)));
136 typedef tUInt64 tCompareAndSwapType;
145 tagged_ptr(): m_pPtr(nullptr), m_nTag(0)
153 tagged_ptr(tagged_ptr
const& oPtr)
163 explicit tagged_ptr(T* pPtr, tTag nTag = 0): m_pPtr(pPtr), m_nTag(nTag)
171 void operator=(tagged_ptr
const& oPtr)
181 void Set(tagged_ptr
const& oPtr)
183 m_pPtr = oPtr.m_pPtr;
184 m_nTag = oPtr.m_nTag;
193 void Set(T* pPtr, tTag nTag = 0)
204 bool operator== (tagged_ptr
const& oPtr)
const
206 return (m_pPtr == oPtr.m_pPtr) && (m_nTag == oPtr.m_nTag);
214 bool operator!= (tagged_ptr
const& oPtr)
const
243 tBool CompareAndSwap(tagged_ptr
const& oOldVal, T* pNewPtr)
245 return CompareAndSwap(oOldVal, pNewPtr, oOldVal.m_nTag + 1);
255 tBool CompareAndSwap(tagged_ptr
const& oOldVal, T* pNewPtr, tTag nTag)
257 tagged_ptr oNewVal(pNewPtr, nTag);
258 return atomic_compare_exchange<tCompareAndSwapType>((tCompareAndSwapType*)
this, *(tCompareAndSwapType*) &oNewVal, *(tCompareAndSwapType*) &oOldVal);
265 T* operator->()
const
274 operator bool(
void)
const
276 return m_pPtr !=
nullptr;
280 #elif (defined(__x86_64__) \
281 && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) \
282 && !defined(A_UTILS_FORCE_NO_TAGGED_POINTER_USE) \
284 || defined(__ARM_ARCH_8A))
290 #define A_UTILS_CAS_ALIGNMENT __declspec(align(8))
292 #define A_UTILS_CAS_ALIGNMENT __attribute__((aligned(8)))
295 #define A_UTILS_TAGGED_POINTER_AVALIABLE
310 class A_UTILS_CAS_ALIGNMENT tagged_ptr
313 typedef tUInt64 tCompareAndSwapType;
319 tCompareAndSwapType nValue;
323 static const tInt s_nTagIndex = 3;
324 static const tCompareAndSwapType s_nPtrMask = 0xffffffffffff;
327 tCompressedPtr m_oPtr;
339 tagged_ptr(tagged_ptr
const& oPtr)
349 explicit tagged_ptr(T* pPtr, tTag nTag = 0)
358 void operator=(tagged_ptr
const& oPtr)
368 void Set(tagged_ptr
const& oPtr)
370 m_oPtr = oPtr.m_oPtr;
379 void Set(T* pPtr, tTag nTag = 0)
381 m_oPtr.nValue = tCompareAndSwapType(pPtr);
382 m_oPtr.nTag[s_nTagIndex] = nTag;
390 bool operator== (tagged_ptr
const& oPtr)
const
392 return m_oPtr.nValue == oPtr.m_oPtr.nValue;
400 bool operator!= (tagged_ptr
const& oPtr)
const
411 return (T*)(m_oPtr.nValue & s_nPtrMask);
420 return m_oPtr.nTag[s_nTagIndex];
429 tBool CompareAndSwap(tagged_ptr
const& oOldVal, T* pNewPtr)
431 return CompareAndSwap(oOldVal, pNewPtr, oOldVal.GetTag() + 1);
441 tBool CompareAndSwap(tagged_ptr
const& oOldVal, T* pNewPtr, tTag nTag)
443 tagged_ptr oNewVal(pNewPtr, nTag);
444 return atomic_compare_exchange<tCompareAndSwapType>((tCompareAndSwapType*)
this, *(tCompareAndSwapType*) &oNewVal, *(tCompareAndSwapType*) &oOldVal);
451 T* operator->()
const
460 operator bool(
void)
const
462 return GetPtr() !=
nullptr;
468 #warning "No required compare and swap operation avaliable. cLockFree* classes will use mutexes."
int64_t tInt64
type definition for signed integer values (64bit) (platform and compiler independent type).
int32_t tInt32
type definition for signed integer values (32bit) (platform and compiler independent type).
void tVoid
The tVoid is always the definition for the void (non-type).
uint16_t tUInt16
type definition for unsigned integer values (16bit) (platform and compiler independent type).
int tInt
type definition for signed integer value (platform and compiler dependent type).
bool tBool
The tBool defines the type for the Values tTrue and tFalse (platform and compiler dependent).
uint32_t tUInt32
type definition for unsigned integer values (32bit) (platform and compiler independent type).
uint64_t tUInt64
type definition for unsigned integer values (64bit) (platform and compiler independent type).
ADTF A_UTIL Namespace - Within adtf this is used as adtf::util or adtf_util.
tVoid memory_barrier()
This method will help ensure that all memory reads and writes will have been performed before this fu...
tBool operator==(const cMultiArrayIndex &o_A, const cMultiArrayIndex &o_B)
Comparison operator.
tBool operator!=(const cMultiArrayIndex &o_A, const cMultiArrayIndex &o_B)
Comparison operator.