Home | History | Annotate | Download | only in testprogcgo
      1 // Copyright 2015 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 /*
      8 void foo1(void) {}
      9 void foo2(void* p) {}
     10 */
     11 import "C"
     12 import (
     13 	"fmt"
     14 	"os"
     15 	"runtime"
     16 	"strconv"
     17 	"time"
     18 	"unsafe"
     19 )
     20 
     21 func init() {
     22 	register("CgoSignalDeadlock", CgoSignalDeadlock)
     23 	register("CgoTraceback", CgoTraceback)
     24 	register("CgoCheckBytes", CgoCheckBytes)
     25 }
     26 
     27 func CgoSignalDeadlock() {
     28 	runtime.GOMAXPROCS(100)
     29 	ping := make(chan bool)
     30 	go func() {
     31 		for i := 0; ; i++ {
     32 			runtime.Gosched()
     33 			select {
     34 			case done := <-ping:
     35 				if done {
     36 					ping <- true
     37 					return
     38 				}
     39 				ping <- true
     40 			default:
     41 			}
     42 			func() {
     43 				defer func() {
     44 					recover()
     45 				}()
     46 				var s *string
     47 				*s = ""
     48 				fmt.Printf("continued after expected panic\n")
     49 			}()
     50 		}
     51 	}()
     52 	time.Sleep(time.Millisecond)
     53 	start := time.Now()
     54 	var times []time.Duration
     55 	n := 64
     56 	if os.Getenv("RUNTIME_TEST_SHORT") != "" {
     57 		n = 16
     58 	}
     59 	for i := 0; i < n; i++ {
     60 		go func() {
     61 			runtime.LockOSThread()
     62 			select {}
     63 		}()
     64 		go func() {
     65 			runtime.LockOSThread()
     66 			select {}
     67 		}()
     68 		time.Sleep(time.Millisecond)
     69 		ping <- false
     70 		select {
     71 		case <-ping:
     72 			times = append(times, time.Since(start))
     73 		case <-time.After(time.Second):
     74 			fmt.Printf("HANG 1 %v\n", times)
     75 			return
     76 		}
     77 	}
     78 	ping <- true
     79 	select {
     80 	case <-ping:
     81 	case <-time.After(time.Second):
     82 		fmt.Printf("HANG 2 %v\n", times)
     83 		return
     84 	}
     85 	fmt.Printf("OK\n")
     86 }
     87 
     88 func CgoTraceback() {
     89 	C.foo1()
     90 	buf := make([]byte, 1)
     91 	runtime.Stack(buf, true)
     92 	fmt.Printf("OK\n")
     93 }
     94 
     95 func CgoCheckBytes() {
     96 	try, _ := strconv.Atoi(os.Getenv("GO_CGOCHECKBYTES_TRY"))
     97 	if try <= 0 {
     98 		try = 1
     99 	}
    100 	b := make([]byte, 1e6*try)
    101 	start := time.Now()
    102 	for i := 0; i < 1e3*try; i++ {
    103 		C.foo2(unsafe.Pointer(&b[0]))
    104 		if time.Since(start) > time.Second {
    105 			break
    106 		}
    107 	}
    108 }
    109