blob: f166d8b495ac458a4a6dd236d0913cd90a68a0e9 [file] [log] [blame]
Dan Willemsenebae3022017-01-13 23:01:08 -08001// 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
5package 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
19void 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*/
44import "C"
45
46import (
47 "io/ioutil"
48 "runtime/pprof"
49 "time"
50)
51
52func 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
62func main() {
63 pprof.StartCPUProfile(ioutil.Discard)
64 go C.spin()
65 goSpin()
66 pprof.StopCPUProfile()
67}