// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package main // This program failed when run under the C/C++ ThreadSanitizer. The // TSAN library was not keeping track of whether signals should be // delivered on the alternate signal stack, and the Go signal handler // was not preserving callee-saved registers from C callers. /* #cgo CFLAGS: -g -fsanitize=thread #cgo LDFLAGS: -g -fsanitize=thread #include <stdlib.h> #include <sys/time.h> void spin() { size_t n; struct timeval tvstart, tvnow; int diff; void *prev = NULL, *cur; gettimeofday(&tvstart, NULL); for (n = 0; n < 1<<20; n++) { cur = malloc(n); free(prev); prev = cur; gettimeofday(&tvnow, NULL); diff = (tvnow.tv_sec - tvstart.tv_sec) * 1000 * 1000 + (tvnow.tv_usec - tvstart.tv_usec); // Profile frequency is 100Hz so we should definitely // get a signal in 50 milliseconds. if (diff > 50 * 1000) { break; } } free(prev); } */ import "C" import ( "io/ioutil" "runtime/pprof" "time" ) func goSpin() { start := time.Now() for n := 0; n < 1<<20; n++ { _ = make([]byte, n) if time.Since(start) > 50*time.Millisecond { break } } } func main() { pprof.StartCPUProfile(ioutil.Discard) go C.spin() goSpin() pprof.StopCPUProfile() }