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