github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/runtime/testdata/testprogcgo/cgo.go (about)

     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  	for i := 0; i < 64; i++ {
    56  		go func() {
    57  			runtime.LockOSThread()
    58  			select {}
    59  		}()
    60  		go func() {
    61  			runtime.LockOSThread()
    62  			select {}
    63  		}()
    64  		time.Sleep(time.Millisecond)
    65  		ping <- false
    66  		select {
    67  		case <-ping:
    68  			times = append(times, time.Since(start))
    69  		case <-time.After(time.Second):
    70  			fmt.Printf("HANG 1 %v\n", times)
    71  			return
    72  		}
    73  	}
    74  	ping <- true
    75  	select {
    76  	case <-ping:
    77  	case <-time.After(time.Second):
    78  		fmt.Printf("HANG 2 %v\n", times)
    79  		return
    80  	}
    81  	fmt.Printf("OK\n")
    82  }
    83  
    84  func CgoTraceback() {
    85  	C.foo1()
    86  	buf := make([]byte, 1)
    87  	runtime.Stack(buf, true)
    88  	fmt.Printf("OK\n")
    89  }
    90  
    91  func CgoCheckBytes() {
    92  	try, _ := strconv.Atoi(os.Getenv("GO_CGOCHECKBYTES_TRY"))
    93  	if try <= 0 {
    94  		try = 1
    95  	}
    96  	b := make([]byte, 1e6*try)
    97  	start := time.Now()
    98  	for i := 0; i < 1e3*try; i++ {
    99  		C.foo2(unsafe.Pointer(&b[0]))
   100  		if time.Since(start) > time.Second {
   101  			break
   102  		}
   103  	}
   104  }