github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/runtime/pprof/testdata/mappingtest/main.go (about)

     1  // Copyright 2018 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  // This program outputs a CPU profile that includes
     6  // both Go and Cgo stacks. This is used by the mapping info
     7  // tests in runtime/pprof.
     8  //
     9  // If SETCGOTRACEBACK=1 is set, the CPU profile will includes
    10  // PCs from C side but they will not be symbolized.
    11  package main
    12  
    13  /*
    14  #include <stdint.h>
    15  #include <stdlib.h>
    16  
    17  int cpuHogCSalt1 = 0;
    18  int cpuHogCSalt2 = 0;
    19  
    20  void CPUHogCFunction() {
    21  	int foo = cpuHogCSalt1;
    22  	int i;
    23  	for (i = 0; i < 100000; i++) {
    24  		if (foo > 0) {
    25  			foo *= foo;
    26  		} else {
    27  			foo *= foo + 1;
    28  		}
    29  		cpuHogCSalt2 = foo;
    30  	}
    31  }
    32  
    33  struct CgoTracebackArg {
    34  	uintptr_t context;
    35          uintptr_t sigContext;
    36  	uintptr_t *buf;
    37          uintptr_t max;
    38  };
    39  
    40  void CollectCgoTraceback(void* parg) {
    41          struct CgoTracebackArg* arg = (struct CgoTracebackArg*)(parg);
    42  	arg->buf[0] = (uintptr_t)(CPUHogCFunction);
    43  	arg->buf[1] = 0;
    44  };
    45  */
    46  import "C"
    47  
    48  import (
    49  	"log"
    50  	"os"
    51  	"runtime"
    52  	"runtime/pprof"
    53  	"time"
    54  	"unsafe"
    55  )
    56  
    57  func init() {
    58  	if v := os.Getenv("SETCGOTRACEBACK"); v == "1" {
    59  		// Collect some PCs from C-side, but don't symbolize.
    60  		runtime.SetCgoTraceback(0, unsafe.Pointer(C.CollectCgoTraceback), nil, nil)
    61  	}
    62  }
    63  
    64  func main() {
    65  	go cpuHogGoFunction()
    66  	go cpuHogCFunction()
    67  	runtime.Gosched()
    68  
    69  	if err := pprof.StartCPUProfile(os.Stdout); err != nil {
    70  		log.Fatal("can't start CPU profile: ", err)
    71  	}
    72  	time.Sleep(1 * time.Second)
    73  	pprof.StopCPUProfile()
    74  
    75  	if err := os.Stdout.Close(); err != nil {
    76  		log.Fatal("can't write CPU profile: ", err)
    77  	}
    78  }
    79  
    80  var salt1 int
    81  var salt2 int
    82  
    83  func cpuHogGoFunction() {
    84  	// Generates CPU profile samples including a Go call path.
    85  	for {
    86  		foo := salt1
    87  		for i := 0; i < 1e5; i++ {
    88  			if foo > 0 {
    89  				foo *= foo
    90  			} else {
    91  				foo *= foo + 1
    92  			}
    93  			salt2 = foo
    94  		}
    95  		runtime.Gosched()
    96  	}
    97  }
    98  
    99  func cpuHogCFunction() {
   100  	// Generates CPU profile samples including a Cgo call path.
   101  	for {
   102  		C.CPUHogCFunction()
   103  		runtime.Gosched()
   104  	}
   105  }