00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _SUPPORT_ATOMIC_H
00014 #define _SUPPORT_ATOMIC_H
00015
00021 #include <support/SupportDefs.h>
00022
00023 #include <SysThread.h>
00024
00025 #ifdef __cplusplus
00026
00028
00029 struct SAtomicInt32
00030 {
00031 public:
00032 inline int32_t Value() const;
00033 inline void SetTo(int32_t newVal);
00034
00035 inline int32_t Add(int32_t amount);
00036 inline bool Swap(int32_t oldVal, int32_t newVal);
00037
00038 inline uint32_t Or(uint32_t bits);
00039 inline uint32_t And(uint32_t bits);
00040
00041 private:
00042 volatile int32_t m_value;
00043 };
00044
00045 extern "C" {
00046
00047 #endif // __cplusplus
00048
00049
00050 uint32_t SysAtomicCompareAndSwap64(uint64_t volatile *ioOperandP, uint64_t iOldValue, uint64_t iNewValue);
00051
00052
00053
00054
00055 extern void _IMPEXP_SUPPORT SysCriticalSectionEnter(SysCriticalSectionType *iCS);
00056 extern void _IMPEXP_SUPPORT SysCriticalSectionExit(SysCriticalSectionType *iCS);
00057
00058
00059
00060
00061 extern void _IMPEXP_SUPPORT SysConditionVariableWait(SysConditionVariableType *iCV, SysCriticalSectionType *iOptionalCS);
00062 extern void _IMPEXP_SUPPORT SysConditionVariableOpen(SysConditionVariableType *iCV);
00063 extern void _IMPEXP_SUPPORT SysConditionVariableClose(SysConditionVariableType *iCV);
00064 extern void _IMPEXP_SUPPORT SysConditionVariableBroadcast(SysConditionVariableType *iCV);
00065
00066 extern int32_t _IMPEXP_SUPPORT atomic_add(volatile int32_t *value, int32_t addvalue);
00067 extern int32_t _IMPEXP_SUPPORT atomic_and(volatile int32_t *value, int32_t andvalue);
00068 extern int32_t _IMPEXP_SUPPORT atomic_or(volatile int32_t *value, int32_t orvalue);
00069 extern int32_t _IMPEXP_SUPPORT compare_and_swap32(volatile int32_t *location, int32_t oldValue, int32_t newValue);
00070 extern int32_t _IMPEXP_SUPPORT compare_and_swap64(volatile int64_t *location, int64_t oldValue, int64_t newValue);
00071
00072 #if TARGET_HOST == TARGET_HOST_WIN32
00073
00074
00075
00076 inline int32_t SysAtomicAdd32(int32_t volatile* ioOperandP, int32_t iAddend)
00077 { return (int32_t)atomic_add((int32_t volatile*)ioOperandP, (int32_t)iAddend); }
00078 inline uint32_t SysAtomicAnd32(uint32_t volatile* ioOperandP, uint32_t iValue)
00079 { return (uint32_t)atomic_and((int32_t volatile*)ioOperandP, (int32_t)iValue); }
00080 inline uint32_t SysAtomicOr32(uint32_t volatile* ioOperandP, uint32_t iValue)
00081 { return (uint32_t)atomic_or((int32_t volatile*)ioOperandP, (int32_t)iValue); }
00082 inline uint32_t SysAtomicCompareAndSwap32(uint32_t volatile* ioOperandP, uint32_t iOldValue, uint32_t iNewValue)
00083 { return (uint32_t)!compare_and_swap32((int32_t volatile*)ioOperandP, (int32_t)iOldValue, (int32_t)iNewValue); }
00084 inline uint32_t SysAtomicCompareAndSwap64(uint64_t volatile* ioOperandP, uint64_t iOldValue, uint64_t iNewValue)
00085 { return (uint32_t)!compare_and_swap64((int64_t volatile*)ioOperandP, (int64_t)iOldValue, (int64_t)iNewValue); }
00086
00087 #endif // #if TARGET_HOST == TARGET_HOST_WIN32
00088
00090
00095 INLINE_FNC int cmpxchg32(volatile int32_t *atom, int32_t *value, int32_t newValue)
00096 {
00097 if (SysAtomicCompareAndSwap32((volatile uint32_t*)atom, *value, newValue)) {
00098
00099 *value = *atom;
00100 return FALSE;
00101 }
00102
00103 return TRUE;
00104 }
00105
00107
00112 INLINE_FNC int cmpxchg64(volatile int64_t *atom, int64_t *value, int64_t newValue)
00113 {
00114 int32_t success = compare_and_swap64(atom, *value, newValue);
00115 if (!success)
00116 *value = *atom;
00117
00118 return success ? TRUE : FALSE;
00119 }
00120
00121
00122
00123
00124 #ifdef __cplusplus
00125 }
00126
00127 inline int32_t SAtomicInt32::Value() const
00128 {
00129 return m_value;
00130 }
00131
00132 inline void SAtomicInt32::SetTo(int32_t newVal)
00133 {
00134 m_value = newVal;
00135 }
00136
00137 inline int32_t SAtomicInt32::Add(int32_t amount)
00138 {
00139 return SysAtomicAdd32(&m_value, amount);
00140 }
00141
00142 inline bool SAtomicInt32::Swap(int32_t oldVal, int32_t newVal)
00143 {
00144 return SysAtomicCompareAndSwap32((volatile uint32_t*)&m_value, oldVal, newVal) == 0;
00145 }
00146
00147 inline uint32_t SAtomicInt32::Or(uint32_t bits)
00148 {
00149 return SysAtomicOr32((volatile uint32_t*)&m_value, bits);
00150 }
00151
00152 inline uint32_t SAtomicInt32::And(uint32_t bits)
00153 {
00154 return SysAtomicAnd32((volatile uint32_t*)&m_value, bits);
00155 }
00156
00157 #endif // __cplusplus
00158
00159 #endif