aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2025-10-29 13:37:52 -0400
committerGopher Robot <gobot@golang.org>2025-10-30 09:55:06 -0700
commitd32b1f02c3e869b6ddf73d2113477b1fd77d42c8 (patch)
tree074df75ed82ee3790fd4a4232a07754ad2693a3b /src/runtime
parentcbbd385cb863e4a0969de9846fdd80227ed91ad0 (diff)
downloadgo-d32b1f02c3e869b6ddf73d2113477b1fd77d42c8.tar.xz
runtime: delete timediv
Now that the compiler handles constant 64-bit divisions without function calls on 32-bit systems, we no longer need to maintain and test a bad custom implementation of 64-bit division. Change-Id: If28807ad4f86507267ae69bc8f0b09ec18e98b66 Reviewed-on: https://go-review.googlesource.com/c/go/+/716463 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Russ Cox <rsc@golang.org> Reviewed-by: Alan Donovan <adonovan@google.com>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/defs1_netbsd_386.go3
-rw-r--r--src/runtime/defs1_netbsd_arm.go3
-rw-r--r--src/runtime/defs_freebsd_386.go3
-rw-r--r--src/runtime/defs_freebsd_arm.go3
-rw-r--r--src/runtime/defs_linux_386.go8
-rw-r--r--src/runtime/defs_linux_arm.go8
-rw-r--r--src/runtime/defs_linux_mipsx.go8
-rw-r--r--src/runtime/defs_openbsd_386.go3
-rw-r--r--src/runtime/defs_openbsd_arm.go3
-rw-r--r--src/runtime/export_test.go2
-rw-r--r--src/runtime/os_dragonfly.go2
-rw-r--r--src/runtime/os_plan9.go2
-rw-r--r--src/runtime/os_windows.go2
-rw-r--r--src/runtime/runtime1.go33
-rw-r--r--src/runtime/runtime_test.go76
15 files changed, 27 insertions, 132 deletions
diff --git a/src/runtime/defs1_netbsd_386.go b/src/runtime/defs1_netbsd_386.go
index 16c55def92..cb4d6f1cf1 100644
--- a/src/runtime/defs1_netbsd_386.go
+++ b/src/runtime/defs1_netbsd_386.go
@@ -121,7 +121,8 @@ type timespec struct {
//go:nosplit
func (ts *timespec) setNsec(ns int64) {
- ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
+ ts.tv_sec = int64(ns / 1e9)
+ ts.tv_nsec = int32(ns % 1e9)
}
type timeval struct {
diff --git a/src/runtime/defs1_netbsd_arm.go b/src/runtime/defs1_netbsd_arm.go
index 77a59d4a05..d31fcd471d 100644
--- a/src/runtime/defs1_netbsd_arm.go
+++ b/src/runtime/defs1_netbsd_arm.go
@@ -123,7 +123,8 @@ type timespec struct {
//go:nosplit
func (ts *timespec) setNsec(ns int64) {
- ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
+ ts.tv_sec = int64(ns / 1e9)
+ ts.tv_nsec = int32(ns % 1e9)
}
type timeval struct {
diff --git a/src/runtime/defs_freebsd_386.go b/src/runtime/defs_freebsd_386.go
index 42a0faf74d..20ac643ad7 100644
--- a/src/runtime/defs_freebsd_386.go
+++ b/src/runtime/defs_freebsd_386.go
@@ -210,7 +210,8 @@ type timespec struct {
//go:nosplit
func (ts *timespec) setNsec(ns int64) {
- ts.tv_sec = timediv(ns, 1e9, &ts.tv_nsec)
+ ts.tv_sec = int32(ns / 1e9)
+ ts.tv_nsec = int32(ns % 1e9)
}
type timeval struct {
diff --git a/src/runtime/defs_freebsd_arm.go b/src/runtime/defs_freebsd_arm.go
index dbb54da51b..cf61fcade5 100644
--- a/src/runtime/defs_freebsd_arm.go
+++ b/src/runtime/defs_freebsd_arm.go
@@ -182,7 +182,8 @@ type timespec struct {
//go:nosplit
func (ts *timespec) setNsec(ns int64) {
- ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
+ ts.tv_sec = int64(ns / 1e9)
+ ts.tv_nsec = int32(ns % 1e9)
}
type timeval struct {
diff --git a/src/runtime/defs_linux_386.go b/src/runtime/defs_linux_386.go
index c6c7d7d6d8..d1875954f3 100644
--- a/src/runtime/defs_linux_386.go
+++ b/src/runtime/defs_linux_386.go
@@ -146,7 +146,8 @@ type timespec32 struct {
//go:nosplit
func (ts *timespec32) setNsec(ns int64) {
- ts.tv_sec = timediv(ns, 1e9, &ts.tv_nsec)
+ ts.tv_sec = int32(ns / 1e9)
+ ts.tv_nsec = int32(ns % 1e9)
}
type timespec struct {
@@ -156,9 +157,8 @@ type timespec struct {
//go:nosplit
func (ts *timespec) setNsec(ns int64) {
- var newNS int32
- ts.tv_sec = int64(timediv(ns, 1e9, &newNS))
- ts.tv_nsec = int64(newNS)
+ ts.tv_sec = int64(ns / 1e9)
+ ts.tv_nsec = int64(ns % 1e9)
}
type timeval struct {
diff --git a/src/runtime/defs_linux_arm.go b/src/runtime/defs_linux_arm.go
index ff879fad89..94577fc597 100644
--- a/src/runtime/defs_linux_arm.go
+++ b/src/runtime/defs_linux_arm.go
@@ -105,7 +105,8 @@ type timespec32 struct {
//go:nosplit
func (ts *timespec32) setNsec(ns int64) {
- ts.tv_sec = timediv(ns, 1e9, &ts.tv_nsec)
+ ts.tv_sec = int32(ns / 1e9)
+ ts.tv_nsec = int32(ns % 1e9)
}
type timespec struct {
@@ -115,9 +116,8 @@ type timespec struct {
//go:nosplit
func (ts *timespec) setNsec(ns int64) {
- var newNS int32
- ts.tv_sec = int64(timediv(ns, 1e9, &newNS))
- ts.tv_nsec = int64(newNS)
+ ts.tv_sec = int64(ns / 1e9)
+ ts.tv_nsec = int64(ns % 1e9)
}
type stackt struct {
diff --git a/src/runtime/defs_linux_mipsx.go b/src/runtime/defs_linux_mipsx.go
index 5b10b910db..5a446e0595 100644
--- a/src/runtime/defs_linux_mipsx.go
+++ b/src/runtime/defs_linux_mipsx.go
@@ -103,7 +103,8 @@ type timespec32 struct {
//go:nosplit
func (ts *timespec32) setNsec(ns int64) {
- ts.tv_sec = timediv(ns, 1e9, &ts.tv_nsec)
+ ts.tv_sec = int32(ns / 1e9)
+ ts.tv_nsec = int32(ns % 1e9)
}
type timespec struct {
@@ -113,9 +114,8 @@ type timespec struct {
//go:nosplit
func (ts *timespec) setNsec(ns int64) {
- var newNS int32
- ts.tv_sec = int64(timediv(ns, 1e9, &newNS))
- ts.tv_nsec = int64(newNS)
+ ts.tv_sec = int64(ns / 1e9)
+ ts.tv_nsec = int64(ns % 1e9)
}
type timeval struct {
diff --git a/src/runtime/defs_openbsd_386.go b/src/runtime/defs_openbsd_386.go
index 996745f6f8..c77b5e16cb 100644
--- a/src/runtime/defs_openbsd_386.go
+++ b/src/runtime/defs_openbsd_386.go
@@ -147,7 +147,8 @@ type timespec struct {
//go:nosplit
func (ts *timespec) setNsec(ns int64) {
- ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
+ ts.tv_sec = int64(ns / 1e9)
+ ts.tv_nsec = int32(ns % 1e9)
}
type timeval struct {
diff --git a/src/runtime/defs_openbsd_arm.go b/src/runtime/defs_openbsd_arm.go
index cdda6b4ad1..5393ea4eeb 100644
--- a/src/runtime/defs_openbsd_arm.go
+++ b/src/runtime/defs_openbsd_arm.go
@@ -152,7 +152,8 @@ type timespec struct {
//go:nosplit
func (ts *timespec) setNsec(ns int64) {
- ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
+ ts.tv_sec = int64(ns / 1e9)
+ ts.tv_nsec = int32(ns % 1e9)
}
type timeval struct {
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index 9f2fcacc30..d6fce72bf0 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -1472,8 +1472,6 @@ func Releasem() {
releasem(getg().m)
}
-var Timediv = timediv
-
type PIController struct {
piController
}
diff --git a/src/runtime/os_dragonfly.go b/src/runtime/os_dragonfly.go
index fbbee64fd3..c34af7f072 100644
--- a/src/runtime/os_dragonfly.go
+++ b/src/runtime/os_dragonfly.go
@@ -113,7 +113,7 @@ func futexsleep1(addr *uint32, val uint32, ns int64) {
// The timeout is specified in microseconds - ensure that we
// do not end up dividing to zero, which would put us to sleep
// indefinitely...
- timeout = timediv(ns, 1000, nil)
+ timeout = int32(ns / 1000)
if timeout == 0 {
timeout = 1
}
diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go
index 72a8657985..80c101f1a1 100644
--- a/src/runtime/os_plan9.go
+++ b/src/runtime/os_plan9.go
@@ -486,7 +486,7 @@ func semacreate(mp *m) {
func semasleep(ns int64) int {
gp := getg()
if ns >= 0 {
- ms := timediv(ns, 1000000, nil)
+ ms := int32(ns / 1000000)
if ms == 0 {
ms = 1
}
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index 7610802e0f..2ae625580d 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -664,7 +664,7 @@ func semasleep(ns int64) int32 {
start := nanotime()
elapsed := int64(0)
for {
- ms := int64(timediv(ns-elapsed, 1000000, nil))
+ ms := (ns - elapsed) / 1000000
if ms == 0 {
ms = 1
}
diff --git a/src/runtime/runtime1.go b/src/runtime/runtime1.go
index 3ec5c44ebd..43e4c14236 100644
--- a/src/runtime/runtime1.go
+++ b/src/runtime/runtime1.go
@@ -212,10 +212,6 @@ func check() {
throw("bad unsafe.Sizeof y1")
}
- if timediv(12345*1000000000+54321, 1000000000, &e) != 12345 || e != 54321 {
- throw("bad timediv")
- }
-
var z uint32
z = 1
if !atomic.Cas(&z, 1, 2) {
@@ -593,35 +589,6 @@ func setTraceback(level string) {
atomic.Store(&traceback_cache, t)
}
-// Poor mans 64-bit division.
-// This is a very special function, do not use it if you are not sure what you are doing.
-// int64 division is lowered into _divv() call on 386, which does not fit into nosplit functions.
-// Handles overflow in a time-specific manner.
-// This keeps us within no-split stack limits on 32-bit processors.
-//
-//go:nosplit
-func timediv(v int64, div int32, rem *int32) int32 {
- res := int32(0)
- for bit := 30; bit >= 0; bit-- {
- if v >= int64(div)<<uint(bit) {
- v = v - (int64(div) << uint(bit))
- // Before this for loop, res was 0, thus all these
- // power of 2 increments are now just bitsets.
- res |= 1 << uint(bit)
- }
- }
- if v >= int64(div) {
- if rem != nil {
- *rem = 0
- }
- return 0x7fffffff
- }
- if rem != nil {
- *rem = int32(v)
- }
- return res
-}
-
// Helpers for Go. Must be NOSPLIT, must only call NOSPLIT functions, and must not block.
//go:nosplit
diff --git a/src/runtime/runtime_test.go b/src/runtime/runtime_test.go
index 6c628f8903..c1c63e3cea 100644
--- a/src/runtime/runtime_test.go
+++ b/src/runtime/runtime_test.go
@@ -6,7 +6,6 @@ package runtime_test
import (
"flag"
- "fmt"
"internal/asan"
"internal/cpu"
"internal/msan"
@@ -498,81 +497,6 @@ func TestVersion(t *testing.T) {
}
}
-func TestTimediv(t *testing.T) {
- for _, tc := range []struct {
- num int64
- div int32
- ret int32
- rem int32
- }{
- {
- num: 8,
- div: 2,
- ret: 4,
- rem: 0,
- },
- {
- num: 9,
- div: 2,
- ret: 4,
- rem: 1,
- },
- {
- // Used by runtime.check.
- num: 12345*1000000000 + 54321,
- div: 1000000000,
- ret: 12345,
- rem: 54321,
- },
- {
- num: 1<<32 - 1,
- div: 2,
- ret: 1<<31 - 1, // no overflow.
- rem: 1,
- },
- {
- num: 1 << 32,
- div: 2,
- ret: 1<<31 - 1, // overflow.
- rem: 0,
- },
- {
- num: 1 << 40,
- div: 2,
- ret: 1<<31 - 1, // overflow.
- rem: 0,
- },
- {
- num: 1<<40 + 1,
- div: 1 << 10,
- ret: 1 << 30,
- rem: 1,
- },
- } {
- name := fmt.Sprintf("%d div %d", tc.num, tc.div)
- t.Run(name, func(t *testing.T) {
- // Double check that the inputs make sense using
- // standard 64-bit division.
- ret64 := tc.num / int64(tc.div)
- rem64 := tc.num % int64(tc.div)
- if ret64 != int64(int32(ret64)) {
- // Simulate timediv overflow value.
- ret64 = 1<<31 - 1
- rem64 = 0
- }
- if ret64 != int64(tc.ret) {
- t.Errorf("%d / %d got ret %d rem %d want ret %d rem %d", tc.num, tc.div, ret64, rem64, tc.ret, tc.rem)
- }
-
- var rem int32
- ret := Timediv(tc.num, tc.div, &rem)
- if ret != tc.ret || rem != tc.rem {
- t.Errorf("timediv %d / %d got ret %d rem %d want ret %d rem %d", tc.num, tc.div, ret, rem, tc.ret, tc.rem)
- }
- })
- }
-}
-
func BenchmarkProcYield(b *testing.B) {
benchN := func(n uint32) func(*testing.B) {
return func(b *testing.B) {