Home | History | Annotate | Download | only in testprogcgo
      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 	"runtime"
     33 )
     34 
     35 func init() {
     36 	register("CgoCallbackGC", CgoCallbackGC)
     37 }
     38 
     39 //export go_callback
     40 func go_callback() {
     41 	runtime.GC()
     42 	grow()
     43 	runtime.GC()
     44 }
     45 
     46 var cnt int
     47 
     48 func grow() {
     49 	x := 10000
     50 	sum := 0
     51 	if grow1(&x, &sum) == 0 {
     52 		panic("bad")
     53 	}
     54 }
     55 
     56 func grow1(x, sum *int) int {
     57 	if *x == 0 {
     58 		return *sum + 1
     59 	}
     60 	*x--
     61 	sum1 := *sum + *x
     62 	return grow1(x, &sum1)
     63 }
     64 
     65 func CgoCallbackGC() {
     66 	const P = 100
     67 	done := make(chan bool)
     68 	// allocate a bunch of stack frames and spray them with pointers
     69 	for i := 0; i < P; i++ {
     70 		go func() {
     71 			grow()
     72 			done <- true
     73 		}()
     74 	}
     75 	for i := 0; i < P; i++ {
     76 		<-done
     77 	}
     78 	// now give these stack frames to cgo callbacks
     79 	for i := 0; i < P; i++ {
     80 		go func() {
     81 			C.foo()
     82 			done <- true
     83 		}()
     84 	}
     85 	for i := 0; i < P; i++ {
     86 		<-done
     87 	}
     88 	fmt.Printf("OK\n")
     89 }
     90