mirror of
https://github.com/golang/go
synced 2024-11-26 17:36:56 -07:00
91102bf723
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>
182 lines
3.3 KiB
Go
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) {}
|