mirror of
https://github.com/golang/go
synced 2024-11-13 15:20:22 -07:00
sync/atomic: adjust for new runtime.cas64 prototype
R=golang-dev, minux.ma, josharian CC=golang-dev https://golang.org/cl/13859043
This commit is contained in:
parent
5639d2754b
commit
828a4b9376
@ -121,27 +121,32 @@ TEXT kernelCAS64<>(SB),NOSPLIT,$0-21
|
|||||||
MOVW R0, 20(FP)
|
MOVW R0, 20(FP)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT generalCAS64<>(SB),NOSPLIT,$20-21
|
TEXT ·generalCAS64(SB),NOSPLIT,$20-21
|
||||||
// bool runtime·cas64(uint64 volatile *addr, uint64 *old, uint64 new)
|
// bool runtime·cas64(uint64 volatile *addr, uint64 old, uint64 new)
|
||||||
MOVW addr+0(FP), R0
|
MOVW addr+0(FP), R0
|
||||||
|
// trigger potential paging fault here,
|
||||||
|
// because a fault in runtime.cas64 will hang.
|
||||||
|
MOVW (R0), R2
|
||||||
// make unaligned atomic access panic
|
// make unaligned atomic access panic
|
||||||
AND.S $7, R0, R1
|
AND.S $7, R0, R1
|
||||||
BEQ 2(PC)
|
BEQ 2(PC)
|
||||||
MOVW R1, (R1)
|
MOVW R1, (R1)
|
||||||
MOVW R0, 4(R13)
|
MOVW R0, 4(R13)
|
||||||
MOVW $4(FP), R1 // oldval
|
MOVW oldlo+4(FP), R1
|
||||||
MOVW R1, 8(R13)
|
MOVW R1, 8(R13)
|
||||||
|
MOVW oldhi+8(FP), R1
|
||||||
|
MOVW R1, 12(R13)
|
||||||
MOVW newlo+12(FP), R2
|
MOVW newlo+12(FP), R2
|
||||||
MOVW R2, 12(R13)
|
MOVW R2, 16(R13)
|
||||||
MOVW newhi+16(FP), R3
|
MOVW newhi+16(FP), R3
|
||||||
MOVW R3, 16(R13)
|
MOVW R3, 20(R13)
|
||||||
BL runtime·cas64(SB)
|
BL runtime·cas64(SB)
|
||||||
MOVW R0, 20(FP)
|
MOVB R0, ret+20(FP)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
GLOBL armCAS64(SB), $4
|
GLOBL armCAS64(SB), $4
|
||||||
|
|
||||||
TEXT setupAndCallCAS64<>(SB),NOSPLIT,$-21
|
TEXT setupAndCallCAS64<>(SB),NOSPLIT,$-4-21
|
||||||
MOVW $0xffff0ffc, R0 // __kuser_helper_version
|
MOVW $0xffff0ffc, R0 // __kuser_helper_version
|
||||||
MOVW (R0), R0
|
MOVW (R0), R0
|
||||||
// __kuser_cmpxchg64 only present if helper version >= 5
|
// __kuser_cmpxchg64 only present if helper version >= 5
|
||||||
@ -156,14 +161,14 @@ TEXT setupAndCallCAS64<>(SB),NOSPLIT,$-21
|
|||||||
MOVW.CS R1, armCAS64(SB)
|
MOVW.CS R1, armCAS64(SB)
|
||||||
MOVW.CS R1, PC
|
MOVW.CS R1, PC
|
||||||
// we are out of luck, can only use runtime's emulated 64-bit cas
|
// we are out of luck, can only use runtime's emulated 64-bit cas
|
||||||
MOVW $generalCAS64<>(SB), R1
|
MOVW $·generalCAS64(SB), R1
|
||||||
MOVW R1, armCAS64(SB)
|
MOVW R1, armCAS64(SB)
|
||||||
MOVW R1, PC
|
MOVW R1, PC
|
||||||
|
|
||||||
TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
|
TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
|
||||||
B ·CompareAndSwapUint64(SB)
|
B ·CompareAndSwapUint64(SB)
|
||||||
|
|
||||||
TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-21
|
TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4-21
|
||||||
MOVW armCAS64(SB), R0
|
MOVW armCAS64(SB), R0
|
||||||
CMP $0, R0
|
CMP $0, R0
|
||||||
MOVW.NE R0, PC
|
MOVW.NE R0, PC
|
||||||
|
14
src/pkg/sync/atomic/atomic_linux_arm_test.go
Normal file
14
src/pkg/sync/atomic/atomic_linux_arm_test.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package atomic_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "sync/atomic"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGeneralCAS64(t *testing.T) {
|
||||||
|
testCompareAndSwapUint64(t, GeneralCAS64)
|
||||||
|
}
|
@ -379,7 +379,7 @@ func TestCompareAndSwapInt64(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompareAndSwapUint64(t *testing.T) {
|
func testCompareAndSwapUint64(t *testing.T, cas func(*uint64, uint64, uint64) bool) {
|
||||||
if test64err != nil {
|
if test64err != nil {
|
||||||
t.Skipf("Skipping 64-bit tests: %v", test64err)
|
t.Skipf("Skipping 64-bit tests: %v", test64err)
|
||||||
}
|
}
|
||||||
@ -392,14 +392,14 @@ func TestCompareAndSwapUint64(t *testing.T) {
|
|||||||
x.after = magic64
|
x.after = magic64
|
||||||
for val := uint64(1); val+val > val; val += val {
|
for val := uint64(1); val+val > val; val += val {
|
||||||
x.i = val
|
x.i = val
|
||||||
if !CompareAndSwapUint64(&x.i, val, val+1) {
|
if !cas(&x.i, val, val+1) {
|
||||||
t.Fatalf("should have swapped %#x %#x", val, val+1)
|
t.Fatalf("should have swapped %#x %#x", val, val+1)
|
||||||
}
|
}
|
||||||
if x.i != val+1 {
|
if x.i != val+1 {
|
||||||
t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
|
t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
|
||||||
}
|
}
|
||||||
x.i = val + 1
|
x.i = val + 1
|
||||||
if CompareAndSwapUint64(&x.i, val, val+2) {
|
if cas(&x.i, val, val+2) {
|
||||||
t.Fatalf("should not have swapped %#x %#x", val, val+2)
|
t.Fatalf("should not have swapped %#x %#x", val, val+2)
|
||||||
}
|
}
|
||||||
if x.i != val+1 {
|
if x.i != val+1 {
|
||||||
@ -411,6 +411,10 @@ func TestCompareAndSwapUint64(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCompareAndSwapUint64(t *testing.T) {
|
||||||
|
testCompareAndSwapUint64(t, CompareAndSwapUint64)
|
||||||
|
}
|
||||||
|
|
||||||
func TestCompareAndSwapUintptr(t *testing.T) {
|
func TestCompareAndSwapUintptr(t *testing.T) {
|
||||||
var x struct {
|
var x struct {
|
||||||
before uintptr
|
before uintptr
|
||||||
|
9
src/pkg/sync/atomic/export_linux_arm_test.go
Normal file
9
src/pkg/sync/atomic/export_linux_arm_test.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package atomic
|
||||||
|
|
||||||
|
func generalCAS64(*uint64, uint64, uint64) bool
|
||||||
|
|
||||||
|
var GeneralCAS64 = generalCAS64
|
Loading…
Reference in New Issue
Block a user