github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/runtime/testdata/testprogcgo/callback.go (about) 1 // Copyright 2015 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. 4 5 // +build !plan9,!windows 6 7 package main 8 9 /* 10 #include <pthread.h> 11 12 void go_callback(); 13 14 static void *thr(void *arg) { 15 go_callback(); 16 return 0; 17 } 18 19 static void foo() { 20 pthread_t th; 21 pthread_attr_t attr; 22 pthread_attr_init(&attr); 23 pthread_attr_setstacksize(&attr, 256 << 10); 24 pthread_create(&th, &attr, thr, 0); 25 pthread_join(th, 0); 26 } 27 */ 28 import "C" 29 30 import ( 31 "fmt" 32 "os" 33 "runtime" 34 ) 35 36 func init() { 37 register("CgoCallbackGC", CgoCallbackGC) 38 } 39 40 //export go_callback 41 func go_callback() { 42 runtime.GC() 43 grow() 44 runtime.GC() 45 } 46 47 var cnt int 48 49 func grow() { 50 x := 10000 51 sum := 0 52 if grow1(&x, &sum) == 0 { 53 panic("bad") 54 } 55 } 56 57 func grow1(x, sum *int) int { 58 if *x == 0 { 59 return *sum + 1 60 } 61 *x-- 62 sum1 := *sum + *x 63 return grow1(x, &sum1) 64 } 65 66 func CgoCallbackGC() { 67 P := 100 68 if os.Getenv("RUNTIME_TESTING_SHORT") != "" { 69 P = 10 70 } 71 done := make(chan bool) 72 // allocate a bunch of stack frames and spray them with pointers 73 for i := 0; i < P; i++ { 74 go func() { 75 grow() 76 done <- true 77 }() 78 } 79 for i := 0; i < P; i++ { 80 <-done 81 } 82 // now give these stack frames to cgo callbacks 83 for i := 0; i < P; i++ { 84 go func() { 85 C.foo() 86 done <- true 87 }() 88 } 89 for i := 0; i < P; i++ { 90 <-done 91 } 92 fmt.Printf("OK\n") 93 }