moduledataverify()
stackinit()
mallocinit()
+ cpuinit() // must run before alginit
+ alginit() // maps, hash, fastrand must not be used before this call
fastrandinit() // must run before mcommoninit
mcommoninit(_g_.m, -1)
- cpuinit() // must run before alginit
- alginit() // maps must not be used before this call
modulesinit() // provides activeModules
typelinksinit() // uses maps, activeModules
itabsinit() // uses activeModules
mp.id = mReserveID()
}
- mp.fastrand[0] = uint32(int64Hash(uint64(mp.id), fastrandseed))
- mp.fastrand[1] = uint32(int64Hash(uint64(cputicks()), ^fastrandseed))
- if mp.fastrand[0]|mp.fastrand[1] == 0 {
- mp.fastrand[1] = 1
- }
+ // cputicks is not very random in startup virtual machine
+ mp.fastrand = uint64(int64Hash(uint64(mp.id), fastrandseed^uintptr(cputicks())))
mpreinit(mp)
if mp.gsignal != nil {
"internal/abi"
"internal/goarch"
"internal/goexperiment"
+ "runtime/internal/math"
"unsafe"
)
//go:nosplit
func fastrand() uint32 {
mp := getg().m
+ // Implement wyrand: https://github.com/wangyi-fudan/wyhash
+ // Only the platform that math.Mul64 can be lowered
+ // by the compiler should be in this list.
+ if goarch.IsAmd64|goarch.IsArm64|goarch.IsPpc64|
+ goarch.IsPpc64le|goarch.IsMips64|goarch.IsMips64le|
+ goarch.IsS390x|goarch.IsRiscv64 == 1 {
+ mp.fastrand += 0xa0761d6478bd642f
+ hi, lo := math.Mul64(mp.fastrand, mp.fastrand^0xe7037ed1a0b428db)
+ return uint32(hi ^ lo)
+ }
+
// Implement xorshift64+: 2 32-bit xorshift sequences added together.
// Shift triplet [17,7,16] was calculated as indicated in Marsaglia's
// Xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
// This generator passes the SmallCrush suite, part of TestU01 framework:
// http://simul.iro.umontreal.ca/testu01/tu01.html
- s1, s0 := mp.fastrand[0], mp.fastrand[1]
+ t := (*[2]uint32)(unsafe.Pointer(&mp.fastrand))
+ s1, s0 := t[0], t[1]
s1 ^= s1 << 17
s1 = s1 ^ s0 ^ s1>>7 ^ s0>>16
- mp.fastrand[0], mp.fastrand[1] = s0, s1
+ t[0], t[1] = s0, s1
return s0 + s1
}