// Copyright 2015 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.

package main

/*
void foo1(void) {}
void foo2(void* p) {}
*/
import "C"
import (
	"fmt"
	"os"
	"runtime"
	"strconv"
	"time"
	"unsafe"
)

func init() {
	register("CgoSignalDeadlock", CgoSignalDeadlock)
	register("CgoTraceback", CgoTraceback)
	register("CgoCheckBytes", CgoCheckBytes)
}

func CgoSignalDeadlock() {
	runtime.GOMAXPROCS(100)
	ping := make(chan bool)
	go func() {
		for i := 0; ; i++ {
			runtime.Gosched()
			select {
			case done := <-ping:
				if done {
					ping <- true
					return
				}
				ping <- true
			default:
			}
			func() {
				defer func() {
					recover()
				}()
				var s *string
				*s = ""
			}()
		}
	}()
	time.Sleep(time.Millisecond)
	for i := 0; i < 64; i++ {
		go func() {
			runtime.LockOSThread()
			select {}
		}()
		go func() {
			runtime.LockOSThread()
			select {}
		}()
		time.Sleep(time.Millisecond)
		ping <- false
		select {
		case <-ping:
		case <-time.After(time.Second):
			fmt.Printf("HANG\n")
			return
		}
	}
	ping <- true
	select {
	case <-ping:
	case <-time.After(time.Second):
		fmt.Printf("HANG\n")
		return
	}
	fmt.Printf("OK\n")
}

func CgoTraceback() {
	C.foo1()
	buf := make([]byte, 1)
	runtime.Stack(buf, true)
	fmt.Printf("OK\n")
}

func CgoCheckBytes() {
	try, _ := strconv.Atoi(os.Getenv("GO_CGOCHECKBYTES_TRY"))
	if try <= 0 {
		try = 1
	}
	b := make([]byte, 1e6*try)
	start := time.Now()
	for i := 0; i < 1e3*try; i++ {
		C.foo2(unsafe.Pointer(&b[0]))
		if time.Since(start) > time.Second {
			break
		}
	}
}
