github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/queues/lscq/asm.go (about) 1 //go:build amd64 && !gccgo && !appengine 2 // +build amd64,!gccgo,!appengine 3 4 package lscq 5 6 import ( 7 "unsafe" 8 ) 9 10 type uint128 [2]uint64 11 12 func compareAndSwapUint128(addr *uint128, old1, old2, new1, new2 uint64) (swapped bool) 13 14 func loadUint128(addr *uint128) (val uint128) 15 16 func loadSCQNodePointer(addr unsafe.Pointer) (val scqNodePointer) 17 18 func loadSCQNodeUint64(addr unsafe.Pointer) (val scqNodeUint64) 19 20 func atomicTestAndSetFirstBit(addr *uint64) (val uint64) 21 22 func atomicTestAndSetSecondBit(addr *uint64) (val uint64) 23 24 func resetNode(addr unsafe.Pointer) 25 26 //go:nosplit 27 func compareAndSwapSCQNodePointer(addr *scqNodePointer, old, new scqNodePointer) (swapped bool) { 28 // Ref: src/runtime/atomic_pointer.go:sync_atomic_CompareAndSwapPointer 29 if runtimeEnableWriteBarrier() { 30 runtimeatomicwb(&addr.data, new.data) 31 } 32 return compareAndSwapUint128((*uint128)(runtimenoescape(unsafe.Pointer(addr))), old.flags, uint64(uintptr(old.data)), new.flags, uint64(uintptr(new.data))) 33 } 34 35 func compareAndSwapSCQNodeUint64(addr *scqNodeUint64, old, new scqNodeUint64) (swapped bool) { 36 return compareAndSwapUint128((*uint128)(unsafe.Pointer(addr)), old.flags, old.data, new.flags, new.data) 37 } 38 39 func runtimeEnableWriteBarrier() bool 40 41 //go:linkname runtimeatomicwb runtime.atomicwb 42 //go:noescape 43 func runtimeatomicwb(ptr *unsafe.Pointer, new unsafe.Pointer) 44 45 //go:linkname runtimenoescape runtime.noescape 46 func runtimenoescape(p unsafe.Pointer) unsafe.Pointer 47 48 //go:nosplit 49 func atomicWriteBarrier(ptr *unsafe.Pointer) { 50 // For SCQ dequeue only. (fastpath) 51 if runtimeEnableWriteBarrier() { 52 runtimeatomicwb(ptr, nil) 53 } 54 }