// Code generated by cmd/cgo; DO NOT EDIT.

//line /home/evie/packages/go/go-1.18-0/go/misc/cgo/test/testx.go:1:1
// Copyright 2011 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.

// Test cases for cgo.
// Both the import "C" prologue and the main file are sorted by issue number.
// This file contains //export directives on Go functions
// and so it must NOT contain C definitions (only declarations).
// See test.go for C definitions.

package cgotest

import (
	"runtime"
	"runtime/cgo"
	"runtime/debug"
	"strings"
	"sync"
	"sync/atomic"
	"testing"
	"time"
	"unsafe"
)

/*
// threads
extern void doAdd(int, int);

// issue 1328
void IntoC(void);

// issue 1560
// mysleep returns the absolute start time in ms.
long long mysleep(int seconds);

// twoSleep returns the absolute start time of the first sleep
// in ms.
long long twoSleep(int);

// issue 3775
void lockOSThreadC(void);
int usleep(unsigned usec);

// issue 4054 part 2 - part 1 in test.go
typedef enum {
	A = 0,
	B,
	C,
	D,
	E,
	F,
	G,
	H,
	II,
	J,
} issue4054b;

// issue 5548

extern int issue5548_in_c(void);

// issue 6833

extern unsigned long long issue6833Func(unsigned int, unsigned long long);

// issue 6907

extern int CheckIssue6907C(_GoString_);

// issue 7665

extern void f7665(void);

// issue 7978
// Stack tracing didn't work during cgo code after calling a Go
// callback.  Make sure GC works and the stack trace is correct.

#include <stdint.h>

// use ugly atomic variable sync since that doesn't require calling back into
// Go code or OS dependencies
void issue7978c(uint32_t *sync);

// issue 8331 part 2 - part 1 in test.go
// A typedef of an unnamed struct is the same struct when
// #include'd twice.  No runtime test; just make sure it compiles.
#include "issue8331.h"

// issue 8945

typedef void (*PFunc8945)();
extern PFunc8945 func8945; // definition is in test.go

// issue 20910
void callMulti(void);

// issue 28772 part 2 - part 1 in issuex.go
#define issue28772Constant2 2


// issue 31891
typedef struct {
	long obj;
} Issue31891A;

typedef struct {
	long obj;
} Issue31891B;

void callIssue31891(void);

typedef struct {
	int i;
} Issue38408, *PIssue38408;

extern void cfunc49633(void*); // definition is in test.go
*/
import _ "unsafe"

// exports

//export ReturnIntLong
func ReturnIntLong() (int,  /*line :123:28*/_Ctype_long /*line :123:34*/) {
	return 1, 2
}

//export gc
func gc() {
	runtime.GC()
}

// threads

var sum struct {
	sync.Mutex
	i int
}

//export Add
func Add(x int) {
	defer func() {
		recover()
	}()
	sum.Lock()
	sum.i += x
	sum.Unlock()
	var p *int
	*p = 2
}

func testCthread(t *testing.T) {
	if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && runtime.GOARCH == "arm64" {
		t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add")
	}
	sum.i = 0
	( /*line :156:2*/_Cfunc_doAdd /*line :156:8*/)(10, 6)

	want := 10 * (10 - 1) / 2 * 6
	if sum.i != want {
		t.Fatalf("sum=%d, want %d", sum.i, want)
	}
}

// issue 1328

//export BackIntoGo
func BackIntoGo() {
	x := 1

	for i := 0; i < 10000; i++ {
		xvariadic(x)
		if x != 1 {
			panic("x is not 1?")
		}
	}
}

func xvariadic(x ...interface{}) {
}

func test1328(t *testing.T) {
	( /*line :182:2*/_Cfunc_IntoC /*line :182:8*/)()
}

// issue 1560

var sleepDone = make(chan int64)

// parallelSleep returns the absolute difference between the start time
// of the two sleeps.
func parallelSleep(n int) int64 {
	t := int64(( /*line :192:13*/_Cfunc_twoSleep /*line :192:22*/)( /*line :192:24*/_Ctype_int /*line :192:29*/(n))) - <-sleepDone
	if t < 0 {
		return -t
	}
	return t
}

//export BackgroundSleep
func BackgroundSleep(n int32) {
	go func() {
		sleepDone <- int64(( /*line :202:22*/_Cfunc_mysleep /*line :202:30*/)( /*line :202:32*/_Ctype_int /*line :202:37*/(n)))
	}()
}

func testParallelSleep(t *testing.T) {
	sleepSec := 1
	dt := time.Duration(parallelSleep(sleepSec)) * time.Millisecond
	t.Logf("difference in start time for two sleep(%d) is %v", sleepSec, dt)
	// bug used to run sleeps in serial, producing a 2*sleepSec-second delay.
	// we detect if the start times of those sleeps are > 0.5*sleepSec-second.
	if dt >= time.Duration(sleepSec)*time.Second/2 {
		t.Fatalf("parallel %d-second sleeps slept for %f seconds", sleepSec, dt.Seconds())
	}
}

// issue 2462

//export exportbyte
func exportbyte() byte {
	return 0
}

//export exportbool
func exportbool() bool {
	return false
}

//export exportrune
func exportrune() rune {
	return 0
}

//export exporterror
func exporterror() error {
	return nil
}

//export exportint
func exportint() int {
	return 0
}

//export exportuint
func exportuint() uint {
	return 0
}

//export exportuintptr
func exportuintptr() uintptr {
	return (uintptr)(0)
}

//export exportint8
func exportint8() int8 {
	return 0
}

//export exportuint8
func exportuint8() uint8 {
	return 0
}

//export exportint16
func exportint16() int16 {
	return 0
}

//export exportuint16
func exportuint16() uint16 {
	return 0
}

//export exportint32
func exportint32() int32 {
	return 0
}

//export exportuint32
func exportuint32() uint32 {
	return 0
}

//export exportint64
func exportint64() int64 {
	return 0
}

//export exportuint64
func exportuint64() uint64 {
	return 0
}

//export exportfloat32
func exportfloat32() float32 {
	return 0
}

//export exportfloat64
func exportfloat64() float64 {
	return 0
}

//export exportcomplex64
func exportcomplex64() complex64 {
	return 0
}

//export exportcomplex128
func exportcomplex128() complex128 {
	return 0
}

// issue 3741

//export exportSliceIn
func exportSliceIn(s []byte) bool {
	return len(s) == cap(s)
}

//export exportSliceOut
func exportSliceOut() []byte {
	return []byte{1}
}

//export exportSliceInOut
func exportSliceInOut(s []byte) []byte {
	return s
}

// issue 3775

func init() {
	if runtime.GOOS == "android" {
		return
	}
	// Same as test3775 but run during init so that
	// there are two levels of internal runtime lock
	// (1 for init, 1 for cgo).
	// This would have been broken by CL 11663043.
	( /*line :341:2*/_Cfunc_lockOSThreadC /*line :341:16*/)()
}

func test3775(t *testing.T) {
	if runtime.GOOS == "android" {
		return
	}
	// Used to panic because of the UnlockOSThread below.
	( /*line :349:2*/_Cfunc_lockOSThreadC /*line :349:16*/)()
}

//export lockOSThreadCallback
func lockOSThreadCallback() {
	runtime.LockOSThread()
	runtime.UnlockOSThread()
	go ( /*line :356:5*/_Cfunc_usleep /*line :356:12*/)(10000)
	runtime.Gosched()
}

// issue 4054 part 2 - part 1 in test.go

var issue4054b = []int{( /*line :362:24*/_Ciconst_A /*line :362:26*/), ( /*line :362:29*/_Ciconst_B /*line :362:31*/), ( /*line :362:34*/_Ciconst_C /*line :362:36*/), ( /*line :362:39*/_Ciconst_D /*line :362:41*/), ( /*line :362:44*/_Ciconst_E /*line :362:46*/), ( /*line :362:49*/_Ciconst_F /*line :362:51*/), ( /*line :362:54*/_Ciconst_G /*line :362:56*/), ( /*line :362:59*/_Ciconst_H /*line :362:61*/), ( /*line :362:64*/_Ciconst_II /*line :362:67*/), ( /*line :362:70*/_Ciconst_J /*line :362:72*/)}

//export issue5548FromC
func issue5548FromC(s string, i int) int {
	if len(s) == 4 && s == "test" && i == 42 {
		return 12345
	}
	println("got", len(s), i)
	return 9876
}

func test5548(t *testing.T) {
	if x := ( /*line :374:10*/_Cfunc_issue5548_in_c /*line :374:25*/)(); x != 12345 {
		t.Errorf("issue5548_in_c = %d, want %d", x, 12345)
	}
}

// issue 6833

//export GoIssue6833Func
func GoIssue6833Func(aui uint, aui64 uint64) uint64 {
	return aui64 + uint64(aui)
}

func test6833(t *testing.T) {
	ui := 7
	ull := uint64(0x4000300020001000)
	v := uint64(( /*line :389:14*/_Cfunc_issue6833Func /*line :389:28*/)( /*line :389:30*/_Ctype_uint /*line :389:36*/(ui),  /*line :389:42*/_Ctype_ulonglong /*line :389:53*/(ull)))
	exp := uint64(ui) + ull
	if v != exp {
		t.Errorf("issue6833Func() returns %x, expected %x", v, exp)
	}
}

// issue 6907

const CString = "C string"

//export CheckIssue6907Go
func CheckIssue6907Go(s string)  /*line :401:33*/_Ctype_int /*line :401:38*/ {
	if s == CString {
		return 1
	}
	return 0
}

func test6907Go(t *testing.T) {
	if got := ( /*line :409:12*/_Cfunc_CheckIssue6907C /*line :409:28*/)(CString); got != 1 {
		t.Errorf("C.CheckIssue6907C() == %d, want %d", got, 1)
	}
}

// issue 7665

var bad7665 unsafe.Pointer = ( /*line :416:30*/_Cgo_ptr(_Cfpvar_fp_f7665) /*line :416:36*/)
var good7665 uintptr = uintptr(( /*line :417:32*/_Cgo_ptr(_Cfpvar_fp_f7665) /*line :417:38*/))

func test7665(t *testing.T) {
	if bad7665 == nil || uintptr(bad7665) != good7665 {
		t.Errorf("ptrs = %p, %#x, want same non-nil pointer", bad7665, good7665)
	}
}

// issue 7978

var issue7978sync uint32

func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) {
	runtime.GC()
	buf := make([]byte, 65536)
	trace := string(buf[:runtime.Stack(buf, true)])
	for _, goroutine := range strings.Split(trace, "\n\n") {
		if strings.Contains(goroutine, "test.issue7978go") {
			trace := strings.Split(goroutine, "\n")
			// look for the expected function in the stack
			for i := 0; i < depth; i++ {
				if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) {
					t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine)
					return
				}
				if strings.Contains(trace[1+2*i], wantFunc) {
					return
				}
			}
			t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine)
			return
		}
	}
	t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace)
}

func issue7978wait(store uint32, wait uint32) {
	if store != 0 {
		atomic.StoreUint32(&issue7978sync, store)
	}
	for atomic.LoadUint32(&issue7978sync) != wait {
		runtime.Gosched()
	}
}

//export issue7978cb
func issue7978cb() {
	// Force a stack growth from the callback to put extra
	// pressure on the runtime. See issue #17785.
	growStack(64)
	issue7978wait(3, 4)
}

func growStack(n int) int {
	var buf [128]int
	if n == 0 {
		return 0
	}
	return buf[growStack(n-1)]
}

func issue7978go() {
	( /*line :479:2*/_Cfunc_issue7978c /*line :479:13*/)((* /*line :479:17*/_Ctype_uint32_t /*line :479:27*/)(&issue7978sync))
	issue7978wait(7, 8)
}

func test7978(t *testing.T) {
	if runtime.Compiler == "gccgo" {
		t.Skip("gccgo can not do stack traces of C code")
	}
	debug.SetTraceback("2")
	issue7978sync = 0
	go issue7978go()
	// test in c code, before callback
	issue7978wait(0, 1)
	issue7978check(t, "_Cfunc_issue7978c(", "", 1)
	// test in go code, during callback
	issue7978wait(2, 3)
	issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3)
	// test in c code, after callback
	issue7978wait(4, 5)
	issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1)
	// test in go code, after return from cgo
	issue7978wait(6, 7)
	issue7978check(t, "test.issue7978go(", "", 3)
	atomic.StoreUint32(&issue7978sync, 8)
}

// issue 8331 part 2

var issue8331Var  /*line :507:18*/_Ctype_issue8331 /*line :507:29*/

// issue 8945

//export Test8945
func Test8945() {
	_ = ( /*line :513:6*/*_Cvar_func8945 /*line :513:15*/)
}

// issue 20910

//export multi
func multi() (* /*line :519:16*/_Ctype_char /*line :519:22*/,  /*line :519:24*/_Ctype_int /*line :519:29*/) {
	return ( /*line :520:9*/_Cfunc_CString /*line :520:17*/)("multi"), 0
}

func test20910(t *testing.T) {
	( /*line :524:2*/_Cfunc_callMulti /*line :524:12*/)()
}

// issue 28772 part 2

const issue28772Constant2 = ( /*line :529:29*/_Ciconst_issue28772Constant2 /*line :529:49*/)

// issue 31891

//export useIssue31891A
func useIssue31891A(c * /*line :534:24*/_Ctype_Issue31891A /*line :534:37*/) {}

//export useIssue31891B
func useIssue31891B(c * /*line :537:24*/_Ctype_Issue31891B /*line :537:37*/) {}

func test31891(t *testing.T) {
	( /*line :540:2*/_Cfunc_callIssue31891 /*line :540:17*/)()
}

// issue 37033, check if cgo.Handle works properly

var issue37033 = 42

//export GoFunc37033
func GoFunc37033(handle  /*line :548:25*/_Ctype_uintptr_t /*line :548:36*/) {
	h := cgo.Handle(handle)
	ch := h.Value().(chan int)
	ch <- issue37033
}

// issue 38408
// A typedef pointer can be used as the element type.
// No runtime test; just make sure it compiles.
var _  /*line :557:7*/_Ctype_PIssue38408 /*line :557:20*/ = & /*line :557:24*/_Ctype_Issue38408 /*line :557:36*/{i: 1}

// issue 49633, example use of cgo.Handle with void*

type data49633 struct {
	msg string
}

//export GoFunc49633
func GoFunc49633(context unsafe.Pointer) {
	h := *(*cgo.Handle)(context)
	v := h.Value().(*data49633)
	v.msg = "hello"
}

func test49633(t *testing.T) {
	v := &data49633{}
	h := cgo.NewHandle(v)
	defer h.Delete()
	func() { _cgoBase0 := /*line :576:30*/&h; _cgo0 := /*line :576:15*/unsafe.Pointer(_cgoBase0); _cgoCheckPointer(_cgoBase0, 0 == 0); _Cfunc_cfunc49633(_cgo0); }()
	if v.msg != "hello" {
		t.Errorf("msg = %q, want 'hello'", v.msg)
	}
}
