mirror of
https://github.com/golang/go
synced 2024-10-01 13:44:47 +00:00
runtime: put runtime.fastrand back temporarily
Callers should be using math/rand/v2.Uint64 instead, but there are lots of linkname references to runtime.fastrand in public code. If we break it all now, that will require people to use //go:build tags to use rand/v2.Uint64 with Go 1.22 and keep using the linkname for earlier versions. Instead, leave the linkname working and then we can remove it in Go 1.24, at which point everyone should be able to use math/rand/v2.Uint64 unconditionally. Change-Id: I7287ca4f67c270b009562313661cc28a4c2219a4 Reviewed-on: https://go-review.googlesource.com/c/go/+/548235 Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Auto-Submit: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
e1c0349a7c
commit
dca2ef2361
|
@ -223,3 +223,25 @@ func cheaprandn(n uint32) uint32 {
|
|||
// See https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
|
||||
return uint32((uint64(cheaprand()) * uint64(n)) >> 32)
|
||||
}
|
||||
|
||||
// Too much legacy code has go:linkname references
|
||||
// to runtime.fastrand and friends, so keep these around for now.
|
||||
// Code should migrate to math/rand/v2.Uint64,
|
||||
// which is just as fast, but that's only available in Go 1.22+.
|
||||
// It would be reasonable to remove these in Go 1.24.
|
||||
// Do not call these from package runtime.
|
||||
|
||||
//go:linkname legacy_fastrand runtime.fastrand
|
||||
func legacy_fastrand() uint32 {
|
||||
return uint32(rand())
|
||||
}
|
||||
|
||||
//go:linkname legacy_fastrandn runtime.fastrandn
|
||||
func legacy_fastrandn(n uint32) uint32 {
|
||||
return randn(n)
|
||||
}
|
||||
|
||||
//go:linkname legacy_fastrand64 runtime.fastrand64
|
||||
func legacy_fastrand64() uint64 {
|
||||
return rand()
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
. "runtime"
|
||||
"strconv"
|
||||
"testing"
|
||||
_ "unsafe" // for go:linkname
|
||||
)
|
||||
|
||||
func TestReadRandom(t *testing.T) {
|
||||
|
@ -62,3 +63,35 @@ func BenchmarkFastrandn(b *testing.B) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
//go:linkname fastrand runtime.fastrand
|
||||
func fastrand() uint32
|
||||
|
||||
//go:linkname fastrandn runtime.fastrandn
|
||||
func fastrandn(uint32) uint32
|
||||
|
||||
//go:linkname fastrand64 runtime.fastrand64
|
||||
func fastrand64() uint64
|
||||
|
||||
func TestLegacyFastrand(t *testing.T) {
|
||||
// Testing mainly that the calls work at all,
|
||||
// but check that all three don't return the same number (1 in 2^64 chance)
|
||||
{
|
||||
x, y, z := fastrand(), fastrand(), fastrand()
|
||||
if x == y && y == z {
|
||||
t.Fatalf("fastrand three times = %#x, %#x, %#x, want different numbers", x, y, z)
|
||||
}
|
||||
}
|
||||
{
|
||||
x, y, z := fastrandn(1e9), fastrandn(1e9), fastrandn(1e9)
|
||||
if x == y && y == z {
|
||||
t.Fatalf("fastrandn three times = %#x, %#x, %#x, want different numbers", x, y, z)
|
||||
}
|
||||
}
|
||||
{
|
||||
x, y, z := fastrand64(), fastrand64(), fastrand64()
|
||||
if x == y && y == z {
|
||||
t.Fatalf("fastrand64 three times = %#x, %#x, %#x, want different numbers", x, y, z)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue