1
0
mirror of https://github.com/golang/go synced 2024-11-23 14:40:02 -07:00

cmd/compile, runtime/internal/atomic: add lwsync for false ppc64 cas

This CL changes ppc64 atomic compare-and-swap (cas). Before this CL,
if the cas failed--if the value in memory was not the value expected
by the cas call--the atomic function would not synchronize memory.

In the note code in runtime/lock_sema.go, used on BSD systems,
notesleep and notetsleep first try a cas on the key. If that cas fails,
something has already called notewakeup, and the sleep completes.
However, because the cas did not synchronize memory on failure,
this meant that notesleep/notetsleep could return to a core that was
unable to see the memory changes that the notewakeup was reporting.

Fixes #30189
Fixes #63384

Change-Id: I9b921de5c1c09b10a37df6b3206b9003c3f32986
Reviewed-on: https://go-review.googlesource.com/c/go/+/533118
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Paul Murphy <murp@ibm.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Ian Lance Taylor 2023-10-06 12:20:19 -07:00 committed by Gopher Robot
parent e7c142a19d
commit 655155d0a7
2 changed files with 15 additions and 11 deletions

View File

@ -347,9 +347,9 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
// BNE end
// STDCCC Rarg2, (Rarg0)
// BNE loop
// LWSYNC // Only for sequential consistency; not required in CasRel.
// MOVD $1, Rout
// end:
// LWSYNC // Only for sequential consistency; not required in CasRel.
ld := ppc64.ALDAR
st := ppc64.ASTDCCC
cmp := ppc64.ACMP
@ -402,22 +402,24 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p4 := s.Prog(ppc64.ABNE)
p4.To.Type = obj.TYPE_BRANCH
p4.To.SetTarget(p0)
// LWSYNC - Assuming shared data not write-through-required nor
// caching-inhibited. See Appendix B.2.1.1 in the ISA 2.07b.
// If the operation is a CAS-Release, then synchronization is not necessary.
if v.AuxInt != 0 {
plwsync2 := s.Prog(ppc64.ALWSYNC)
plwsync2.To.Type = obj.TYPE_NONE
}
// return value true
p5 := s.Prog(ppc64.AMOVD)
p5.From.Type = obj.TYPE_CONST
p5.From.Offset = 1
p5.To.Type = obj.TYPE_REG
p5.To.Reg = out
// done (label)
p6 := s.Prog(obj.ANOP)
p2.To.SetTarget(p6)
// LWSYNC - Assuming shared data not write-through-required nor
// caching-inhibited. See Appendix B.2.1.1 in the ISA 2.07b.
// If the operation is a CAS-Release, then synchronization is not necessary.
if v.AuxInt != 0 {
plwsync2 := s.Prog(ppc64.ALWSYNC)
plwsync2.To.Type = obj.TYPE_NONE
p2.To.SetTarget(plwsync2)
} else {
// done (label)
p6 := s.Prog(obj.ANOP)
p2.To.SetTarget(p6)
}
case ssa.OpPPC64LoweredPubBarrier:
// LWSYNC

View File

@ -101,6 +101,7 @@ cas_again:
MOVB R3, ret+16(FP)
RET
cas_fail:
LWSYNC
MOVB R0, ret+16(FP)
RET
@ -128,6 +129,7 @@ cas64_again:
MOVB R3, ret+24(FP)
RET
cas64_fail:
LWSYNC
MOVB R0, ret+24(FP)
RET