Skip to content

Commit 4bd8040

Browse files
committed
runtime, sync/atomic: add memory barriers in arm cas routines
This only triggers on ARMv7+. If there are important SMP ARMv6 machines we can reconsider. Makes TestLFStress tests pass and sync/atomic tests not time out on Apple iPad Mini 3. Fixes #7977. Fixes #10189. Change-Id: Ie424dea3765176a377d39746be9aa8265d11bec4 Reviewed-on: https://go-review.googlesource.com/12950 Reviewed-by: David Crawshaw <[email protected]>
1 parent 87fd98d commit 4bd8040

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

src/runtime/asm_arm.s

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,10 +713,22 @@ casl:
713713
LDREX (R1), R0
714714
CMP R0, R2
715715
BNE casfail
716+
717+
MOVB runtime·goarm(SB), R11
718+
CMP $7, R11
719+
BLT 2(PC)
720+
WORD $0xf57ff05a // dmb ishst
721+
716722
STREX R3, (R1), R0
717723
CMP $0, R0
718724
BNE casl
719725
MOVW $1, R0
726+
727+
MOVB runtime·goarm(SB), R11
728+
CMP $7, R11
729+
BLT 2(PC)
730+
WORD $0xf57ff05b // dmb ish
731+
720732
MOVB R0, ret+12(FP)
721733
RET
722734
casfail:

src/sync/atomic/asm_arm.s

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@
88

99
// ARM atomic operations, for use by asm_$(GOOS)_arm.s.
1010

11+
#define DMB_ISHST_7 \
12+
MOVB runtime·goarm(SB), R11; \
13+
CMP $7, R11; \
14+
BLT 2(PC); \
15+
WORD $0xf57ff05a // dmb ishst
16+
17+
#define DMB_ISH_7 \
18+
MOVB runtime·goarm(SB), R11; \
19+
CMP $7, R11; \
20+
BLT 2(PC); \
21+
WORD $0xf57ff05b // dmb ish
22+
1123
TEXT ·armCompareAndSwapUint32(SB),NOSPLIT,$0-13
1224
MOVW addr+0(FP), R1
1325
MOVW old+4(FP), R2
@@ -17,10 +29,12 @@ casloop:
1729
LDREX (R1), R0
1830
CMP R0, R2
1931
BNE casfail
32+
DMB_ISHST_7
2033
STREX R3, (R1), R0
2134
CMP $0, R0
2235
BNE casloop
2336
MOVW $1, R0
37+
DMB_ISH_7
2438
MOVBU R0, ret+12(FP)
2539
RET
2640
casfail:
@@ -46,10 +60,12 @@ cas64loop:
4660
BNE cas64fail
4761
CMP R3, R7
4862
BNE cas64fail
63+
DMB_ISHST_7
4964
STREXD R4, (R1), R0 // stores R4 and R5
5065
CMP $0, R0
5166
BNE cas64loop
5267
MOVW $1, R0
68+
DMB_ISH_7
5369
MOVBU R0, ret+20(FP)
5470
RET
5571
cas64fail:
@@ -64,9 +80,11 @@ addloop:
6480
// LDREX and STREX were introduced in ARMv6.
6581
LDREX (R1), R3
6682
ADD R2, R3
83+
DMB_ISHST_7
6784
STREX R3, (R1), R0
6885
CMP $0, R0
6986
BNE addloop
87+
DMB_ISH_7
7088
MOVW R3, ret+8(FP)
7189
RET
7290

@@ -84,9 +102,11 @@ add64loop:
84102
LDREXD (R1), R4 // loads R4 and R5
85103
ADD.S R2, R4
86104
ADC R3, R5
105+
DMB_ISHST_7
87106
STREXD R4, (R1), R0 // stores R4 and R5
88107
CMP $0, R0
89108
BNE add64loop
109+
DMB_ISH_7
90110
MOVW R4, retlo+12(FP)
91111
MOVW R5, rethi+16(FP)
92112
RET
@@ -97,9 +117,11 @@ TEXT ·armSwapUint32(SB),NOSPLIT,$0-12
97117
swaploop:
98118
// LDREX and STREX were introduced in ARMv6.
99119
LDREX (R1), R3
120+
DMB_ISHST_7
100121
STREX R2, (R1), R0
101122
CMP $0, R0
102123
BNE swaploop
124+
DMB_ISH_7
103125
MOVW R3, old+8(FP)
104126
RET
105127

@@ -115,9 +137,11 @@ TEXT ·armSwapUint64(SB),NOSPLIT,$0-20
115137
swap64loop:
116138
// LDREXD and STREXD were introduced in ARMv6k.
117139
LDREXD (R1), R4 // loads R4 and R5
140+
DMB_ISHST_7
118141
STREXD R2, (R1), R0 // stores R2 and R3
119142
CMP $0, R0
120143
BNE swap64loop
144+
DMB_ISH_7
121145
MOVW R4, oldlo+12(FP)
122146
MOVW R5, oldhi+16(FP)
123147
RET
@@ -131,9 +155,11 @@ TEXT ·armLoadUint64(SB),NOSPLIT,$0-12
131155
MOVW R2, (R2)
132156
load64loop:
133157
LDREXD (R1), R2 // loads R2 and R3
158+
DMB_ISHST_7
134159
STREXD R2, (R1), R0 // stores R2 and R3
135160
CMP $0, R0
136161
BNE load64loop
162+
DMB_ISH_7
137163
MOVW R2, vallo+4(FP)
138164
MOVW R3, valhi+8(FP)
139165
RET
@@ -149,9 +175,11 @@ TEXT ·armStoreUint64(SB),NOSPLIT,$0-12
149175
MOVW valhi+8(FP), R3
150176
store64loop:
151177
LDREXD (R1), R4 // loads R4 and R5
178+
DMB_ISHST_7
152179
STREXD R2, (R1), R0 // stores R2 and R3
153180
CMP $0, R0
154181
BNE store64loop
182+
DMB_ISH_7
155183
RET
156184

157185
// Check for broken 64-bit LDREXD as found in QEMU.

0 commit comments

Comments
 (0)