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