1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
6 // Both the import "C" prologue and the main file are sorted by issue number.
7 // This file contains //export directives on Go functions
8 // and so it must NOT contain C definitions (only declarations).
9 // See test.go for C definitions.
26 extern void doAdd(int, int);
27 extern int callGoInCThread(int);
33 extern void Issue1560InC(void);
35 // twoSleep returns the absolute start time of the first sleep
37 long long twoSleep(int);
40 void lockOSThreadC(void);
41 int usleep(unsigned usec);
43 // issue 4054 part 2 - part 1 in test.go
59 extern int issue5548_in_c(void);
63 extern unsigned long long issue6833Func(unsigned int, unsigned long long);
67 extern int CheckIssue6907C(_GoString_);
71 extern void f7665(void);
74 // Stack tracing didn't work during cgo code after calling a Go
75 // callback. Make sure GC works and the stack trace is correct.
79 // use ugly atomic variable sync since that doesn't require calling back into
80 // Go code or OS dependencies
81 void issue7978c(uint32_t *sync);
83 // issue 8331 part 2 - part 1 in test.go
84 // A typedef of an unnamed struct is the same struct when
85 // #include'd twice. No runtime test; just make sure it compiles.
86 #include "issue8331.h"
90 typedef void (*PFunc8945)();
91 extern PFunc8945 func8945; // definition is in test.go
96 // issue 28772 part 2 - part 1 in issuex.go
97 #define issue28772Constant2 2
109 void callIssue31891(void);
113 } Issue38408, *PIssue38408;
115 extern void cfunc49633(void*); // definition is in test.go
121 //export ReturnIntLong
122 func ReturnIntLong() (int, C.long) {
154 func testCthread(t *testing.T) {
155 if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && runtime.GOARCH == "arm64" {
156 t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add")
161 want := 10 * (10 - 1) / 2 * 6
163 t.Fatalf("sum=%d, want %d", sum.i, want)
167 // Benchmark measuring overhead from C to Go in a C thread.
168 // Create a new C thread and invoke Go function repeatedly in the new C thread.
169 func benchCGoInCthread(b *testing.B) {
170 n := C.callGoInCThread(C.int(b.N))
172 b.Fatal("unmatch loop times")
182 for i := 0; i < 10000; i++ {
190 func xvariadic(x ...interface{}) {
193 func test1328(t *testing.T) {
198 // Test that C functions and Go functions run in parallel.
203 issue1560Ch = make(chan bool, 2)
206 //export Issue1560FromC
207 func Issue1560FromC() {
208 for atomic.LoadInt32(&issue1560) != 1 {
211 atomic.AddInt32(&issue1560, 1)
212 for atomic.LoadInt32(&issue1560) != 3 {
218 func Issue1560FromGo() {
219 atomic.AddInt32(&issue1560, 1)
220 for atomic.LoadInt32(&issue1560) != 2 {
223 atomic.AddInt32(&issue1560, 1)
227 func test1560(t *testing.T) {
237 func exportbyte() byte {
242 func exportbool() bool {
247 func exportrune() rune {
252 func exporterror() error {
257 func exportint() int {
262 func exportuint() uint {
266 //export exportuintptr
267 func exportuintptr() uintptr {
272 func exportint8() int8 {
277 func exportuint8() uint8 {
282 func exportint16() int16 {
286 //export exportuint16
287 func exportuint16() uint16 {
292 func exportint32() int32 {
296 //export exportuint32
297 func exportuint32() uint32 {
302 func exportint64() int64 {
306 //export exportuint64
307 func exportuint64() uint64 {
311 //export exportfloat32
312 func exportfloat32() float32 {
316 //export exportfloat64
317 func exportfloat64() float64 {
321 //export exportcomplex64
322 func exportcomplex64() complex64 {
326 //export exportcomplex128
327 func exportcomplex128() complex128 {
333 //export exportSliceIn
334 func exportSliceIn(s []byte) bool {
335 return len(s) == cap(s)
338 //export exportSliceOut
339 func exportSliceOut() []byte {
343 //export exportSliceInOut
344 func exportSliceInOut(s []byte) []byte {
351 if runtime.GOOS == "android" {
354 // Same as test3775 but run during init so that
355 // there are two levels of internal runtime lock
356 // (1 for init, 1 for cgo).
357 // This would have been broken by CL 11663043.
361 func test3775(t *testing.T) {
362 if runtime.GOOS == "android" {
365 // Used to panic because of the UnlockOSThread below.
369 //export lockOSThreadCallback
370 func lockOSThreadCallback() {
371 runtime.LockOSThread()
372 runtime.UnlockOSThread()
377 // issue 4054 part 2 - part 1 in test.go
379 var issue4054b = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.II, C.J}
381 //export issue5548FromC
382 func issue5548FromC(s string, i int) int {
383 if len(s) == 4 && s == "test" && i == 42 {
386 println("got", len(s), i)
390 func test5548(t *testing.T) {
391 if x := C.issue5548_in_c(); x != 12345 {
392 t.Errorf("issue5548_in_c = %d, want %d", x, 12345)
398 //export GoIssue6833Func
399 func GoIssue6833Func(aui uint, aui64 uint64) uint64 {
400 return aui64 + uint64(aui)
403 func test6833(t *testing.T) {
405 ull := uint64(0x4000300020001000)
406 v := uint64(C.issue6833Func(C.uint(ui), C.ulonglong(ull)))
407 exp := uint64(ui) + ull
409 t.Errorf("issue6833Func() returns %x, expected %x", v, exp)
415 const CString = "C string"
417 //export CheckIssue6907Go
418 func CheckIssue6907Go(s string) C.int {
425 func test6907Go(t *testing.T) {
426 if got := C.CheckIssue6907C(CString); got != 1 {
427 t.Errorf("C.CheckIssue6907C() == %d, want %d", got, 1)
433 var bad7665 unsafe.Pointer = C.f7665
434 var good7665 uintptr = uintptr(C.f7665)
436 func test7665(t *testing.T) {
437 if bad7665 == nil || uintptr(bad7665) != good7665 {
438 t.Errorf("ptrs = %p, %#x, want same non-nil pointer", bad7665, good7665)
444 var issue7978sync uint32
446 func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) {
448 buf := make([]byte, 65536)
449 trace := string(buf[:runtime.Stack(buf, true)])
450 for _, goroutine := range strings.Split(trace, "\n\n") {
451 if strings.Contains(goroutine, "test.issue7978go") {
452 trace := strings.Split(goroutine, "\n")
453 // look for the expected function in the stack
454 for i := 0; i < depth; i++ {
455 if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) {
456 t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine)
459 if strings.Contains(trace[1+2*i], wantFunc) {
463 t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine)
467 t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace)
470 func issue7978wait(store uint32, wait uint32) {
472 atomic.StoreUint32(&issue7978sync, store)
474 for atomic.LoadUint32(&issue7978sync) != wait {
481 // Force a stack growth from the callback to put extra
482 // pressure on the runtime. See issue #17785.
487 func growStack(n int) int {
492 return buf[growStack(n-1)]
496 C.issue7978c((*C.uint32_t)(&issue7978sync))
500 func test7978(t *testing.T) {
501 if runtime.Compiler == "gccgo" {
502 t.Skip("gccgo can not do stack traces of C code")
504 debug.SetTraceback("2")
507 // test in c code, before callback
509 issue7978check(t, "_Cfunc_issue7978c(", "", 1)
510 // test in go code, during callback
512 issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3)
513 // test in c code, after callback
515 issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1)
516 // test in go code, after return from cgo
518 issue7978check(t, "test.issue7978go(", "", 3)
519 atomic.StoreUint32(&issue7978sync, 8)
524 var issue8331Var C.issue8331
536 func multi() (*C.char, C.int) {
537 return C.CString("multi"), 0
540 func test20910(t *testing.T) {
544 // issue 28772 part 2
546 const issue28772Constant2 = C.issue28772Constant2
550 //export useIssue31891A
551 func useIssue31891A(c *C.Issue31891A) {}
553 //export useIssue31891B
554 func useIssue31891B(c *C.Issue31891B) {}
556 func test31891(t *testing.T) {
560 // issue 37033, check if cgo.Handle works properly
565 func GoFunc37033(handle C.uintptr_t) {
566 h := cgo.Handle(handle)
567 ch := h.Value().(chan int)
572 // A typedef pointer can be used as the element type.
573 // No runtime test; just make sure it compiles.
574 var _ C.PIssue38408 = &C.Issue38408{i: 1}
576 // issue 49633, example use of cgo.Handle with void*
578 type data49633 struct {
583 func GoFunc49633(context unsafe.Pointer) {
584 h := *(*cgo.Handle)(context)
585 v := h.Value().(*data49633)
589 func test49633(t *testing.T) {
591 h := cgo.NewHandle(v)
593 C.cfunc49633(unsafe.Pointer(&h))
594 if v.msg != "hello" {
595 t.Errorf("msg = %q, want 'hello'", v.msg)