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