Home | History | Annotate | Download | only in src
      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 package main
      6 
      7 // This program failed when run under the C/C++ ThreadSanitizer. The
      8 // TSAN library was not keeping track of whether signals should be
      9 // delivered on the alternate signal stack, and the Go signal handler
     10 // was not preserving callee-saved registers from C callers.
     11 
     12 /*
     13 #cgo CFLAGS: -g -fsanitize=thread
     14 #cgo LDFLAGS: -g -fsanitize=thread
     15 
     16 #include <stdlib.h>
     17 #include <sys/time.h>
     18 
     19 void spin() {
     20 	size_t n;
     21 	struct timeval tvstart, tvnow;
     22 	int diff;
     23 	void *prev = NULL, *cur;
     24 
     25 	gettimeofday(&tvstart, NULL);
     26 	for (n = 0; n < 1<<20; n++) {
     27 		cur = malloc(n);
     28 		free(prev);
     29 		prev = cur;
     30 
     31 		gettimeofday(&tvnow, NULL);
     32 		diff = (tvnow.tv_sec - tvstart.tv_sec) * 1000 * 1000 + (tvnow.tv_usec - tvstart.tv_usec);
     33 
     34 		// Profile frequency is 100Hz so we should definitely
     35 		// get a signal in 50 milliseconds.
     36 		if (diff > 50 * 1000) {
     37 			break;
     38 		}
     39 	}
     40 
     41 	free(prev);
     42 }
     43 */
     44 import "C"
     45 
     46 import (
     47 	"io/ioutil"
     48 	"runtime/pprof"
     49 	"time"
     50 )
     51 
     52 func goSpin() {
     53 	start := time.Now()
     54 	for n := 0; n < 1<<20; n++ {
     55 		_ = make([]byte, n)
     56 		if time.Since(start) > 50*time.Millisecond {
     57 			break
     58 		}
     59 	}
     60 }
     61 
     62 func main() {
     63 	pprof.StartCPUProfile(ioutil.Discard)
     64 	go C.spin()
     65 	goSpin()
     66 	pprof.StopCPUProfile()
     67 }
     68