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