github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/runtime/testdata/testprogcgo/numgoroutine.go (about) 1 // Copyright 2017 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 <stddef.h> 11 #include <pthread.h> 12 13 extern void CallbackNumGoroutine(); 14 15 static void* thread2(void* arg __attribute__ ((unused))) { 16 CallbackNumGoroutine(); 17 return NULL; 18 } 19 20 static void CheckNumGoroutine() { 21 pthread_t tid; 22 pthread_create(&tid, NULL, thread2, NULL); 23 pthread_join(tid, NULL); 24 } 25 */ 26 import "C" 27 28 import ( 29 "fmt" 30 "runtime" 31 "strings" 32 ) 33 34 var baseGoroutines int 35 36 func init() { 37 register("NumGoroutine", NumGoroutine) 38 } 39 40 func NumGoroutine() { 41 // Test that there are just the expected number of goroutines 42 // running. Specifically, test that the spare M's goroutine 43 // doesn't show up. 44 // 45 // On non-Windows platforms there's a signal handling thread 46 // started by os/signal.init in addition to the main 47 // goroutine. 48 if runtime.GOOS != "windows" { 49 baseGoroutines = 1 50 } 51 if _, ok := checkNumGoroutine("first", 1+baseGoroutines); !ok { 52 return 53 } 54 55 // Test that the goroutine for a callback from C appears. 56 if C.CheckNumGoroutine(); !callbackok { 57 return 58 } 59 60 // Make sure we're back to the initial goroutines. 61 if _, ok := checkNumGoroutine("third", 1+baseGoroutines); !ok { 62 return 63 } 64 65 fmt.Println("OK") 66 } 67 68 func checkNumGoroutine(label string, want int) (string, bool) { 69 n := runtime.NumGoroutine() 70 if n != want { 71 fmt.Printf("%s NumGoroutine: want %d; got %d\n", label, want, n) 72 return "", false 73 } 74 75 sbuf := make([]byte, 32<<10) 76 sbuf = sbuf[:runtime.Stack(sbuf, true)] 77 n = strings.Count(string(sbuf), "goroutine ") 78 if n != want { 79 fmt.Printf("%s Stack: want %d; got %d:\n%s\n", label, want, n, string(sbuf)) 80 return "", false 81 } 82 return string(sbuf), true 83 } 84 85 var callbackok bool 86 87 //export CallbackNumGoroutine 88 func CallbackNumGoroutine() { 89 stk, ok := checkNumGoroutine("second", 2+baseGoroutines) 90 if !ok { 91 return 92 } 93 if !strings.Contains(stk, "CallbackNumGoroutine") { 94 fmt.Printf("missing CallbackNumGoroutine from stack:\n%s\n", stk) 95 return 96 } 97 98 callbackok = true 99 }