github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/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  	"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  }