github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/runtime/testdata/testprogcgo/raceprof.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 linux,amd64 6 7 package main 8 9 // Test that we can collect a lot of colliding profiling signals from 10 // an external C thread. This used to fail when built with the race 11 // detector, because a call of the predeclared function copy was 12 // turned into a call to runtime.slicecopy, which is not marked nosplit. 13 14 /* 15 #include <signal.h> 16 #include <stdint.h> 17 #include <pthread.h> 18 #include <sched.h> 19 20 struct cgoTracebackArg { 21 uintptr_t context; 22 uintptr_t sigContext; 23 uintptr_t* buf; 24 uintptr_t max; 25 }; 26 27 static int raceprofCount; 28 29 // We want a bunch of different profile stacks that collide in the 30 // hash table maintained in runtime/cpuprof.go. This code knows the 31 // size of the hash table (1 << 10) and knows that the hash function 32 // is simply multiplicative. 33 void raceprofTraceback(void* parg) { 34 struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg); 35 raceprofCount++; 36 arg->buf[0] = raceprofCount * (1 << 10); 37 arg->buf[1] = 0; 38 } 39 40 static void* raceprofThread(void* p) { 41 int i; 42 43 for (i = 0; i < 100; i++) { 44 pthread_kill(pthread_self(), SIGPROF); 45 sched_yield(); 46 } 47 return 0; 48 } 49 50 void runRaceprofThread() { 51 pthread_t tid; 52 pthread_create(&tid, 0, raceprofThread, 0); 53 pthread_join(tid, 0); 54 } 55 */ 56 import "C" 57 58 import ( 59 "bytes" 60 "fmt" 61 "runtime" 62 "runtime/pprof" 63 "unsafe" 64 ) 65 66 func init() { 67 register("CgoRaceprof", CgoRaceprof) 68 } 69 70 func CgoRaceprof() { 71 runtime.SetCgoTraceback(0, unsafe.Pointer(C.raceprofTraceback), nil, nil) 72 73 var buf bytes.Buffer 74 pprof.StartCPUProfile(&buf) 75 76 C.runRaceprofThread() 77 fmt.Println("OK") 78 }