diff options
Diffstat (limited to 'misc')
-rw-r--r-- | misc/cgo/stdio/Makefile | 3 | ||||
-rw-r--r-- | misc/cgo/stdio/hello.go | 20 | ||||
-rw-r--r-- | misc/cgo/test/Makefile | 23 | ||||
-rw-r--r-- | misc/cgo/test/align.go (renamed from misc/cgo/stdio/align.go) | 18 | ||||
-rw-r--r-- | misc/cgo/test/basic.go (renamed from misc/cgo/stdio/test.go) | 36 | ||||
-rw-r--r-- | misc/cgo/test/callback.go | 136 | ||||
-rw-r--r-- | misc/cgo/test/callback_c.c | 12 | ||||
-rw-r--r-- | misc/cgo/test/cgo_test.go | 6 | ||||
-rw-r--r-- | misc/cgo/test/issue1222.go (renamed from misc/cgo/stdio/test1.go) | 2 | ||||
-rw-r--r-- | misc/cgo/test/issue1328.go | 30 | ||||
-rw-r--r-- | misc/cgo/test/issue1560.go | 46 | ||||
-rw-r--r-- | misc/cgo/test/runtime.c | 21 |
12 files changed, 295 insertions, 58 deletions
diff --git a/misc/cgo/stdio/Makefile b/misc/cgo/stdio/Makefile index fc925e607..3f7a4c01c 100644 --- a/misc/cgo/stdio/Makefile +++ b/misc/cgo/stdio/Makefile @@ -6,10 +6,7 @@ include ../../../src/Make.inc TARG=stdio CGOFILES=\ - align.go\ file.go\ - test.go\ - test1.go\ CLEANFILES+=hello fib chain run.out diff --git a/misc/cgo/stdio/hello.go b/misc/cgo/stdio/hello.go index 9cb6e6884..58fc6d574 100644 --- a/misc/cgo/stdio/hello.go +++ b/misc/cgo/stdio/hello.go @@ -4,26 +4,8 @@ package main -import ( - "os" - "stdio" -) +import "stdio" func main() { stdio.Stdout.WriteString(stdio.Greeting + "\n") - - l := stdio.Atol("123") - if l != 123 { - println("Atol 123: ", l) - panic("bad atol") - } - - n, err := stdio.Strtol("asdf", 123) - if n != 0 || err != os.EINVAL { - println("Strtol: ", n, err) - panic("bad atoi2") - } - - stdio.TestAlign() - stdio.TestEnum() } diff --git a/misc/cgo/test/Makefile b/misc/cgo/test/Makefile new file mode 100644 index 000000000..893540d97 --- /dev/null +++ b/misc/cgo/test/Makefile @@ -0,0 +1,23 @@ +# 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. + +include ../../../src/Make.inc + +TARG=runtime/cgotest + +CGOFILES=\ + align.go\ + basic.go\ + callback.go\ + issue1222.go\ + issue1328.go\ + issue1560.go\ + +CGO_OFILES=\ + callback_c.o\ + +OFILES=\ + runtime.$O\ + +include ../../../src/Make.pkg diff --git a/misc/cgo/stdio/align.go b/misc/cgo/test/align.go index 6cdfd902f..2d2979595 100644 --- a/misc/cgo/stdio/align.go +++ b/misc/cgo/test/align.go @@ -1,4 +1,4 @@ -package stdio +package cgotest /* #include <stdio.h> @@ -55,24 +55,18 @@ void cTest(SDL_KeyboardEvent *event) { import "C" import ( - "fmt" - "syscall" + "testing" ) -func TestAlign() { - if syscall.ARCH == "amd64" { - // alignment is known to be broken on amd64. - // http://code.google.com/p/go/issues/detail?id=609 - return - } +func TestAlign(t *testing.T) { var evt C.SDL_KeyboardEvent C.makeEvent(&evt) if C.same(&evt, evt.typ, evt.which, evt.state, evt.keysym.scancode, evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) == 0 { - fmt.Println("*** bad alignment") + t.Error("*** bad alignment") C.cTest(&evt) - fmt.Printf("Go: %#x %#x %#x %#x %#x %#x %#x\n", + t.Errorf("Go: %#x %#x %#x %#x %#x %#x %#x\n", evt.typ, evt.which, evt.state, evt.keysym.scancode, evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) - fmt.Println(evt) + t.Error(evt) } } diff --git a/misc/cgo/stdio/test.go b/misc/cgo/test/basic.go index 8f21603ca..a94074c52 100644 --- a/misc/cgo/stdio/test.go +++ b/misc/cgo/test/basic.go @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// This file contains test cases for cgo. +// Basic test cases for cgo. -package stdio +package cgotest /* #include <stdio.h> @@ -52,6 +52,7 @@ struct ibv_context { import "C" import ( "os" + "testing" "unsafe" ) @@ -89,38 +90,35 @@ func Atol(s string) int { return int(n) } -func TestConst() { +func TestConst(t *testing.T) { C.myConstFunc(nil, 0, nil) } -func TestEnum() { +func TestEnum(t *testing.T) { if C.Enum1 != 1 || C.Enum2 != 2 { - println("bad enum", C.Enum1, C.Enum2) + t.Error("bad enum", C.Enum1, C.Enum2) } } -func TestAtol() { +func TestAtol(t *testing.T) { l := Atol("123") if l != 123 { - println("Atol 123: ", l) - panic("bad atol") + t.Error("Atol 123: ", l) } } -func TestErrno() { +func TestErrno(t *testing.T) { n, err := Strtol("asdf", 123) if n != 0 || err != os.EINVAL { - println("Strtol: ", n, err) - panic("bad strtol") + t.Error("Strtol: ", n, err) } } -func TestMultipleAssign() { - p := C.CString("123") +func TestMultipleAssign(t *testing.T) { + p := C.CString("234") n, m := C.strtol(p, nil, 345), C.strtol(p, nil, 10) if n != 0 || m != 234 { - println("Strtol x2: ", n, m) - panic("bad strtol x2") + t.Fatal("Strtol x2: ", n, m) } C.free(unsafe.Pointer(p)) } @@ -134,11 +132,3 @@ var ( type Context struct { ctx *C.struct_ibv_context } - -func Test() { - TestAlign() - TestAtol() - TestEnum() - TestErrno() - TestConst() -} diff --git a/misc/cgo/test/callback.go b/misc/cgo/test/callback.go new file mode 100644 index 000000000..b4e6c191a --- /dev/null +++ b/misc/cgo/test/callback.go @@ -0,0 +1,136 @@ +package cgotest + +/* +void callback(void *f); +void callGoFoo(void) { + extern void goFoo(void); + goFoo(); +} +*/ +import "C" + +import ( + "runtime" + "testing" + "unsafe" +) + +// nestedCall calls into C, back into Go, and finally to f. +func nestedCall(f func()) { + // NOTE: Depends on representation of f. + // callback(x) calls goCallback(x) + C.callback(*(*unsafe.Pointer)(unsafe.Pointer(&f))) +} + +//export goCallback +func goCallback(p unsafe.Pointer) { + (*(*func())(unsafe.Pointer(&p)))() +} + +func TestCallback(t *testing.T) { + var x = false + nestedCall(func(){x = true}) + if !x { + t.Fatal("nestedCall did not call func") + } +} + +func TestCallbackGC(t *testing.T) { + nestedCall(runtime.GC) +} + +func lockedOSThread() bool // in runtime.c + +func TestCallbackPanic(t *testing.T) { + // Make sure panic during callback unwinds properly. + if lockedOSThread() { + t.Fatal("locked OS thread on entry to TestCallbackPanic") + } + defer func() { + s := recover() + if s == nil { + t.Fatal("did not panic") + } + if s.(string) != "callback panic" { + t.Fatal("wrong panic:", s) + } + if lockedOSThread() { + t.Fatal("locked OS thread on exit from TestCallbackPanic") + } + }() + nestedCall(func(){panic("callback panic")}) + panic("nestedCall returned") +} + +func TestCallbackPanicLoop(t *testing.T) { + // Make sure we don't blow out m->g0 stack. + for i := 0; i < 100000; i++ { + TestCallbackPanic(t) + } +} + +func TestCallbackPanicLocked(t *testing.T) { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + if !lockedOSThread() { + t.Fatal("runtime.LockOSThread didn't") + } + defer func() { + s := recover() + if s == nil { + t.Fatal("did not panic") + } + if s.(string) != "callback panic" { + t.Fatal("wrong panic:", s) + } + if !lockedOSThread() { + t.Fatal("lost lock on OS thread after panic") + } + }() + nestedCall(func(){panic("callback panic")}) + panic("nestedCall returned") +} + +// Callback with zero arguments used to make the stack misaligned, +// which broke the garbage collector and other things. +func TestZeroArgCallback(t *testing.T) { + defer func() { + s := recover() + if s != nil { + t.Fatal("panic during callback:", s) + } + }() + C.callGoFoo() +} + +//export goFoo +func goFoo() { + x := 1 + for i := 0; i < 10000; i++ { + // variadic call mallocs + writes to + variadic(x, x, x) + if x != 1 { + panic("bad x") + } + } +} + +func variadic(x ...interface{}) {} + +func TestBlocking(t *testing.T) { + c := make(chan int) + go func() { + for i := 0; i < 10; i++ { + c <- <-c + } + }() + nestedCall(func(){ + for i := 0; i < 10; i++ { + c <- i + if j := <-c; j != i { + t.Errorf("out of sync %d != %d", j, i) + } + } + }) +} diff --git a/misc/cgo/test/callback_c.c b/misc/cgo/test/callback_c.c new file mode 100644 index 000000000..5983a5e11 --- /dev/null +++ b/misc/cgo/test/callback_c.c @@ -0,0 +1,12 @@ +// 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. + +#include <sys/types.h> +#include "_cgo_export.h" + +void +callback(void *f) +{ + goCallback(f); +} diff --git a/misc/cgo/test/cgo_test.go b/misc/cgo/test/cgo_test.go new file mode 100644 index 000000000..9b9f1f9d8 --- /dev/null +++ b/misc/cgo/test/cgo_test.go @@ -0,0 +1,6 @@ +package cgotest + +// dummy file so gotest thinks there are tests. +// the actual tests are in the main go files, next +// to the code they test. + diff --git a/misc/cgo/stdio/test1.go b/misc/cgo/test/issue1222.go index dce2ef83c..c396a0c41 100644 --- a/misc/cgo/stdio/test1.go +++ b/misc/cgo/test/issue1222.go @@ -4,7 +4,7 @@ // This file contains test cases for cgo. -package stdio +package cgotest /* // issue 1222 diff --git a/misc/cgo/test/issue1328.go b/misc/cgo/test/issue1328.go new file mode 100644 index 000000000..f29d7057e --- /dev/null +++ b/misc/cgo/test/issue1328.go @@ -0,0 +1,30 @@ +// 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. + +package cgotest + +import "testing" + +// extern void BackIntoGo(void); +// void IntoC() { BackIntoGo(); } +import "C" + +//export BackIntoGo +func BackIntoGo() { + x := 1 + + for i := 0; i < 10000; i++ { + xvariadic(x) + if x != 1 { + panic("x is not 1?") + } + } +} + +func xvariadic(x ...interface{}) { +} + +func Test1328(t *testing.T) { + C.IntoC() +} diff --git a/misc/cgo/test/issue1560.go b/misc/cgo/test/issue1560.go new file mode 100644 index 000000000..b5feafce5 --- /dev/null +++ b/misc/cgo/test/issue1560.go @@ -0,0 +1,46 @@ +// 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. + +package cgotest + +/* +#include <unistd.h> + +extern void BackgroundSleep(int); +void twoSleep(int n) { + BackgroundSleep(n); + sleep(n); +} +*/ +import "C" + +import ( + "testing" + "time" +) + +var sleepDone = make(chan bool) + +func parallelSleep(n int) { + C.twoSleep(C.int(n)) + <-sleepDone +} + +//export BackgroundSleep +func BackgroundSleep(n int){ + go func(){ + C.sleep(C.uint(n)) + sleepDone <- true + }() +} + +func TestParallelSleep(t *testing.T) { + dt := -time.Nanoseconds() + parallelSleep(1) + dt += time.Nanoseconds() + // bug used to run sleeps in serial, producing a 2-second delay. + if dt >= 1.3e9 { + t.Fatalf("parallel 1-second sleeps slept for %f seconds", float64(dt)/1e9) + } +} diff --git a/misc/cgo/test/runtime.c b/misc/cgo/test/runtime.c new file mode 100644 index 000000000..e087c7622 --- /dev/null +++ b/misc/cgo/test/runtime.c @@ -0,0 +1,21 @@ +// 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. + +// Expose some runtime functions for testing. + +typedef char bool; + +bool runtime·lockedOSThread(void); + +static void +FLUSH(void*) +{ +} + +void +·lockedOSThread(bool b) +{ + b = runtime·lockedOSThread(); + FLUSH(&b); +} |