github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/runtime/testdata/testprogcgo/threadpprof.go (about) 1 // Copyright 2016 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 // Run a slow C function saving a CPU profile. 10 11 /* 12 #include <stdint.h> 13 #include <time.h> 14 #include <pthread.h> 15 16 int threadSalt1; 17 int threadSalt2; 18 19 void cpuHogThread() { 20 int foo = threadSalt1; 21 int i; 22 23 for (i = 0; i < 100000; i++) { 24 if (foo > 0) { 25 foo *= foo; 26 } else { 27 foo *= foo + 1; 28 } 29 } 30 threadSalt2 = foo; 31 } 32 33 void cpuHogThread2() { 34 } 35 36 struct cgoTracebackArg { 37 uintptr_t context; 38 uintptr_t sigContext; 39 uintptr_t* buf; 40 uintptr_t max; 41 }; 42 43 // pprofCgoThreadTraceback is passed to runtime.SetCgoTraceback. 44 // For testing purposes it pretends that all CPU hits in C code are in cpuHog. 45 void pprofCgoThreadTraceback(void* parg) { 46 struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg); 47 arg->buf[0] = (uintptr_t)(cpuHogThread) + 0x10; 48 arg->buf[1] = (uintptr_t)(cpuHogThread2) + 0x4; 49 arg->buf[2] = 0; 50 } 51 52 static void* cpuHogDriver(void* arg __attribute__ ((unused))) { 53 while (1) { 54 cpuHogThread(); 55 } 56 return 0; 57 } 58 59 void runCPUHogThread(void) { 60 pthread_t tid; 61 pthread_create(&tid, 0, cpuHogDriver, 0); 62 } 63 */ 64 import "C" 65 66 import ( 67 "fmt" 68 "os" 69 "runtime" 70 "runtime/pprof" 71 "time" 72 "unsafe" 73 ) 74 75 func init() { 76 register("CgoPprofThread", CgoPprofThread) 77 register("CgoPprofThreadNoTraceback", CgoPprofThreadNoTraceback) 78 } 79 80 func CgoPprofThread() { 81 runtime.SetCgoTraceback(0, unsafe.Pointer(C.pprofCgoThreadTraceback), nil, nil) 82 pprofThread() 83 } 84 85 func CgoPprofThreadNoTraceback() { 86 pprofThread() 87 } 88 89 func pprofThread() { 90 f, err := os.CreateTemp("", "prof") 91 if err != nil { 92 fmt.Fprintln(os.Stderr, err) 93 os.Exit(2) 94 } 95 96 if err := pprof.StartCPUProfile(f); err != nil { 97 fmt.Fprintln(os.Stderr, err) 98 os.Exit(2) 99 } 100 101 C.runCPUHogThread() 102 103 time.Sleep(1*time.Second) 104 105 pprof.StopCPUProfile() 106 107 name := f.Name() 108 if err := f.Close(); err != nil { 109 fmt.Fprintln(os.Stderr, err) 110 os.Exit(2) 111 } 112 113 fmt.Println(name) 114 }