github.com/arr-ai/hash@v0.8.0/stubs.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package hash 6 7 import ( 8 "unsafe" 9 10 "sync/atomic" 11 ) 12 13 // Should be a built-in for unsafe.Pointer? 14 //go:nosplit 15 func add(p unsafe.Pointer, x uintptr) unsafe.Pointer { 16 return unsafe.Pointer(uintptr(p) + x) 17 } 18 19 var fastrandState uint64 20 21 //go:nosplit 22 func fastrand() uint32 { 23 var s1, s0 uint32 24 for i := 0; i < 3; i++ { 25 state := atomic.LoadUint64(&fastrandState) 26 frand := *(*[]uint32)(noescape(unsafe.Pointer(&state))) 27 // Implement xorshift64+: 2 32-bit xorshift sequences added together. 28 // Shift triplet [17,7,16] was calculated as indicated in Marsaglia's 29 // Xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf 30 // This generator passes the SmallCrush suite, part of TestU01 framework: 31 // http://simul.iro.umontreal.ca/testu01/tu01.html 32 s1, s0 = frand[0], frand[1] 33 s1 ^= s1 << 17 34 s1 = s1 ^ s0 ^ s1>>7 ^ s0>>16 35 frand[0], frand[1] = s0, s1 36 newState := *(*uint64)(noescape(unsafe.Pointer(&frand))) 37 if atomic.CompareAndSwapUint64(&fastrandState, state, newState) { 38 break 39 } 40 } 41 return s0 + s1 42 } 43 44 // noescape hides a pointer from escape analysis. noescape is 45 // the identity function but escape analysis doesn't think the 46 // output depends on the input. noescape is inlined and currently 47 // compiles down to zero instructions. 48 // USE CAREFULLY! 49 //go:nosplit 50 func noescape(p unsafe.Pointer) unsafe.Pointer { 51 x := uintptr(p) 52 return unsafe.Pointer(x ^ 0) //nolint:staticcheck 53 }