Source file src/runtime/pprof/testdata/mappingtest/main.go

     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 CPUHogCFunction0(int foo) {
    21  	int i;
    22  	for (i = 0; i < 100000; i++) {
    23  		if (foo > 0) {
    24  			foo *= foo;
    25  		} else {
    26  			foo *= foo + 1;
    27  		}
    28  		cpuHogCSalt2 = foo;
    29  	}
    30  }
    31  
    32  void CPUHogCFunction() {
    33  	CPUHogCFunction0(cpuHogCSalt1);
    34  }
    35  
    36  struct CgoTracebackArg {
    37  	uintptr_t context;
    38          uintptr_t sigContext;
    39  	uintptr_t *buf;
    40          uintptr_t max;
    41  };
    42  
    43  void CollectCgoTraceback(void* parg) {
    44          struct CgoTracebackArg* arg = (struct CgoTracebackArg*)(parg);
    45  	arg->buf[0] = (uintptr_t)(CPUHogCFunction0);
    46  	arg->buf[1] = (uintptr_t)(CPUHogCFunction);
    47  	arg->buf[2] = 0;
    48  };
    49  */
    50  import "C"
    51  
    52  import (
    53  	"log"
    54  	"os"
    55  	"runtime"
    56  	"runtime/pprof"
    57  	"time"
    58  	"unsafe"
    59  )
    60  
    61  func init() {
    62  	if v := os.Getenv("SETCGOTRACEBACK"); v == "1" {
    63  		// Collect some PCs from C-side, but don't symbolize.
    64  		runtime.SetCgoTraceback(0, unsafe.Pointer(C.CollectCgoTraceback), nil, nil)
    65  	}
    66  }
    67  
    68  func main() {
    69  	go cpuHogGoFunction()
    70  	go cpuHogCFunction()
    71  	runtime.Gosched()
    72  
    73  	if err := pprof.StartCPUProfile(os.Stdout); err != nil {
    74  		log.Fatal("can't start CPU profile: ", err)
    75  	}
    76  	time.Sleep(200 * time.Millisecond)
    77  	pprof.StopCPUProfile()
    78  
    79  	if err := os.Stdout.Close(); err != nil {
    80  		log.Fatal("can't write CPU profile: ", err)
    81  	}
    82  }
    83  
    84  var salt1 int
    85  var salt2 int
    86  
    87  func cpuHogGoFunction() {
    88  	for {
    89  		foo := salt1
    90  		for i := 0; i < 1e5; i++ {
    91  			if foo > 0 {
    92  				foo *= foo
    93  			} else {
    94  				foo *= foo + 1
    95  			}
    96  			salt2 = foo
    97  		}
    98  		runtime.Gosched()
    99  	}
   100  }
   101  
   102  func cpuHogCFunction() {
   103  	// Generates CPU profile samples including a Cgo call path.
   104  	for {
   105  		C.CPUHogCFunction()
   106  		runtime.Gosched()
   107  	}
   108  }
   109  

View as plain text