Updated Branches: refs/heads/master e551e1c2d -> 57a39fb6f
TS-1385: Attempt to fix 64-bit atomics on ARM. Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/57a39fb6 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/57a39fb6 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/57a39fb6 Branch: refs/heads/master Commit: 57a39fb6f297351cc6842096f3478dffd4d831c2 Parents: e551e1c Author: James Peach <[email protected]> Authored: Wed Aug 8 21:43:12 2012 -0700 Committer: James Peach <[email protected]> Committed: Wed Aug 8 21:44:11 2012 -0700 ---------------------------------------------------------------------- lib/ts/ink_atomic.h | 66 ++++++++++++++++++++++++++++++++++----------- 1 files changed, 50 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/57a39fb6/lib/ts/ink_atomic.h ---------------------------------------------------------------------- diff --git a/lib/ts/ink_atomic.h b/lib/ts/ink_atomic.h index effe64e..8c12cbb 100644 --- a/lib/ts/ink_atomic.h +++ b/lib/ts/ink_atomic.h @@ -123,14 +123,14 @@ ink_atomic_increment(volatile Type * mem, Amount count) { return __sync_fetch_and_add(mem, (Type)count); } -// Special hacks for ARM 32-bit +// Special hacks for ARM 32-bit that don't have 8-byte atomic operations. The usual symptom of this is the linker +// failing to find __sync_bool_compare_and_swap_8 and friends. #if defined(__arm__) && (SIZEOF_VOIDP == 4) extern ProcessMutex __global_death; -template<> -inline int64_t -ink_atomic_swap<int64_t>(pvint64 mem, int64_t value) { - int64_t old; +template <typename T> static inline T +ink_atomic_death_swap(volatile T * mem, T value) { + T old; ink_mutex_acquire(&__global_death); old = *mem; *mem = value; @@ -138,22 +138,20 @@ ink_atomic_swap<int64_t>(pvint64 mem, int64_t value) { return old; } -template<> -inline bool -ink_atomic_cas<int64_t>(pvint64 mem, int64_t old, int64_t new_value) { - int64_t curr; +template <typename T> static inline bool +ink_atomic_death_cas(volatile T * mem, T old, T new_value) { + T curr; ink_mutex_acquire(&__global_death); curr = *mem; - if(old == curr) *mem = new_value; + if (old == curr) *mem = new_value; ink_mutex_release(&__global_death); - if(old == curr) return 1; - return 0; + if (old == curr) return true; + return false; } -template<> -inline int64_t -ink_atomic_increment<int64_t>(pvint64 mem, int64_t value) { - int64_t curr; +template<typename T> static inline +ink_atomic_death_increment(volatile T * mem, T value) { + T curr; ink_mutex_acquire(&__global_death); curr = *mem; *mem = curr + value; @@ -161,6 +159,42 @@ ink_atomic_increment<int64_t>(pvint64 mem, int64_t value) { return curr + value; } +template<> +inline int64_t +ink_atomic_swap<int64_t>(volatile int64_t * mem, int64_t value) { + return ink_atomic_death_swap(mem, value); +} + +template<> +inline uint64_t +ink_atomic_swap<uint64_t>(volatile uint64_t * mem, uint64_t value) { + return ink_atomic_death_swap(mem, value); +} + +template<> +inline bool +ink_atomic_cas<int64_t>(volatile int64_t * mem, int64_t old, int64_t new_value) { + return ink_atomic_death_cas(mem, old, new_value); +} + +template<> +inline bool +ink_atomic_cas<uint64_t>(volatile uint64_t * mem, uint64_t old, uint64_t new_value) { + return ink_atomic_death_cas(mem, old, new_value); +} + +template<> +inline int64_t +ink_atomic_increment(volatile int64_t * mem, int64_t value) { + return ink_atomic_death_increment(mem, value); +} + +template<> +inline uint64_t +ink_atomic_increment(volatile uint64_t * mem, uint64_t value) { + return ink_atomic_death_increment(mem, value); +} + #endif /* not used for Intel Processors which have sequential(esque) consistency */
