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