mirror of
https://github.com/golang/go
synced 2024-11-23 18:10:04 -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:
parent
e7c142a19d
commit
655155d0a7
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user