1
0
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:
Russ Cox 2013-09-24 15:54:48 -04:00
parent 5639d2754b
commit 828a4b9376
4 changed files with 44 additions and 12 deletions

View File

@ -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

View 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)
}

View File

@ -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

View 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