Skip to content

Commit a977157

Browse files
author
Andrew Haley
committedJun 29, 2021
8261579: AArch64: Support for weaker memory ordering in Atomic
Reviewed-by: adinn, shade
1 parent ee1e202 commit a977157

File tree

6 files changed

+115
-5
lines changed

6 files changed

+115
-5
lines changed
 

‎src/hotspot/cpu/aarch64/atomic_aarch64.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,9 @@ extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_impl;
4545
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_1_relaxed_impl;
4646
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_4_relaxed_impl;
4747
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_relaxed_impl;
48+
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_4_release_impl;
49+
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_release_impl;
50+
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_4_seq_cst_impl;
51+
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_seq_cst_impl;
4852

4953
#endif // CPU_AARCH64_ATOMIC_AARCH64_HPP

‎src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -5956,6 +5956,10 @@ class StubGenerator: public StubCodeGenerator {
59565956
acquire = false;
59575957
release = false;
59585958
break;
5959+
case memory_order_release:
5960+
acquire = false;
5961+
release = true;
5962+
break;
59595963
default:
59605964
acquire = true;
59615965
release = true;
@@ -6037,6 +6041,20 @@ class StubGenerator: public StubCodeGenerator {
60376041
(_masm, &aarch64_atomic_cmpxchg_8_relaxed_impl);
60386042
gen_cas_entry(MacroAssembler::xword, memory_order_relaxed);
60396043

6044+
AtomicStubMark mark_cmpxchg_4_release
6045+
(_masm, &aarch64_atomic_cmpxchg_4_release_impl);
6046+
gen_cas_entry(MacroAssembler::word, memory_order_release);
6047+
AtomicStubMark mark_cmpxchg_8_release
6048+
(_masm, &aarch64_atomic_cmpxchg_8_release_impl);
6049+
gen_cas_entry(MacroAssembler::xword, memory_order_release);
6050+
6051+
AtomicStubMark mark_cmpxchg_4_seq_cst
6052+
(_masm, &aarch64_atomic_cmpxchg_4_seq_cst_impl);
6053+
gen_cas_entry(MacroAssembler::word, memory_order_seq_cst);
6054+
AtomicStubMark mark_cmpxchg_8_seq_cst
6055+
(_masm, &aarch64_atomic_cmpxchg_8_seq_cst_impl);
6056+
gen_cas_entry(MacroAssembler::xword, memory_order_seq_cst);
6057+
60406058
ICache::invalidate_range(first_entry, __ pc() - first_entry);
60416059
}
60426060
#endif // LINUX
@@ -7203,6 +7221,10 @@ DEFAULT_ATOMIC_OP(cmpxchg, 8, )
72037221
DEFAULT_ATOMIC_OP(cmpxchg, 1, _relaxed)
72047222
DEFAULT_ATOMIC_OP(cmpxchg, 4, _relaxed)
72057223
DEFAULT_ATOMIC_OP(cmpxchg, 8, _relaxed)
7224+
DEFAULT_ATOMIC_OP(cmpxchg, 4, _release)
7225+
DEFAULT_ATOMIC_OP(cmpxchg, 8, _release)
7226+
DEFAULT_ATOMIC_OP(cmpxchg, 4, _seq_cst)
7227+
DEFAULT_ATOMIC_OP(cmpxchg, 8, _seq_cst)
72067228

72077229
#undef DEFAULT_ATOMIC_OP
72087230

‎src/hotspot/os_cpu/bsd_aarch64/atomic_bsd_aarch64.hpp

+29-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#ifndef OS_CPU_BSD_AARCH64_ATOMIC_BSD_AARCH64_HPP
2828
#define OS_CPU_BSD_AARCH64_ATOMIC_BSD_AARCH64_HPP
2929

30+
#include "utilities/debug.hpp"
31+
3032
// Implementation of class atomic
3133
// Note that memory_order_conservative requires a full barrier after atomic stores.
3234
// See https://patchwork.kernel.org/patch/3575821/
@@ -64,17 +66,40 @@ inline T Atomic::PlatformCmpxchg<byte_size>::operator()(T volatile* dest,
6466
T exchange_value,
6567
atomic_memory_order order) const {
6668
STATIC_ASSERT(byte_size == sizeof(T));
67-
if (order == memory_order_relaxed) {
69+
if (order == memory_order_conservative) {
6870
T value = compare_value;
71+
FULL_MEM_BARRIER;
6972
__atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false,
7073
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
74+
FULL_MEM_BARRIER;
7175
return value;
7276
} else {
77+
STATIC_ASSERT (
78+
// The modes that align with C++11 are intended to
79+
// follow the same semantics.
80+
memory_order_relaxed == __ATOMIC_RELAXED &&
81+
memory_order_acquire == __ATOMIC_ACQUIRE &&
82+
memory_order_release == __ATOMIC_RELEASE &&
83+
memory_order_acq_rel == __ATOMIC_ACQ_REL &&
84+
memory_order_seq_cst == __ATOMIC_SEQ_CST);
85+
86+
// Some sanity checking on the memory order. It makes no
87+
// sense to have a release operation for a store that never
88+
// happens.
89+
int failure_memory_order;
90+
switch (order) {
91+
case memory_order_release:
92+
failure_memory_order = memory_order_relaxed; break;
93+
case memory_order_acq_rel:
94+
failure_memory_order = memory_order_acquire; break;
95+
default:
96+
failure_memory_order = order;
97+
}
98+
assert(failure_memory_order <= order, "must be");
99+
73100
T value = compare_value;
74-
FULL_MEM_BARRIER;
75101
__atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false,
76-
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
77-
FULL_MEM_BARRIER;
102+
order, failure_memory_order);
78103
return value;
79104
}
80105
}

‎src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S

+49-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,55 @@ aarch64_atomic_cmpxchg_8_default_impl:
112112
dmb ish
113113
ret
114114

115-
.globl aarch64_atomic_cmpxchg_1_relaxed_default_impl
115+
.globl aarch64_atomic_cmpxchg_4_release_default_impl
116+
.align 5
117+
aarch64_atomic_cmpxchg_4_release_default_impl:
118+
prfm pstl1strm, [x0]
119+
0: ldxr w3, [x0]
120+
cmp w3, w1
121+
b.ne 1f
122+
stlxr w8, w2, [x0]
123+
cbnz w8, 0b
124+
1: mov w0, w3
125+
ret
126+
127+
.globl aarch64_atomic_cmpxchg_8_release_default_impl
128+
.align 5
129+
aarch64_atomic_cmpxchg_8_release_default_impl:
130+
prfm pstl1strm, [x0]
131+
0: ldxr x3, [x0]
132+
cmp x3, x1
133+
b.ne 1f
134+
stlxr w8, x2, [x0]
135+
cbnz w8, 0b
136+
1: mov x0, x3
137+
ret
138+
139+
.globl aarch64_atomic_cmpxchg_4_seq_cst_default_impl
140+
.align 5
141+
aarch64_atomic_cmpxchg_4_seq_cst_default_impl:
142+
prfm pstl1strm, [x0]
143+
0: ldaxr w3, [x0]
144+
cmp w3, w1
145+
b.ne 1f
146+
stlxr w8, w2, [x0]
147+
cbnz w8, 0b
148+
1: mov w0, w3
149+
ret
150+
151+
.globl aarch64_atomic_cmpxchg_8_seq_cst_default_impl
152+
.align 5
153+
aarch64_atomic_cmpxchg_8_seq_cst_default_impl:
154+
prfm pstl1strm, [x0]
155+
0: ldaxr x3, [x0]
156+
cmp x3, x1
157+
b.ne 1f
158+
stlxr w8, x2, [x0]
159+
cbnz w8, 0b
160+
1: mov x0, x3
161+
ret
162+
163+
.globl aarch64_atomic_cmpxchg_1_relaxed_default_impl
116164
.align 5
117165
aarch64_atomic_cmpxchg_1_relaxed_default_impl:
118166
prfm pstl1strm, [x0]

‎src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp

+10
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ inline T Atomic::PlatformCmpxchg<4>::operator()(T volatile* dest,
151151
switch (order) {
152152
case memory_order_relaxed:
153153
stub = aarch64_atomic_cmpxchg_4_relaxed_impl; break;
154+
case memory_order_release:
155+
stub = aarch64_atomic_cmpxchg_4_release_impl; break;
156+
case memory_order_acq_rel:
157+
case memory_order_seq_cst:
158+
stub = aarch64_atomic_cmpxchg_4_seq_cst_impl; break;
154159
default:
155160
stub = aarch64_atomic_cmpxchg_4_impl; break;
156161
}
@@ -169,6 +174,11 @@ inline T Atomic::PlatformCmpxchg<8>::operator()(T volatile* dest,
169174
switch (order) {
170175
case memory_order_relaxed:
171176
stub = aarch64_atomic_cmpxchg_8_relaxed_impl; break;
177+
case memory_order_release:
178+
stub = aarch64_atomic_cmpxchg_8_release_impl; break;
179+
case memory_order_acq_rel:
180+
case memory_order_seq_cst:
181+
stub = aarch64_atomic_cmpxchg_8_seq_cst_impl; break;
172182
default:
173183
stub = aarch64_atomic_cmpxchg_8_impl; break;
174184
}

‎src/hotspot/share/runtime/atomic.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ enum atomic_memory_order {
4747
memory_order_acquire = 2,
4848
memory_order_release = 3,
4949
memory_order_acq_rel = 4,
50+
memory_order_seq_cst = 5,
5051
// Strong two-way memory barrier.
5152
memory_order_conservative = 8
5253
};

0 commit comments

Comments
 (0)
Please sign in to comment.