equal
deleted
inserted
replaced
27 #define OS_CPU_LINUX_AARCH64_ATOMIC_LINUX_AARCH64_HPP |
27 #define OS_CPU_LINUX_AARCH64_ATOMIC_LINUX_AARCH64_HPP |
28 |
28 |
29 #include "vm_version_aarch64.hpp" |
29 #include "vm_version_aarch64.hpp" |
30 |
30 |
31 // Implementation of class atomic |
31 // Implementation of class atomic |
|
32 // Note that memory_order_conservative requires a full barrier after atomic stores. |
|
33 // See https://patchwork.kernel.org/patch/3575821/ |
32 |
34 |
33 #define FULL_MEM_BARRIER __sync_synchronize() |
35 #define FULL_MEM_BARRIER __sync_synchronize() |
34 #define READ_MEM_BARRIER __atomic_thread_fence(__ATOMIC_ACQUIRE); |
36 #define READ_MEM_BARRIER __atomic_thread_fence(__ATOMIC_ACQUIRE); |
35 #define WRITE_MEM_BARRIER __atomic_thread_fence(__ATOMIC_RELEASE); |
37 #define WRITE_MEM_BARRIER __atomic_thread_fence(__ATOMIC_RELEASE); |
36 |
38 |
50 template<typename T> |
52 template<typename T> |
51 inline T Atomic::PlatformXchg<byte_size>::operator()(T exchange_value, |
53 inline T Atomic::PlatformXchg<byte_size>::operator()(T exchange_value, |
52 T volatile* dest, |
54 T volatile* dest, |
53 atomic_memory_order order) const { |
55 atomic_memory_order order) const { |
54 STATIC_ASSERT(byte_size == sizeof(T)); |
56 STATIC_ASSERT(byte_size == sizeof(T)); |
55 T res = __sync_lock_test_and_set(dest, exchange_value); |
57 T res = __atomic_exchange_n(dest, exchange_value, __ATOMIC_RELEASE); |
56 FULL_MEM_BARRIER; |
58 FULL_MEM_BARRIER; |
57 return res; |
59 return res; |
58 } |
60 } |
59 |
61 |
60 template<size_t byte_size> |
62 template<size_t byte_size> |
68 T value = compare_value; |
70 T value = compare_value; |
69 __atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false, |
71 __atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false, |
70 __ATOMIC_RELAXED, __ATOMIC_RELAXED); |
72 __ATOMIC_RELAXED, __ATOMIC_RELAXED); |
71 return value; |
73 return value; |
72 } else { |
74 } else { |
73 return __sync_val_compare_and_swap(dest, compare_value, exchange_value); |
75 T value = compare_value; |
|
76 FULL_MEM_BARRIER; |
|
77 __atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false, |
|
78 __ATOMIC_RELAXED, __ATOMIC_RELAXED); |
|
79 FULL_MEM_BARRIER; |
|
80 return value; |
74 } |
81 } |
75 } |
82 } |
76 |
83 |
77 #endif // OS_CPU_LINUX_AARCH64_ATOMIC_LINUX_AARCH64_HPP |
84 #endif // OS_CPU_LINUX_AARCH64_ATOMIC_LINUX_AARCH64_HPP |