Source file src/cmd/cgo/internal/testsanitizers/testdata/tsan9.go

     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  

View as plain text