github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/queues/lscq/asm_arm64.go (about)

     1  //go:build arm64 && !gccgo && !appengine
     2  // +build arm64,!gccgo,!appengine
     3  
     4  package lscq
     5  
     6  import (
     7  	"runtime"
     8  	"unsafe"
     9  
    10  	"github.com/songzhibin97/go-baseutils/sys/cpu"
    11  )
    12  
    13  var arm64HasAtomics = detectArm64HasAtomics()
    14  
    15  type uint128 [2]uint64
    16  
    17  func compareAndSwapUint128(addr *uint128, old1, old2, new1, new2 uint64) (swapped bool)
    18  
    19  func loadUint128(addr *uint128) (val uint128)
    20  
    21  func loadSCQNodePointer(addr unsafe.Pointer) (val scqNodePointer)
    22  
    23  func loadSCQNodeUint64(addr unsafe.Pointer) (val scqNodeUint64)
    24  
    25  func atomicTestAndSetFirstBit(addr *uint64) (val uint64)
    26  
    27  func atomicTestAndSetSecondBit(addr *uint64) (val uint64)
    28  
    29  func resetNode(addr unsafe.Pointer)
    30  
    31  //go:nosplit
    32  func compareAndSwapSCQNodePointer(addr *scqNodePointer, old, new scqNodePointer) (swapped bool) {
    33  	// Ref: src/runtime/atomic_pointer.go:sync_atomic_CompareAndSwapPointer
    34  	if runtimeEnableWriteBarrier() {
    35  		runtimeatomicwb(&addr.data, new.data)
    36  	}
    37  	return compareAndSwapUint128((*uint128)(runtimenoescape(unsafe.Pointer(addr))), old.flags, uint64(uintptr(old.data)), new.flags, uint64(uintptr(new.data)))
    38  }
    39  
    40  func compareAndSwapSCQNodeUint64(addr *scqNodeUint64, old, new scqNodeUint64) (swapped bool) {
    41  	return compareAndSwapUint128((*uint128)(unsafe.Pointer(addr)), old.flags, old.data, new.flags, new.data)
    42  }
    43  
    44  func runtimeEnableWriteBarrier() bool
    45  
    46  //go:linkname runtimeatomicwb runtime.atomicwb
    47  //go:noescape
    48  func runtimeatomicwb(ptr *unsafe.Pointer, new unsafe.Pointer)
    49  
    50  //go:linkname runtimenoescape runtime.noescape
    51  func runtimenoescape(p unsafe.Pointer) unsafe.Pointer
    52  
    53  //go:nosplit
    54  func atomicWriteBarrier(ptr *unsafe.Pointer) {
    55  	// For SCQ dequeue only. (fastpath)
    56  	if runtimeEnableWriteBarrier() {
    57  		runtimeatomicwb(ptr, nil)
    58  	}
    59  }
    60  
    61  //go:linkname sysctlEnabled internal/cpu.sysctlEnabled
    62  func sysctlEnabled(name []byte) bool
    63  
    64  func detectArm64HasAtomics() bool {
    65  	switch runtime.GOOS {
    66  	case "darwin":
    67  		return sysctlEnabled([]byte("hw.optional.armv8_1_atomics\x00"))
    68  	default:
    69  		return cpu.ARM64.HasATOMICS
    70  	}
    71  }