github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/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 if _, ok := checkNumGoroutine("first", 1+baseGoroutines); !ok { 45 return 46 } 47 48 // Test that the goroutine for a callback from C appears. 49 if C.CheckNumGoroutine(); !callbackok { 50 return 51 } 52 53 // Make sure we're back to the initial goroutines. 54 if _, ok := checkNumGoroutine("third", 1+baseGoroutines); !ok { 55 return 56 } 57 58 fmt.Println("OK") 59 } 60 61 func checkNumGoroutine(label string, want int) (string, bool) { 62 n := runtime.NumGoroutine() 63 if n != want { 64 fmt.Printf("%s NumGoroutine: want %d; got %d\n", label, want, n) 65 return "", false 66 } 67 68 sbuf := make([]byte, 32<<10) 69 sbuf = sbuf[:runtime.Stack(sbuf, true)] 70 n = strings.Count(string(sbuf), "goroutine ") 71 if n != want { 72 fmt.Printf("%s Stack: want %d; got %d:\n%s\n", label, want, n, string(sbuf)) 73 return "", false 74 } 75 return string(sbuf), true 76 } 77 78 var callbackok bool 79 80 //export CallbackNumGoroutine 81 func CallbackNumGoroutine() { 82 stk, ok := checkNumGoroutine("second", 2+baseGoroutines) 83 if !ok { 84 return 85 } 86 if !strings.Contains(stk, "CallbackNumGoroutine") { 87 fmt.Printf("missing CallbackNumGoroutine from stack:\n%s\n", stk) 88 return 89 } 90 91 callbackok = true 92 }