Closed haruyama480 closed 6 months ago
sync/atomic uses AArch64's STLR* instructions. https://github.com/golang/go/blob/ac174400f460e9b577079e8606439e0bae62adb0/src/internal/runtime/atomic/atomic_arm64.s#L105-L121
But, arm's hardware memory model allows memory accesses to different addresses to be "Re-order"ed. https://developer.arm.com/documentation/102376/0100/Normal-memory
r1 == 0 && r2 == 1
isn't this simply: W1, (the two store ops), W2
W1, (the two store ops), W2
Sorry, I don't understand. Could you give me some details?
(I added "R1" and "R2" for convention)
Sorry, I get it.
You meant R1, W1, W2, R2.
I fixed my code, and confirmed the test works.
- r1 := atomic.LoadInt32(&x)
- r2 := atomic.LoadInt32(&y)
- if r1 == 0 && r2 == 1 {
+ r1 := atomic.LoadInt32(&y)
+ r2 := atomic.LoadInt32(&x)
+ if r1 == 1 && r2 == 0 {
Thank you for comments!
(Though I'm curious there are correct ordering with arm's STLR/LDAR instructions, I will study it. )
In my macOS, TSO mode is enabled. So, If I turn it off or use another arm, fixed test may fail possibly.
% sysctl net.inet.tcp.tso
net.inet.tcp.tso: 1
Go version
go version go1.22.2 darwin/arm64
Output of
go env
in your module/workspace:What did you do?
sample
What did you see happen?
r1 == 0 && r2 == 1 was observed.
https://pkg.go.dev/sync/atomic says,
but, it seems to be false.
What did you expect to see?
If W1 synchronized before W2, r1 == 0 && r2 == 1 should not be observed.