Source file src/runtime/testdata/testprogcgo/callback.go

     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  }
    95  

View as plain text