diff options
| author | Russ Cox <rsc@golang.org> | 2023-12-07 11:11:01 -0500 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-12-07 23:44:31 +0000 |
| commit | dca2ef236151e5606a5863d82f1a10289ce77105 (patch) | |
| tree | 37d6803a1c641db3fbae08c32b36cac02896fba6 /src/runtime | |
| parent | e1c0349a7c607cdfcfa8f7c0c6b70aceff9d3752 (diff) | |
| download | go-dca2ef236151e5606a5863d82f1a10289ce77105.tar.xz | |
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>
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/rand.go | 22 | ||||
| -rw-r--r-- | src/runtime/rand_test.go | 33 |
2 files changed, 55 insertions, 0 deletions
diff --git a/src/runtime/rand.go b/src/runtime/rand.go index 6cb8deef51..10cd116fad 100644 --- a/src/runtime/rand.go +++ b/src/runtime/rand.go @@ -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() +} diff --git a/src/runtime/rand_test.go b/src/runtime/rand_test.go index 94648c5216..baecb6984d 100644 --- a/src/runtime/rand_test.go +++ b/src/runtime/rand_test.go @@ -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) + } + } +} |
