gcc/libgo/go/runtime/testdata/testprogcgo/threadprof.go
Ian Lance Taylor c2047754c3 libgo: update to Go 1.8 release candidate 1
Compiler changes:
      * Change map assignment to use mapassign and assign value directly.
      * Change string iteration to use decoderune, faster for ASCII strings.
      * Change makeslice to take int, and use makeslice64 for larger values.
      * Add new noverflow field to hmap struct used for maps.
    
    Unresolved problems, to be fixed later:
      * Commented out test in go/types/sizes_test.go that doesn't compile.
      * Commented out reflect.TestStructOf test for padding after zero-sized field.
    
    Reviewed-on: https://go-review.googlesource.com/35231

gotools/:
	Updates for Go 1.8rc1.
	* Makefile.am (go_cmd_go_files): Add bug.go.
	(s-zdefaultcc): Write defaultPkgConfig.
	* Makefile.in: Rebuild.

From-SVN: r244456
2017-01-14 00:05:42 +00:00

99 lines
2.1 KiB
Go

// Copyright 2015 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.
// We only build this file with the tag "threadprof", since it starts
// a thread running a busy loop at constructor time.
// +build !plan9,!windows
// +build threadprof
package main
/*
#include <stdint.h>
#include <signal.h>
#include <pthread.h>
volatile int32_t spinlock;
static void *thread1(void *p) {
(void)p;
while (spinlock == 0)
;
pthread_kill(pthread_self(), SIGPROF);
spinlock = 0;
return NULL;
}
__attribute__((constructor)) void issue9456() {
pthread_t tid;
pthread_create(&tid, 0, thread1, NULL);
}
void **nullptr;
void *crash(void *p) {
*nullptr = p;
return 0;
}
int start_crashing_thread(void) {
pthread_t tid;
return pthread_create(&tid, 0, crash, 0);
}
*/
import "C"
import (
"fmt"
"os"
"os/exec"
"runtime"
"sync/atomic"
"time"
"unsafe"
)
func init() {
register("CgoExternalThreadSIGPROF", CgoExternalThreadSIGPROF)
register("CgoExternalThreadSignal", CgoExternalThreadSignal)
}
func CgoExternalThreadSIGPROF() {
// This test intends to test that sending SIGPROF to foreign threads
// before we make any cgo call will not abort the whole process, so
// we cannot make any cgo call here. See https://golang.org/issue/9456.
atomic.StoreInt32((*int32)(unsafe.Pointer(&C.spinlock)), 1)
for atomic.LoadInt32((*int32)(unsafe.Pointer(&C.spinlock))) == 1 {
runtime.Gosched()
}
println("OK")
}
func CgoExternalThreadSignal() {
if len(os.Args) > 2 && os.Args[2] == "crash" {
i := C.start_crashing_thread()
if i != 0 {
fmt.Println("pthread_create failed:", i)
// Exit with 0 because parent expects us to crash.
return
}
// We should crash immediately, but give it plenty of
// time before failing (by exiting 0) in case we are
// running on a slow system.
time.Sleep(5 * time.Second)
return
}
out, err := exec.Command(os.Args[0], "CgoExternalThreadSignal", "crash").CombinedOutput()
if err == nil {
fmt.Println("C signal did not crash as expected")
fmt.Printf("\n%s\n", out)
os.Exit(1)
}
fmt.Println("OK")
}