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

     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  
     8  package main
     9  
    10  /*
    11  #include <stddef.h>
    12  #include <pthread.h>
    13  
    14  extern void CallbackNumGoroutine();
    15  
    16  static void* thread2(void* arg __attribute__ ((unused))) {
    17  	CallbackNumGoroutine();
    18  	return NULL;
    19  }
    20  
    21  static void CheckNumGoroutine() {
    22  	pthread_t tid;
    23  	pthread_create(&tid, NULL, thread2, NULL);
    24  	pthread_join(tid, NULL);
    25  }
    26  */
    27  import "C"
    28  
    29  import (
    30  	"fmt"
    31  	"runtime"
    32  	"strings"
    33  )
    34  
    35  var baseGoroutines int
    36  
    37  func init() {
    38  	register("NumGoroutine", NumGoroutine)
    39  }
    40  
    41  func 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  
    62  func 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  
    79  var callbackok bool
    80  
    81  //export CallbackNumGoroutine
    82  func 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  

View as plain text