]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: introduce and consistently use setNsec for timespec
authorIan Lance Taylor <iant@golang.org>
Thu, 14 Mar 2019 01:56:37 +0000 (18:56 -0700)
committerIan Lance Taylor <iant@golang.org>
Fri, 15 Mar 2019 03:37:49 +0000 (03:37 +0000)
The general code for setting a timespec value sometimes used set_nsec
and sometimes used a combination of set_sec and set_nsec. Standardize
on a setNsec function that takes a number of nanoseconds and splits
them up to set the tv_sec and tv_nsec fields. Consistently mark
setNsec as go:nosplit, since it has to be that way on some systems
including Darwin and GNU/Linux. Consistently use timediv on 32-bit
systems to help stay within split-stack limits on processors that
don't have a 64-bit division instruction.

Change-Id: I6396bb7ddbef171a96876bdeaf7a1c585a6d725b
Reviewed-on: https://go-review.googlesource.com/c/go/+/167389
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
34 files changed:
src/runtime/defs1_netbsd_386.go
src/runtime/defs1_netbsd_amd64.go
src/runtime/defs1_netbsd_arm.go
src/runtime/defs1_solaris_amd64.go
src/runtime/defs_aix_ppc64.go
src/runtime/defs_darwin_386.go
src/runtime/defs_darwin_amd64.go
src/runtime/defs_darwin_arm.go
src/runtime/defs_darwin_arm64.go
src/runtime/defs_dragonfly_amd64.go
src/runtime/defs_freebsd_386.go
src/runtime/defs_freebsd_amd64.go
src/runtime/defs_freebsd_arm.go
src/runtime/defs_linux_386.go
src/runtime/defs_linux_amd64.go
src/runtime/defs_linux_arm.go
src/runtime/defs_linux_arm64.go
src/runtime/defs_linux_mips64x.go
src/runtime/defs_linux_mipsx.go
src/runtime/defs_linux_ppc64.go
src/runtime/defs_linux_ppc64le.go
src/runtime/defs_linux_s390x.go
src/runtime/defs_nacl_386.go
src/runtime/defs_nacl_amd64p32.go
src/runtime/defs_nacl_arm.go
src/runtime/defs_openbsd_386.go
src/runtime/defs_openbsd_amd64.go
src/runtime/defs_openbsd_arm.go
src/runtime/os_darwin.go
src/runtime/os_freebsd.go
src/runtime/os_linux.go
src/runtime/os_netbsd.go
src/runtime/os_openbsd.go
src/runtime/runtime1.go

index c26f417a02e0a537ab3255e79887e389b3d074c4..3eae12eed0ef6c67206b7300b711eeddf52387fa 100644 (file)
@@ -106,12 +106,9 @@ type timespec struct {
        tv_nsec int32
 }
 
