github.com/alphadose/zenq/v2@v2.8.4/benchmarks/cgo_test/cgobench.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"runtime"
     6  	"sync"
     7  	"unsafe"
     8  	_ "unsafe"
     9  )
    10  
    11  /*
    12  #include <stdlib.h>
    13  */
    14  import "C"
    15  
    16  //go:linkname noescape runtime.noescape
    17  func noescape(p unsafe.Pointer) unsafe.Pointer
    18  
    19  //go:linkname memmove runtime.memmove
    20  func memmove(to, from unsafe.Pointer, n uintptr)
    21  
    22  //go:linkname memclrNoHeapPointers runtime.memclrNoHeapPointers
    23  func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
    24  
    25  //go:linkname mallocgc runtime.mallocgc
    26  func mallocgc(size uintptr, typ unsafe.Pointer, needzero bool) unsafe.Pointer
    27  
    28  func alloc[T any](sample T, size uintptr) unsafe.Pointer {
    29  	length := unsafe.Sizeof(sample) * size
    30  	return mallocgc(length, nil, true)
    31  }
    32  
    33  func getIndexAt[T any](ptr unsafe.Pointer, offset uintptr) unsafe.Pointer {
    34  	return unsafe.Pointer(uintptr(ptr) + offset)
    35  }
    36  
    37  type block struct {
    38  	Data  int
    39  	Kooky string
    40  	Endy  float64
    41  	// Last  *uint
    42  }
    43  
    44  func main() {
    45  	// a := make([]int32, 0, 3)
    46  	// a = append(a, 10, 20, 30)
    47  	// t := unsafe.Pointer(&a[0])
    48  	// fmt.Println(*(*int32)(unsafe.Pointer(uintptr(t) + 2*unsafe.Sizeof(int32(0)))))
    49  	// return
    50  
    51  	const n = uintptr(100)
    52  	t := make([]block, n, n)
    53  	k := unsafe.Pointer(&t[0])
    54  	// k := alloc(block{Data: 1, Kooky: "2", Endy: 3.2, Last: new(uint)}, n)
    55  	// k := C.calloc(C.ulong(unsafe.Sizeof(block{})), C.ulong(n))
    56  	// unsafe.Slice(k, n)
    57  	// memclrNoHeapPointers(k, n)
    58  	// t := (*[]block)(k)
    59  	// runtime.KeepAlive((*[n]block)(k))
    60  	// for i := uintptr(0); i < n; i++ {
    61  	// 	slot := getIndexAt[block](k, i*unsafe.Sizeof(block{}))
    62  	// 	slot.Data = int(i)
    63  	// 	slot.Kooky = fmt.Sprintf("wutface%d", i)
    64  	// 	slot.Endy = float64(i)
    65  	// 	slot.Last = new(uint)
    66  	// 	*slot.Last = uint(i)
    67  	// }
    68  	// for i := uintptr(0); i < n; i++ {
    69  	// 	fmt.Printf("%#v\n", t[i])
    70  	// }
    71  	// return
    72  	var wg sync.WaitGroup
    73  	wg.Add(int(n))
    74  	for i := uintptr(0); i < n; i++ {
    75  		slot := unsafe.Pointer(uintptr(k) + i*unsafe.Sizeof(block{}))
    76  		(*block)(slot).Data = int(i)
    77  		(*block)(slot).Kooky = fmt.Sprintf("wutface%d", i)
    78  		(*block)(slot).Endy = float64(i)
    79  		// (*block)(slot).Last = new(uint)
    80  		// *(*block)(slot).Last = uint(i)
    81  	}
    82  	for i := uintptr(0); i < n; i++ {
    83  		j := i
    84  		go func() {
    85  			slot := unsafe.Pointer(uintptr(k) + j*unsafe.Sizeof(block{}))
    86  			// *(*block)(slot).Last++
    87  			fmt.Println(uintptr(slot), "  ", *(*block)(slot))
    88  			runtime.GC()
    89  			wg.Done()
    90  		}()
    91  	}
    92  	wg.Wait()
    93  }