Source file src/runtime/testdata/testprogcgo/cgo.go

     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  

View as plain text