-func (ts *timespec) set_sec(x int32) {
-       ts.tv_sec = int64(x)
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = x
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
 }
 
 type timeval struct {
index 0704cd4fb3f129aba89d01e587c11b39bc64589c..51d55c91f935ee966180db224f8123f540c6aa9f 100644 (file)
@@ -108,12 +108,10 @@ type timespec struct {
        tv_nsec int64
 }
 
-func (ts *timespec) set_sec(x int32) {
-       ts.tv_sec = int64(x)
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = int64(x)
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type timeval struct {
index d2a13ad4b0267c5c295e7541eb2c939e9c935c7a..fadb3415b33f3cd29cec496825fd7118ff81b8f7 100644 (file)
@@ -108,12 +108,9 @@ type timespec struct {
        _       [4]byte // EABI
 }
 
-func (ts *timespec) set_sec(x int32) {
-       ts.tv_sec = int64(x)
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = x
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
 }
 
 type timeval struct {
index 5ee3c3fc275c2baa0a6e10f6b659a56fcb829a8a..64d51a7bd80241073cb43133815c7881e0aa53a2 100644 (file)
@@ -161,6 +161,12 @@ type timespec struct {
        tv_nsec int64
 }
 
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
+}
+
 type timeval struct {
        tv_sec  int64
        tv_usec int64
index e7480d06ba23a92178994381b6185a822f8d18f1..db17b90496504f9032b4e033a1ef8017702c4415 100644 (file)
@@ -126,6 +126,13 @@ type timespec struct {
        tv_sec  int64
        tv_nsec int64
 }
+
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
+}
+
 type timeval struct {
        tv_sec    int64
        tv_usec   int32
index ae56d154fafb0d334fd4b6b8555c5e435cb6d293..43dc08a078e381eb87a1929b6166dd5e27a77c69 100644 (file)
@@ -149,9 +149,8 @@ type timespec struct {
 }
 
 //go:nosplit
-func (t *timespec) set_nsec(ns int64) {
-       t.tv_sec = int32(ns / 1000000000)
-       t.tv_nsec = int32(ns % 1000000000)
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = timediv(ns, 1e9, &ts.tv_nsec)
 }
 
 type fpcontrol struct {
index a339ebd4c6cf416af1eb620122c92fe1483cec97..59b0effa135e2f076d43d4d87366f047094d30b4 100644 (file)
@@ -151,9 +151,9 @@ type timespec struct {
 }
 
 //go:nosplit
-func (t *timespec) set_nsec(ns int64) {
-       t.tv_sec = ns / 1000000000
-       t.tv_nsec = ns % 1000000000
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type fpcontrol struct {
index 148b0a764e06747e14b4b680516226e595201d72..243f52a5dfd8c3e0ecfe6074b09b393761010834 100644 (file)
@@ -151,9 +151,8 @@ type timespec struct {
 }
 
 //go:nosplit
-func (t *timespec) set_nsec(ns int64) {
-       t.tv_sec = int32(ns / 1000000000)
-       t.tv_nsec = int32(ns % 1000000000)
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = timediv(ns, 1e9, &ts.tv_nsec)
 }
 
 type floatstate32 struct {
index 46e6d9ff8c3441de9a9dbce7bc9b1062fad742ce..7056074f468f411bf86c511b13e6438a6d8b2a63 100644 (file)
@@ -151,9 +151,9 @@ type timespec struct {
 }
 
 //go:nosplit
-func (t *timespec) set_nsec(ns int64) {
-       t.tv_sec = ns / 1000000000
-       t.tv_nsec = ns % 1000000000
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type exceptionstate64 struct {
index c30da805ccb1736253ae40d424c766123a2d0f31..30f1b33845e612d0d6d6cfc799f9dbd9f3d17459 100644 (file)
@@ -174,8 +174,10 @@ type timespec struct {
        tv_nsec int64
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type timeval struct {
index afdf54055f7e00bde435d7b134bef2d8aff8f40c..c4d5c897d3ea980a35cfa88b5181476170db02cc 100644 (file)
@@ -191,8 +191,9 @@ type timespec struct {
        tv_nsec int32
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = int32(x)
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = timediv(ns, 1e9, &ts.tv_nsec)
 }
 
 type timeval struct {
index c88c0c55c7f096e80694d361b8be6b49550c23ec..89d36c270db8d99d401e7efc711a816bd9f09caf 100644 (file)
@@ -201,8 +201,10 @@ type timespec struct {
        tv_nsec int64
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type timeval struct {
index 0c21ea6cff1e26ec163dfbfa918067607a70fb86..cc8c924c3710a300d7097c1738440a8a4f7f8c1a 100644 (file)
@@ -163,8 +163,9 @@ type timespec struct {
        pad_cgo_0 [4]byte
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
 }
 
 type timeval struct {
index 0ebac17aefa9e87dedb6792a19a88f5d50b8c418..e2fcbcac7187a5a232441e5727edb8399c933593 100644 (file)
@@ -137,12 +137,9 @@ type timespec struct {
        tv_nsec int32
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = int32(x)
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = x
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = timediv(ns, 1e9, &ts.tv_nsec)
 }
 
 type timeval struct {
index c0a0ef0dd4ec5069628676e786af248625afb489..ddad7fddd442e63b5bc3d6ff7c28027c3d89736d 100644 (file)
@@ -99,12 +99,10 @@ type timespec struct {
        tv_nsec int64
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = int64(x)
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type timeval struct {
index 43946bb79ca8e507639348dc5513e96727e61143..9d10d664e1703c78b2b6c659c06d33c29b90801f 100644 (file)
@@ -94,12 +94,9 @@ type timespec struct {
        tv_nsec int32
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = int32(x)
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = x
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = timediv(ns, 1e9, &ts.tv_nsec)
 }
 
 type stackt struct {
index c2cc281ab4f5c23e63c0a7db60d1199113e0a3a1..b325a229a1d990df5873f05e20e9c29459ea5531 100644 (file)
@@ -99,12 +99,10 @@ type timespec struct {
        tv_nsec int64
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = int64(x)
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type timeval struct {
index 9dacd5d1e9bacbc99547e6adac3143caf3a0a7ff..a52d0d40cf249788e43d548790e6659310c0248a 100644 (file)
@@ -99,12 +99,10 @@ type timespec struct {
        tv_nsec int64
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = int64(x)
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type timeval struct {
index 9532ac54ee83da0b3c9c8b9e2f3bd46d9367c6e1..f3a1dd0cf0d7acfb09d89686d48da67af1f5d702 100644 (file)
@@ -99,13 +99,8 @@ type timespec struct {
 }
 
 //go:nosplit
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = int32(x)
-}
-
-//go:nosplit
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = x
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = timediv(ns, 1e9, &ts.tv_nsec)
 }
 
 type timeval struct {
index 5a4326da07a94e17dc2e1afdeefe281f9b227927..f438993721728e8c64d9ff34e13c14d3c75ea08e 100644 (file)
@@ -99,12 +99,10 @@ type timespec struct {
        tv_nsec int64
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = int64(x)
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type timeval struct {
index 5a4326da07a94e17dc2e1afdeefe281f9b227927..f438993721728e8c64d9ff34e13c14d3c75ea08e 100644 (file)
@@ -99,12 +99,10 @@ type timespec struct {
        tv_nsec int64
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = int64(x)
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type timeval struct {
index a6cc9c48e91de22e7561c02931e120069b35877c..19b99b5bdfb8c707d44e7b01b6f298d94b38a8fb 100644 (file)
@@ -95,12 +95,10 @@ type timespec struct {
        tv_nsec int64
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = int64(x)
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type timeval struct {
index 5e65e033ab3c58101ce99c327b6504583ecdba88..70dfcf2c515a81f859919b757e566b530d187f85 100644 (file)
@@ -14,6 +14,11 @@ type timespec struct {
        tv_nsec int32
 }
 
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
+}
+
 type excregs386 struct {
        eax    uint32
        ecx    uint32
index 27afc388ccabf5d65cf2a36ba883f146d54c17bf..37067483f4624bd1ff5d4cdd8de03d672eb50d3f 100644 (file)
@@ -14,6 +14,12 @@ type timespec struct {
        tv_nsec int32
 }
 
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = int32(ns % 1e9)
+}
+
 type excregs386 struct {
        eax    uint32
        ecx    uint32
index 817a3d3054ada20971b09c512779f8c6dd6eb3eb..89e539ea7b3f183041405936d862cabd86e5a6dc 100644 (file)
@@ -14,6 +14,11 @@ type timespec struct {
        tv_nsec int32
 }
 
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
+}
+
 type excregsarm struct {
        r0   uint32
        r1   uint32
index 7b956c44f071f5859b404d90123452619c87cb7c..0e59a0591a76815edca39d3941e36ad44afe0c32 100644 (file)
@@ -134,12 +134,9 @@ type timespec struct {
        tv_nsec int32
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = x
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
 }
 
 type timeval struct {
index 0a939057179e52ef3d4dd3ce9d4c5499e8bb0ec7..5cefac5858a606f1ccc6ec82b7dbdbf475cf5343 100644 (file)
@@ -144,12 +144,10 @@ type timespec struct {
        tv_nsec int64
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = int64(x)
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = ns / 1e9
+       ts.tv_nsec = ns % 1e9
 }
 
 type timeval struct {
index 59f9410e1d63fe6c1a9563f148610449be04d207..b187e9776f56c9eda0ce56d8c6699718b34d4c1f 100644 (file)
@@ -139,12 +139,9 @@ type timespec struct {
        pad_cgo_0 [4]byte
 }
 
-func (ts *timespec) set_sec(x int64) {
-       ts.tv_sec = x
-}
-
-func (ts *timespec) set_nsec(x int32) {
-       ts.tv_nsec = x
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+       ts.tv_sec = int64(timediv(ns, 1e9, &ts.tv_nsec))
 }
 
 type timeval struct {
index 26b02820cd32c12b70d7ecc94aff59b7e75bc977..18c15ad89ee48a7ad370aa821c7f87654a08c08b 100644 (file)
@@ -53,7 +53,7 @@ func semasleep(ns int64) int32 {
                                return -1
                        }
                        var t timespec
-                       t.set_nsec(ns - spent)
+                       t.setNsec(ns - spent)
                        err := pthread_cond_timedwait_relative_np(&mp.cond, &mp.mutex, &t)
                        if err == _ETIMEDOUT {
                                pthread_mutex_unlock(&mp.mutex)
index 08f7b0ecf047f3b917923120ee5f64d6d0658ab7..ba0afa23bfe6c459af47198a2de12ba173a303e3 100644 (file)
@@ -156,7 +156,7 @@ func futexsleep1(addr *uint32, val uint32, ns int64) {
        if ns >= 0 {
                var ut umtx_time
                ut._clockid = _CLOCK_MONOTONIC
-               ut._timeout.set_sec(int64(timediv(ns, 1000000000, (*int32)(unsafe.Pointer(&ut._timeout.tv_nsec)))))
+               ut._timeout.setNsec(ns)
                utp = &ut
        }
        ret := sys_umtx_op(addr, _UMTX_OP_WAIT_UINT_PRIVATE, val, unsafe.Sizeof(*utp), utp)
index a04c995c008c9ce96e70824e04143d0836172428..8f3afe05777e472da6a1aa7ec94cf2b989c8630a 100644 (file)
@@ -35,8 +35,6 @@ const (
 // Don't sleep longer than ns; ns < 0 means forever.
 //go:nosplit
 func futexsleep(addr *uint32, val uint32, ns int64) {
-       var ts timespec
-
        // Some Linux kernels have a bug where futex of
        // FUTEX_WAIT returns an internal error code
        // as an errno. Libpthread ignores the return value
@@ -47,19 +45,8 @@ func futexsleep(addr *uint32, val uint32, ns int64) {
                return
        }
 
-       // It's difficult to live within the no-split stack limits here.
-       // On ARM and 386, a 64-bit divide invokes a general software routine
-       // that needs more stack than we can afford. So we use timediv instead.
-       // But on real 64-bit systems, where words are larger but the stack limit
-       // is not, even timediv is too heavy, and we really need to use just an
-       // ordinary machine instruction.
-       if sys.PtrSize == 8 {
-               ts.set_sec(ns / 1000000000)
-               ts.set_nsec(int32(ns % 1000000000))
-       } else {
-               ts.tv_nsec = 0
-               ts.set_sec(int64(timediv(ns, 1000000000, (*int32)(unsafe.Pointer(&ts.tv_nsec)))))
-       }
+       var ts timespec
+       ts.setNsec(ns)
        futex(unsafe.Pointer(addr), _FUTEX_WAIT_PRIVATE, val, unsafe.Pointer(&ts), nil, 0)
 }
 
index 7deab3ed03569c134cf7c195e0e72f5b18fd5f86..fa3c9fa6493df35d39a3c0b5229b830fc527eb95 100644 (file)
@@ -148,9 +148,7 @@ func semasleep(ns int64) int32 {
                        if wait <= 0 {
                                return -1
                        }
-                       var nsec int32
-                       ts.set_sec(timediv(wait, 1000000000, &nsec))
-                       ts.set_nsec(nsec)
+                       ts.setNsec(wait)
                        tsp = &ts
                }
                ret := lwp_park(_CLOCK_MONOTONIC, _TIMER_RELTIME, tsp, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil)
index 353a5d94ba077ab1867d2a157464f2ff57d9620e..42fe315bcd795b998e7d823603f69ea41d9fa803 100644 (file)
@@ -139,10 +139,7 @@ func semasleep(ns int64) int32 {
        var tsp *timespec
        if ns >= 0 {
                var ts timespec
-               var nsec int32
-               ns += nanotime()
-               ts.set_sec(int64(timediv(ns, 1000000000, &nsec)))
-               ts.set_nsec(nsec)
+               ts.setNsec(ns + nanotime())
                tsp = &ts
        }
 
index a597e1cd7fe09836b653eb986f2f2471c67b52ad..ad29818e0a5d3680866b296299ceb78c97713d5a 100644 (file)
@@ -412,6 +412,7 @@ func setTraceback(level string) {
 // 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)