github.com/puzpuzpuz/xsync/v2@v2.5.2-0.20231021165734-92b8269e19a9/util.go (about)

     1  package xsync
     2  
     3  import (
     4  	"hash/maphash"
     5  	"reflect"
     6  	"runtime"
     7  	"unsafe"
     8  	_ "unsafe"
     9  )
    10  
    11  // test-only assert()-like flag
    12  var assertionsEnabled = false
    13  
    14  const (
    15  	// cacheLineSize is used in paddings to prevent false sharing;
    16  	// 64B are used instead of 128B as a compromise between
    17  	// memory footprint and performance; 128B usage may give ~30%
    18  	// improvement on NUMA machines.
    19  	cacheLineSize = 64
    20  )
    21  
    22  // nextPowOf2 computes the next highest power of 2 of 32-bit v.
    23  // Source: https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
    24  func nextPowOf2(v uint32) uint32 {
    25  	if v == 0 {
    26  		return 1
    27  	}
    28  	v--
    29  	v |= v >> 1
    30  	v |= v >> 2
    31  	v |= v >> 4
    32  	v |= v >> 8
    33  	v |= v >> 16
    34  	v++
    35  	return v
    36  }
    37  
    38  func parallelism() uint32 {
    39  	maxProcs := uint32(runtime.GOMAXPROCS(0))
    40  	numCores := uint32(runtime.NumCPU())
    41  	if maxProcs < numCores {
    42  		return maxProcs
    43  	}
    44  	return numCores
    45  }
    46  
    47  // hashString calculates a hash of s with the given seed.
    48  func hashString(seed maphash.Seed, s string) uint64 {
    49  	seed64 := *(*uint64)(unsafe.Pointer(&seed))
    50  	if s == "" {
    51  		return seed64
    52  	}
    53  	strh := (*reflect.StringHeader)(unsafe.Pointer(&s))
    54  	return uint64(memhash(unsafe.Pointer(strh.Data), uintptr(seed64), uintptr(strh.Len)))
    55  }
    56  
    57  //go:noescape
    58  //go:linkname memhash runtime.memhash
    59  func memhash(p unsafe.Pointer, h, s uintptr) uintptr
    60  
    61  //go:noescape
    62  //go:linkname fastrand runtime.fastrand
    63  func fastrand() uint32