github.com/s1s1ty/go@v0.0.0-20180207192209-104445e3140f/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  }