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" 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(io.Discard) 64 go C.spin() 65 goSpin() 66 pprof.StopCPUProfile() 67 } 68