Commit 6b335712 authored by Russ Cox's avatar Russ Cox

build: add all-qemu.bash, handful of arm fixes

R=r
CC=golang-dev
https://golang.org/cl/4313051
parent dacd1cad
...@@ -8,7 +8,7 @@ all: index.html ...@@ -8,7 +8,7 @@ all: index.html
include ../../../src/Make.common include ../../../src/Make.common
CLEANFILES+=index.html srcextract.bin htmlify.bin CLEANFILES+=index.html srcextract.bin htmlify.bin get.bin
index.html: srcextract.bin htmlify.bin index.html: srcextract.bin htmlify.bin
PATH=.:$$PATH awk '/^!/{system(substr($$0,2)); next} {print}' < wiki.html | tr -d '\r' > index.html PATH=.:$$PATH awk '/^!/{system(substr($$0,2)); next} {print}' < wiki.html | tr -d '\r' > index.html
......
#!/usr/bin/env bash
# Copyright 2011 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.
# Run all.bash but exclude tests that depend on functionality
# missing in QEMU's system call emulation.
export DISABLE_NET_TESTS=1 # no external network
export NOTEST=""
NOTEST="$NOTEST big" # xxx
NOTEST="$NOTEST http net rpc syslog websocket" # no localhost network
NOTEST="$NOTEST os" # 64-bit seek fails
./all.bash
...@@ -169,7 +169,7 @@ DIRS+=\ ...@@ -169,7 +169,7 @@ DIRS+=\
endif endif
NOTEST=\ NOTEST+=\
crypto\ crypto\
crypto/openpgp/error\ crypto/openpgp/error\
debug/proc\ debug/proc\
...@@ -196,7 +196,7 @@ NOTEST=\ ...@@ -196,7 +196,7 @@ NOTEST=\
../cmd/goyacc\ ../cmd/goyacc\
../cmd/hgpatch\ ../cmd/hgpatch\
NOBENCH=\ NOBENCH+=\
container/vector\ container/vector\
# Disable tests that depend on an external network. # Disable tests that depend on an external network.
......
...@@ -114,7 +114,7 @@ func check(t *testing.T, source, golden string, mode checkMode) { ...@@ -114,7 +114,7 @@ func check(t *testing.T, source, golden string, mode checkMode) {
// start a timer to produce a time-out signal // start a timer to produce a time-out signal
tc := make(chan int) tc := make(chan int)
go func() { go func() {
time.Sleep(2e9) // plenty of a safety margin, even for very slow machines time.Sleep(10e9) // plenty of a safety margin, even for very slow machines
tc <- 0 tc <- 0
}() }()
......
...@@ -135,6 +135,8 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart) ...@@ -135,6 +135,8 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
sa.sa_flags |= SA_RESTART; sa.sa_flags |= SA_RESTART;
sa.sa_mask = ~0ULL; sa.sa_mask = ~0ULL;
sa.sa_restorer = (void*)runtime·sigreturn; sa.sa_restorer = (void*)runtime·sigreturn;
if(fn == runtime·sighandler)
fn = (void*)runtime·sigtramp;
sa.sa_handler = fn; sa.sa_handler = fn;
runtime·rt_sigaction(i, &sa, nil, 8); runtime·rt_sigaction(i, &sa, nil, 8);
} }
......
...@@ -13,7 +13,7 @@ SigTab runtime·sigtab[] = { ...@@ -13,7 +13,7 @@ SigTab runtime·sigtab[] = {
/* 1 */ Q+R, "SIGHUP: terminal line hangup", /* 1 */ Q+R, "SIGHUP: terminal line hangup",
/* 2 */ Q+R, "SIGINT: interrupt", /* 2 */ Q+R, "SIGINT: interrupt",
/* 3 */ C, "SIGQUIT: quit", /* 3 */ C, "SIGQUIT: quit",
/* 4 */ C, "SIGILL: illegal instruction", /* 4 */ C+P, "SIGILL: illegal instruction",
/* 5 */ C, "SIGTRAP: trace trap", /* 5 */ C, "SIGTRAP: trace trap",
/* 6 */ C, "SIGABRT: abort", /* 6 */ C, "SIGABRT: abort",
/* 7 */ C+P, "SIGBUS: bus error", /* 7 */ C+P, "SIGBUS: bus error",
......
...@@ -25,6 +25,7 @@ casfail: ...@@ -25,6 +25,7 @@ casfail:
RET RET
TEXT ·armCompareAndSwapUint64(SB),7,$0 TEXT ·armCompareAndSwapUint64(SB),7,$0
BL fastCheck64<>(SB)
MOVW valptr+0(FP), R1 MOVW valptr+0(FP), R1
MOVW oldlo+4(FP), R2 MOVW oldlo+4(FP), R2
MOVW oldhi+8(FP), R3 MOVW oldhi+8(FP), R3
...@@ -62,6 +63,7 @@ addloop: ...@@ -62,6 +63,7 @@ addloop:
RET RET
TEXT ·armAddUint64(SB),7,$0 TEXT ·armAddUint64(SB),7,$0
BL fastCheck64<>(SB)
MOVW valptr+0(FP), R1 MOVW valptr+0(FP), R1
MOVW deltalo+4(FP), R2 MOVW deltalo+4(FP), R2
MOVW deltahi+8(FP), R3 MOVW deltahi+8(FP), R3
...@@ -76,3 +78,42 @@ add64loop: ...@@ -76,3 +78,42 @@ add64loop:
MOVW R4, retlo+12(FP) MOVW R4, retlo+12(FP)
MOVW R5, rethi+16(FP) MOVW R5, rethi+16(FP)
RET RET
// Check for broken 64-bit LDREXD as found in QEMU.
// LDREXD followed by immediate STREXD should succeed.
// If it fails, try a few times just to be sure (maybe our thread got
// rescheduled between the two instructions) and then panic.
// A bug in some copies of QEMU makes STREXD never succeed,
// which will make uses of the 64-bit atomic operations loop forever.
// If things are working, set okLDREXD to avoid future checks.
// https://bugs.launchpad.net/qemu/+bug/670883.
TEXT check64<>(SB),7,$8
MOVW $10, R1
loop:
LDREXD (SP), R2
STREXD R2, (SP), R0
CMP $0, R0
BEQ ok
SUB $1, R1
CMP $0, R1
BNE loop
// Must be buggy QEMU.
BL ·panic64(SB)
ok:
RET
// Fast, cached version of check. No frame, just MOVW CMP RET after first time.
TEXT fastCheck64<>(SB),7,$-4
MOVW ok64<>(SB), R0
CMP $0, R0 // have we been here before?
RET.NE
B slowCheck64<>(SB)
TEXT slowCheck64<>(SB),7,$0
BL check64<>(SB)
// Still here, must be okay.
MOVW $1, R0
MOVW R0, ok64<>(SB)
RET
GLOBL ok64<>(SB), $4
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package atomic package atomic_test
import ( import (
"runtime" "runtime"
. "sync/atomic"
"testing" "testing"
"unsafe" "unsafe"
) )
...@@ -27,6 +28,16 @@ const ( ...@@ -27,6 +28,16 @@ const (
magic64 = 0xdeddeadbeefbeef magic64 = 0xdeddeadbeefbeef
) )
// Do the 64-bit functions panic? If so, don't bother testing.
var test64err = func() (err interface{}) {
defer func() {
err = recover()
}()
var x int64
AddInt64(&x, 1)
return nil
}()
func TestAddInt32(t *testing.T) { func TestAddInt32(t *testing.T) {
var x struct { var x struct {
before int32 before int32
...@@ -70,6 +81,10 @@ func TestAddUint32(t *testing.T) { ...@@ -70,6 +81,10 @@ func TestAddUint32(t *testing.T) {
} }
func TestAddInt64(t *testing.T) { func TestAddInt64(t *testing.T) {
if test64err != nil {
t.Logf("Skipping 64-bit tests: %v", test64err)
return
}
var x struct { var x struct {
before int64 before int64
i int64 i int64
...@@ -91,6 +106,10 @@ func TestAddInt64(t *testing.T) { ...@@ -91,6 +106,10 @@ func TestAddInt64(t *testing.T) {
} }
func TestAddUint64(t *testing.T) { func TestAddUint64(t *testing.T) {
if test64err != nil {
t.Logf("Skipping 64-bit tests: %v", test64err)
return
}
var x struct { var x struct {
before uint64 before uint64
i uint64 i uint64
...@@ -193,6 +212,10 @@ func TestCompareAndSwapUint32(t *testing.T) { ...@@ -193,6 +212,10 @@ func TestCompareAndSwapUint32(t *testing.T) {
} }
func TestCompareAndSwapInt64(t *testing.T) { func TestCompareAndSwapInt64(t *testing.T) {
if test64err != nil {
t.Logf("Skipping 64-bit tests: %v", test64err)
return
}
var x struct { var x struct {
before int64 before int64
i int64 i int64
...@@ -222,6 +245,10 @@ func TestCompareAndSwapInt64(t *testing.T) { ...@@ -222,6 +245,10 @@ func TestCompareAndSwapInt64(t *testing.T) {
} }
func TestCompareAndSwapUint64(t *testing.T) { func TestCompareAndSwapUint64(t *testing.T) {
if test64err != nil {
t.Logf("Skipping 64-bit tests: %v", test64err)
return
}
var x struct { var x struct {
before uint64 before uint64
i uint64 i uint64
...@@ -479,6 +506,10 @@ func hammerCompareAndSwapUintptr64(uval *uint64, count int) { ...@@ -479,6 +506,10 @@ func hammerCompareAndSwapUintptr64(uval *uint64, count int) {
} }
func TestHammer64(t *testing.T) { func TestHammer64(t *testing.T) {
if test64err != nil {
t.Logf("Skipping 64-bit tests: %v", test64err)
return
}
const p = 4 const p = 4
n := 100000 n := 100000
if testing.Short() { if testing.Short() {
......
...@@ -55,3 +55,8 @@ func AddUint64(val *uint64, delta uint64) (new uint64) ...@@ -55,3 +55,8 @@ func AddUint64(val *uint64, delta uint64) (new uint64)
// AddUintptr atomically adds delta to *val and returns the new value. // AddUintptr atomically adds delta to *val and returns the new value.
func AddUintptr(val *uintptr, delta uintptr) (new uintptr) func AddUintptr(val *uintptr, delta uintptr) (new uintptr)
// Helper for ARM. Linker will discard on other systems
func panic64() {
panic("sync/atomic: broken 64-bit atomic operations (buggy QEMU)")
}
...@@ -98,6 +98,7 @@ time gomake ogle ...@@ -98,6 +98,7 @@ time gomake ogle
time ./run time ./run
) || exit $? ) || exit $?
[ "$GOARCH" == arm ] || # uses network, fails under QEMU
(xcd ../doc/codelab/wiki (xcd ../doc/codelab/wiki
gomake clean gomake clean
gomake gomake
......
...@@ -6,12 +6,14 @@ ...@@ -6,12 +6,14 @@
package main package main
import ( import "os"
"net"
) // Issue 481: closures and var declarations
// with multiple variables assigned from one
// function call.
func main() { func main() {
var listen, _ = net.Listen("tcp", "127.0.0.1:0") var listen, _ = Listen("tcp", "127.0.0.1:0")
go func() { go func() {
for { for {
...@@ -20,6 +22,31 @@ func main() { ...@@ -20,6 +22,31 @@ func main() {
} }
}() }()
var conn, _ = net.Dial("tcp", "", listen.Addr().String()) var conn, _ = Dial("tcp", "", listen.Addr().String())
_ = conn _ = conn
} }
// Simulated net interface to exercise bug
// without involving a real network.
type T chan int
var global T
func Listen(x, y string) (T, string) {
global = make(chan int)
return global, y
}
func (t T) Addr() os.Error {
return os.ErrorString("stringer")
}
func (t T) Accept() (int, string) {
return <-t, ""
}
func Dial(x, y, z string) (int, string) {
global <- 1
return 0, ""
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment