1
0
mirror of https://github.com/golang/go synced 2024-11-08 19:46:23 -07:00
go/misc/cgo/test/basic.go
Ilya Tocar 91102bf723 runtime: use bytes.IndexByte in findnull
bytes.IndexByte is heavily optimized. Use it in findnull.
This is second attempt, similar to CL97523.
In this version we never call IndexByte on region of memory,
that crosses page boundary. A bit slower than CL97523,
but still fast:

name        old time/op  new time/op  delta
GoString-6   164ns ± 2%   118ns ± 0%  -28.00%  (p=0.000 n=10+6)

findnull is also used in gostringnocopy,
which is used in many hot spots in the runtime.

Fixes #23830

Change-Id: Id843dd4f65a34309d92bdd8df229e484d26b0cb2
Reviewed-on: https://go-review.googlesource.com/98015
Run-TryBot: Ilya Tocar <ilya.tocar@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-03-09 19:37:39 +00:00

182 lines
3.3 KiB
Go

// Copyright 2010 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.
// Basic test cases for cgo.
package cgotest
/*
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <errno.h>
#define SHIFT(x, y) ((x)<<(y))
#define KILO SHIFT(1, 10)
#define UINT32VAL 0xc008427bU
enum E {
Enum1 = 1,
Enum2 = 2,
};
typedef unsigned char cgo_uuid_t[20];
void uuid_generate(cgo_uuid_t x) {
x[0] = 0;
}
struct S {
int x;
};
const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter);
enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; }
// issue 1222
typedef union {
long align;
} xxpthread_mutex_t;
struct ibv_async_event {
union {
int x;
} element;
};
struct ibv_context {
xxpthread_mutex_t mutex;
};
int add(int x, int y) {
return x+y;
};
*/
import "C"
import (
"runtime"
"syscall"
"testing"
"unsafe"
)
const EINVAL = C.EINVAL /* test #define */
var KILO = C.KILO
func uuidgen() {
var uuid C.cgo_uuid_t
C.uuid_generate(&uuid[0])
}
func Strtol(s string, base int) (int, error) {
p := C.CString(s)
n, err := C.strtol(p, nil, C.int(base))
C.free(unsafe.Pointer(p))
return int(n), err
}
func Atol(s string) int {
p := C.CString(s)
n := C.atol(p)
C.free(unsafe.Pointer(p))
return int(n)
}
func testConst(t *testing.T) {
C.myConstFunc(nil, 0, nil)
}
func testEnum(t *testing.T) {
if C.Enum1 != 1 || C.Enum2 != 2 {
t.Error("bad enum", C.Enum1, C.Enum2)
}
}
func testAtol(t *testing.T) {
l := Atol("123")
if l != 123 {
t.Error("Atol 123: ", l)
}
}
func testErrno(t *testing.T) {
p := C.CString("no-such-file")
m := C.CString("r")
f, err := C.fopen(p, m)
C.free(unsafe.Pointer(p))
C.free(unsafe.Pointer(m))
if err == nil {
C.fclose(f)
t.Fatalf("C.fopen: should fail")
}
if err != syscall.ENOENT {
t.Fatalf("C.fopen: unexpected error: %v", err)
}
}
func testMultipleAssign(t *testing.T) {
p := C.CString("234")
n, m := C.strtol(p, nil, 345), C.strtol(p, nil, 10)
if runtime.GOOS == "openbsd" {
// Bug in OpenBSD strtol(3) - base > 36 succeeds.
if (n != 0 && n != 239089) || m != 234 {
t.Fatal("Strtol x2: ", n, m)
}
} else if n != 0 || m != 234 {
t.Fatal("Strtol x2: ", n, m)
}
C.free(unsafe.Pointer(p))
}
var (
cuint = (C.uint)(0)
culong C.ulong
cchar C.char
)
type Context struct {
ctx *C.struct_ibv_context
}
func benchCgoCall(b *testing.B) {
const x = C.int(2)
const y = C.int(3)
for i := 0; i < b.N; i++ {
C.add(x, y)
}
}
var sinkString string
func benchGoString(b *testing.B) {
for i := 0; i < b.N; i++ {
sinkString = C.GoString(C.cstr)
}
const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"
if sinkString != want {
b.Fatalf("%q != %q", sinkString, want)
}
}
// Issue 2470.
func testUnsignedInt(t *testing.T) {
a := (int64)(C.UINT32VAL)
b := (int64)(0xc008427b)
if a != b {
t.Errorf("Incorrect unsigned int - got %x, want %x", a, b)
}
}
// Static (build-time) test that syntax traversal visits all operands of s[i:j:k].
func sliceOperands(array [2000]int) {
_ = array[C.KILO:C.KILO:C.KILO] // no type error
}
// set in cgo_thread_lock.go init
var testThreadLockFunc = func(*testing.T) {}