]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime: put runtime.fastrand back temporarily
authorRuss Cox <rsc@golang.org>
Thu, 7 Dec 2023 16:11:01 +0000 (11:11 -0500)
committerGopher Robot <gobot@golang.org>
Thu, 7 Dec 2023 23:44:31 +0000 (23:44 +0000)
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>

src/runtime/rand.go
src/runtime/rand_test.go

index 6cb8deef519d3227fd1d221abb53170719221411..10cd116fadeaaf7188f8d50e80e40f8528482977 100644 (file)
@@ -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()
+}
index 94648c5216a64d6c1565308600103d60bbbf390d..baecb6984d02500a78b07b7b9258c005f6977ea3 100644 (file)
@@ -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)
+               }
+       }
+}