github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/algorithm.go (about) 1 package runtime 2 3 // This file implements various core algorithms used in the runtime package and 4 // standard library. 5 6 import ( 7 "unsafe" 8 ) 9 10 // This function is needed by math/rand since Go 1.20. 11 // See: https://github.com/golang/go/issues/54880 12 // 13 //go:linkname rand_fastrand64 math/rand.fastrand64 14 func rand_fastrand64() uint64 { 15 return fastrand64() 16 } 17 18 // This function is used by hash/maphash. 19 // This function isn't required anymore since Go 1.22, so should be removed once 20 // that becomes the minimum requirement. 21 func fastrand() uint32 { 22 xorshift32State = xorshift32(xorshift32State) 23 return xorshift32State 24 } 25 26 var xorshift32State uint32 = 1 27 28 func xorshift32(x uint32) uint32 { 29 // Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs". 30 // Improved sequence based on 31 // http://www.iro.umontreal.ca/~lecuyer/myftp/papers/xorshift.pdf 32 x ^= x << 7 33 x ^= x >> 1 34 x ^= x << 9 35 return x 36 } 37 38 // This function is used by hash/maphash. 39 // This function isn't required anymore since Go 1.22, so should be removed once 40 // that becomes the minimum requirement. 41 func fastrand64() uint64 { 42 xorshift64State = xorshiftMult64(xorshift64State) 43 return xorshift64State 44 } 45 46 var xorshift64State uint64 = 1 47 48 // 64-bit xorshift multiply rng from http://vigna.di.unimi.it/ftp/papers/xorshift.pdf 49 func xorshiftMult64(x uint64) uint64 { 50 x ^= x >> 12 // a 51 x ^= x << 25 // b 52 x ^= x >> 27 // c 53 return x * 2685821657736338717 54 } 55 56 // This function is used by hash/maphash. 57 func memhash(p unsafe.Pointer, seed, s uintptr) uintptr { 58 if unsafe.Sizeof(uintptr(0)) > 4 { 59 return uintptr(hash64(p, s, seed)) 60 } 61 return uintptr(hash32(p, s, seed)) 62 } 63 64 // Function that's called from various packages starting with Go 1.22. 65 func rand() uint64 { 66 // Return a random number from hardware, falling back to software if 67 // unavailable. 68 n, ok := hardwareRand() 69 if !ok { 70 // Fallback to static random number. 71 // Not great, but we can't do much better than this. 72 n = fastrand64() 73 } 74 return n 75 }