aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/testdata/testprogcgo
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2017-01-14 00:05:42 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2017-01-14 00:05:42 +0000
commitc2047754c300b68c05d65faa8dc2925fe67b71b4 (patch)
treee183ae81a1f48a02945cb6de463a70c5be1b06f6 /libgo/go/runtime/testdata/testprogcgo
parent829afb8f05602bb31c9c597b24df7377fed4f059 (diff)
downloadgcc-c2047754c300b68c05d65faa8dc2925fe67b71b4.zip
gcc-c2047754c300b68c05d65faa8dc2925fe67b71b4.tar.gz
gcc-c2047754c300b68c05d65faa8dc2925fe67b71b4.tar.bz2
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
Diffstat (limited to 'libgo/go/runtime/testdata/testprogcgo')
-rw-r--r--libgo/go/runtime/testdata/testprogcgo/pprof.go2
-rw-r--r--libgo/go/runtime/testdata/testprogcgo/raceprof.go78
-rw-r--r--libgo/go/runtime/testdata/testprogcgo/racesig.go102
-rw-r--r--libgo/go/runtime/testdata/testprogcgo/threadpprof.go35
-rw-r--r--libgo/go/runtime/testdata/testprogcgo/threadprof.go9
5 files changed, 211 insertions, 15 deletions
diff --git a/libgo/go/runtime/testdata/testprogcgo/pprof.go b/libgo/go/runtime/testdata/testprogcgo/pprof.go
index cb30ec5..4460b93 100644
--- a/libgo/go/runtime/testdata/testprogcgo/pprof.go
+++ b/libgo/go/runtime/testdata/testprogcgo/pprof.go
@@ -1,4 +1,4 @@
-// Copyright 2016 The Go Authors. All rights reserved.
+// 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.
diff --git a/libgo/go/runtime/testdata/testprogcgo/raceprof.go b/libgo/go/runtime/testdata/testprogcgo/raceprof.go
new file mode 100644
index 0000000..fe624c5
--- /dev/null
+++ b/libgo/go/runtime/testdata/testprogcgo/raceprof.go
@@ -0,0 +1,78 @@
+// 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.
+
+// +build linux,amd64
+
+package main
+
+// Test that we can collect a lot of colliding profiling signals from
+// an external C thread. This used to fail when built with the race
+// detector, because a call of the predeclared function copy was
+// turned into a call to runtime.slicecopy, which is not marked nosplit.
+
+/*
+#include <signal.h>
+#include <stdint.h>
+#include <pthread.h>
+#include <sched.h>
+
+struct cgoTracebackArg {
+ uintptr_t context;
+ uintptr_t sigContext;
+ uintptr_t* buf;
+ uintptr_t max;
+};
+
+static int raceprofCount;
+
+// We want a bunch of different profile stacks that collide in the
+// hash table maintained in runtime/cpuprof.go. This code knows the
+// size of the hash table (1 << 10) and knows that the hash function
+// is simply multiplicative.
+void raceprofTraceback(void* parg) {
+ struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
+ raceprofCount++;
+ arg->buf[0] = raceprofCount * (1 << 10);
+ arg->buf[1] = 0;
+}
+
+static void* raceprofThread(void* p) {
+ int i;
+
+ for (i = 0; i < 100; i++) {
+ pthread_kill(pthread_self(), SIGPROF);
+ sched_yield();
+ }
+ return 0;
+}
+
+void runRaceprofThread() {
+ pthread_t tid;
+ pthread_create(&tid, 0, raceprofThread, 0);
+ pthread_join(tid, 0);
+}
+*/
+import "C"
+
+import (
+ "bytes"
+ "fmt"
+ "runtime"
+ "runtime/pprof"
+ "unsafe"
+)
+
+func init() {
+ register("CgoRaceprof", CgoRaceprof)
+}
+
+func CgoRaceprof() {
+ runtime.SetCgoTraceback(0, unsafe.Pointer(C.raceprofTraceback), nil, nil)
+
+ var buf bytes.Buffer
+ pprof.StartCPUProfile(&buf)
+
+ C.runRaceprofThread()
+ fmt.Println("OK")
+}
diff --git a/libgo/go/runtime/testdata/testprogcgo/racesig.go b/libgo/go/runtime/testdata/testprogcgo/racesig.go
new file mode 100644
index 0000000..d0c1c3c
--- /dev/null
+++ b/libgo/go/runtime/testdata/testprogcgo/racesig.go
@@ -0,0 +1,102 @@
+// 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.
+
+// +build linux,amd64
+
+package main
+
+// Test that an external C thread that is calling malloc can be hit
+// with SIGCHLD signals. This used to fail when built with the race
+// detector, because in that case the signal handler would indirectly
+// call the C malloc function.
+
+/*
+#include <errno.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sched.h>
+#include <unistd.h>
+
+#define ALLOCERS 100
+#define SIGNALERS 10
+
+static void* signalThread(void* p) {
+ pthread_t* pt = (pthread_t*)(p);
+ int i, j;
+
+ for (i = 0; i < 100; i++) {
+ for (j = 0; j < ALLOCERS; j++) {
+ if (pthread_kill(pt[j], SIGCHLD) < 0) {
+ return NULL;
+ }
+ }
+ usleep(1);
+ }
+ return NULL;
+}
+
+#define CALLS 100
+
+static void* mallocThread(void* p) {
+ int i;
+ void *a[CALLS];
+
+ for (i = 0; i < ALLOCERS; i++) {
+ sched_yield();
+ }
+ for (i = 0; i < CALLS; i++) {
+ a[i] = malloc(i);
+ }
+ for (i = 0; i < CALLS; i++) {
+ free(a[i]);
+ }
+ return NULL;
+}
+
+void runRaceSignalThread() {
+ int i;
+ pthread_t m[ALLOCERS];
+ pthread_t s[SIGNALERS];
+
+ for (i = 0; i < ALLOCERS; i++) {
+ pthread_create(&m[i], NULL, mallocThread, NULL);
+ }
+ for (i = 0; i < SIGNALERS; i++) {
+ pthread_create(&s[i], NULL, signalThread, &m[0]);
+ }
+ for (i = 0; i < SIGNALERS; i++) {
+ pthread_join(s[i], NULL);
+ }
+ for (i = 0; i < ALLOCERS; i++) {
+ pthread_join(m[i], NULL);
+ }
+}
+*/
+import "C"
+
+import (
+ "fmt"
+ "os"
+ "time"
+)
+
+func init() {
+ register("CgoRaceSignal", CgoRaceSignal)
+}
+
+func CgoRaceSignal() {
+ // The failure symptom is that the program hangs because of a
+ // deadlock in malloc, so set an alarm.
+ go func() {
+ time.Sleep(5 * time.Second)
+ fmt.Println("Hung for 5 seconds")
+ os.Exit(1)
+ }()
+
+ C.runRaceSignalThread()
+ fmt.Println("OK")
+}
diff --git a/libgo/go/runtime/testdata/testprogcgo/threadpprof.go b/libgo/go/runtime/testdata/testprogcgo/threadpprof.go
index fdeee69..44afb91 100644
--- a/libgo/go/runtime/testdata/testprogcgo/threadpprof.go
+++ b/libgo/go/runtime/testdata/testprogcgo/threadpprof.go
@@ -1,4 +1,4 @@
-// Copyright 2016 The Go Authors. All rights reserved.
+// 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.
@@ -39,17 +39,6 @@ struct cgoTracebackArg {
uintptr_t max;
};
-static void *pprofThread(void* p) {
- time_t start;
-
- (void)p;
- start = time(NULL);
- while (__sync_add_and_fetch(&cpuHogThreadCount, 0) < 2 && time(NULL) - start < 2) {
- cpuHogThread();
- }
-}
-
-
// pprofCgoThreadTraceback is passed to runtime.SetCgoTraceback.
// For testing purposes it pretends that all CPU hits in C code are in cpuHog.
void pprofCgoThreadTraceback(void* parg) {
@@ -64,6 +53,18 @@ void pprofCgoThreadTraceback(void* parg) {
int getCPUHogThreadCount() {
return __sync_add_and_fetch(&cpuHogThreadCount, 0);
}
+
+static void* cpuHogDriver(void* arg __attribute__ ((unused))) {
+ while (1) {
+ cpuHogThread();
+ }
+ return 0;
+}
+
+void runCPUHogThread() {
+ pthread_t tid;
+ pthread_create(&tid, 0, cpuHogDriver, 0);
+}
*/
import "C"
@@ -79,11 +80,19 @@ import (
func init() {
register("CgoPprofThread", CgoPprofThread)
+ register("CgoPprofThreadNoTraceback", CgoPprofThreadNoTraceback)
}
func CgoPprofThread() {
runtime.SetCgoTraceback(0, unsafe.Pointer(C.pprofCgoThreadTraceback), nil, nil)
+ pprofThread()
+}
+
+func CgoPprofThreadNoTraceback() {
+ pprofThread()
+}
+func pprofThread() {
f, err := ioutil.TempFile("", "prof")
if err != nil {
fmt.Fprintln(os.Stderr, err)
@@ -95,6 +104,8 @@ func CgoPprofThread() {
os.Exit(2)
}
+ C.runCPUHogThread()
+
t0 := time.Now()
for C.getCPUHogThreadCount() < 2 && time.Since(t0) < time.Second {
time.Sleep(100 * time.Millisecond)
diff --git a/libgo/go/runtime/testdata/testprogcgo/threadprof.go b/libgo/go/runtime/testdata/testprogcgo/threadprof.go
index a77479d..2d4c103 100644
--- a/libgo/go/runtime/testdata/testprogcgo/threadprof.go
+++ b/libgo/go/runtime/testdata/testprogcgo/threadprof.go
@@ -2,7 +2,11 @@
// 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
@@ -21,6 +25,7 @@ static void *thread1(void *p) {
spinlock = 0;
return NULL;
}
+
__attribute__((constructor)) void issue9456() {
pthread_t tid;
pthread_create(&tid, 0, thread1, NULL);
@@ -84,8 +89,8 @@ func CgoExternalThreadSignal() {
out, err := exec.Command(os.Args[0], "CgoExternalThreadSignal", "crash").CombinedOutput()
if err == nil {
- fmt.Println("C signal did not crash as expected\n")
- fmt.Printf("%s\n", out)
+ fmt.Println("C signal did not crash as expected")
+ fmt.Printf("\n%s\n", out)
os.Exit(1)
}