runtime: use kernel-supplied cas on linux/arm

Using the kernel-supplied compare-and-swap code
on linux/arm means that runtime doesn't have to care
whether this is GOARM=5 or GOARM=6 anymore.

Fixes #1494.

R=r, r2
CC=golang-dev
https://golang.org/cl/4245043
This commit is contained in:
Russ Cox 2011-02-25 14:29:55 -05:00
parent 12b7875bf2
commit 9ad9742157
5 changed files with 49 additions and 129 deletions

View File

@ -40,11 +40,8 @@ OFILES_386=\
vlop.$O\
vlrt.$O\
GOARM?=6
# arm-specific object files
OFILES_arm=\
cas$(GOARM).$O\
memset.$O\
softfloat.$O\
vlop.$O\

View File

@ -274,3 +274,34 @@ TEXT runtime·abort(SB),7,$-4
TEXT runtime·runcgocallback(SB),7,$0
MOVW $0, R0
MOVW (R0), R1
// bool armcas(int32 *val, int32 old, int32 new)
// Atomically:
// if(*val == old){
// *val = new;
// return 1;
// }else
// return 0;
//
// To implement runtime·cas in ../$GOOS/arm/sys.s
// using the native instructions, use:
//
// TEXT runtime·cas(SB),7,$0
// B runtime·armcas(SB)
//
TEXT runtime·armcas(SB),7,$0
MOVW valptr+0(FP), R1
MOVW old+4(FP), R2
MOVW new+8(FP), R3
casl:
LDREX (R1), R0
CMP R0, R2
BNE casfail
STREX R3, (R1), R0
CMP $0, R0
BNE casl
MOVW $1, R0
RET
casfail:
MOVW $0, R0
RET

View File

@ -1,74 +0,0 @@
// Copyright 2009 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.
#include "arm/asm.h"
// This version works on pre v6 architectures
// bool cas(int32 *val, int32 old, int32 new)
// Atomically:
// if(*val == old){
// *val = new;
// return 1;
// }else
// return 0;
TEXT runtime·cas(SB),7,$0
MOVW 0(FP), R0 // *val
MOVW 4(FP), R1 // old
MOVW 8(FP), R2 // new
MOVW $1, R3
MOVW $runtime·cas_mutex(SB), R4
SWPW (R4), R3 // acquire mutex
CMP $0, R3
BNE fail0
MOVW (R0), R5
CMP R1, R5
BNE fail1
MOVW R2, (R0)
MOVW R3, (R4) // release mutex
MOVW $1, R0
RET
fail1:
MOVW R3, (R4) // release mutex
fail0:
MOVW $0, R0
RET
// bool casp(void **p, void *old, void *new)
// Atomically:
// if(*p == old){
// *p = new;
// return 1;
// }else
// return 0;
TEXT runtime·casp(SB),7,$0
MOVW 0(FP), R0 // *p
MOVW 4(FP), R1 // old
MOVW 8(FP), R2 // new
MOVW $1, R3
MOVW $runtime·cas_mutex(SB), R4
SWPW (R4), R3 // acquire mutex
CMP $0, R3
BNE failp0
MOVW (R0), R5
CMP R1, R5
BNE failp1
MOVW R2, (R0)
MOVW R3, (R4) // release mutex
MOVW $1, R0
RET
failp1:
MOVW R3, (R4) // release mutex
failp0:
MOVW $0, R0
RET
DATA runtime·cas_mutex(SB)/4, $0
GLOBL runtime·cas_mutex(SB), $4

View File

@ -1,52 +0,0 @@
// Copyright 2009 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.
// bool cas(int32 *val, int32 old, int32 new)
// Atomically:
// if(*val == old){
// *val = new;
// return 1;
// }else
// return 0;
TEXT runtime·cas(SB),7,$0
MOVW 0(FP), R1 // *val
MOVW 4(FP), R2 // old
MOVW 8(FP), R3 // new
l:
LDREX (R1), R0
CMP R0, R2
BNE fail
STREX R3, (R1), R0
CMP $0, R0
BNE l
MOVW $1, R0
RET
fail:
MOVW $0, R0
RET
// bool casp(void **p, void *old, void *new)
// Atomically:
// if(*p == old){
// *p = new;
// return 1;
// }else
// return 0;
TEXT runtime·casp(SB), 7, $0
MOVW 0(FP), R1 // *p
MOVW 4(FP), R2 // old
MOVW 8(FP), R3 // new
lp:
LDREX (R1), R0
CMP R0, R2
BNE failp
STREX R3, (R1), R0
CMP $0, R0
BNE lp
MOVW $1, R0
RET
failp:
MOVW $0, R0
RET

View File

@ -230,3 +230,21 @@ TEXT runtime·sigreturn(SB),7,$0
MOVW $SYS_rt_sigreturn, R7
SWI $0
RET
// Use kernel version instead of native armcas in ../../arm.s.
// See ../../../sync/atomic/asm_linux_arm.s for details.
TEXT cas<>(SB),7,$0
MOVW $0xffff0fc0, PC
TEXT runtime·cas(SB),7,$0
MOVW valptr+0(FP), R2
MOVW old+4(FP), R0
MOVW new+8(FP), R1
BL cas<>(SB)
MOVW $0, R0
MOVW.CS $1, R0
RET
TEXT runtime·casp(SB),7,$0
B runtime·cas(SB)