Commit a1ee0a21 authored by Dmitry Vyukov's avatar Dmitry Vyukov

runtime, time: refactor startNano handling

Move startNano from runtime to time package.
In preparation for a subsequent change that speeds up Since and Until.
This also makes code simpler as we have less assembly as the result,
monotonic time handling is better localized in time package.
This changes values returned from nanotime on windows
(it does not account for startNano anymore), current comments state
that it's important, but it's unclear how it can be important
since no other OS does this.

Update #25729

Change-Id: I2275d57b7b5ed8fd0d53eb0f19d55a86136cc555
Reviewed-on: https://go-review.googlesource.com/c/146340Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent a86f5497
...@@ -157,8 +157,7 @@ func main() { ...@@ -157,8 +157,7 @@ func main() {
} }
}() }()
// Record when the world started. Must be after runtime_init // Record when the world started.
// because nanotime on some platforms depends on startNano.
runtimeInitTime = nanotime() runtimeInitTime = nanotime()
gcenable() gcenable()
......
...@@ -455,9 +455,7 @@ loop: ...@@ -455,9 +455,7 @@ loop:
MULL CX MULL CX
IMULL $100, DI IMULL $100, DI
ADDL DI, DX ADDL DI, DX
// wintime*100 = DX:AX, subtract startNano and return // wintime*100 = DX:AX
SUBL runtime·startNano+0(SB), AX
SBBL runtime·startNano+4(SB), DX
MOVL AX, ret_lo+0(FP) MOVL AX, ret_lo+0(FP)
MOVL DX, ret_hi+4(FP) MOVL DX, ret_hi+4(FP)
RET RET
...@@ -482,9 +480,6 @@ loop: ...@@ -482,9 +480,6 @@ loop:
IMULL $100, DI IMULL $100, DI
ADDL DI, DX ADDL DI, DX
// w*100 = DX:AX // w*100 = DX:AX
// subtract startNano and save for return
SUBL runtime·startNano+0(SB), AX
SBBL runtime·startNano+4(SB), DX
MOVL AX, mono+12(FP) MOVL AX, mono+12(FP)
MOVL DX, mono+16(FP) MOVL DX, mono+16(FP)
......
...@@ -486,7 +486,6 @@ loop: ...@@ -486,7 +486,6 @@ loop:
SHLQ $32, CX SHLQ $32, CX
ORQ BX, CX ORQ BX, CX
IMULQ $100, CX IMULQ $100, CX
SUBQ runtime·startNano(SB), CX
MOVQ CX, ret+0(FP) MOVQ CX, ret+0(FP)
RET RET
useQPC: useQPC:
...@@ -506,7 +505,6 @@ loop: ...@@ -506,7 +505,6 @@ loop:
SHLQ $32, AX SHLQ $32, AX
ORQ BX, AX ORQ BX, AX
IMULQ $100, AX IMULQ $100, AX
SUBQ runtime·startNano(SB), AX
MOVQ AX, mono+16(FP) MOVQ AX, mono+16(FP)
MOVQ $_SYSTEM_TIME, DI MOVQ $_SYSTEM_TIME, DI
......
...@@ -510,11 +510,7 @@ loop: ...@@ -510,11 +510,7 @@ loop:
MULLU R0, R2, (R4, R3) // R4:R3 = R1:R0 * R2 MULLU R0, R2, (R4, R3) // R4:R3 = R1:R0 * R2
MULA R1, R2, R4, R4 MULA R1, R2, R4, R4
// wintime*100 = R4:R3, subtract startNano and return // wintime*100 = R4:R3
MOVW runtime·startNano+0(SB), R0
MOVW runtime·startNano+4(SB), R1
SUB.S R0, R3
SBC R1, R4
MOVW R3, ret_lo+0(FP) MOVW R3, ret_lo+0(FP)
MOVW R4, ret_hi+4(FP) MOVW R4, ret_hi+4(FP)
RET RET
...@@ -540,11 +536,7 @@ loop: ...@@ -540,11 +536,7 @@ loop:
MULLU R0, R2, (R4, R3) // R4:R3 = R1:R0 * R2 MULLU R0, R2, (R4, R3) // R4:R3 = R1:R0 * R2
MULA R1, R2, R4, R4 MULA R1, R2, R4, R4
// wintime*100 = R4:R3, subtract startNano and return // wintime*100 = R4:R3
MOVW runtime·startNano+0(SB), R0
MOVW runtime·startNano+4(SB), R1
SUB.S R0, R3
SBC R1, R4
MOVW R3, mono+12(FP) MOVW R3, mono+12(FP)
MOVW R4, mono+16(FP) MOVW R4, mono+16(FP)
......
...@@ -470,11 +470,3 @@ func poll_runtimeNano() int64 { ...@@ -470,11 +470,3 @@ func poll_runtimeNano() int64 {
func time_runtimeNano() int64 { func time_runtimeNano() int64 {
return nanotime() return nanotime()
} }
// Monotonic times are reported as offsets from startNano.
// We initialize startNano to nanotime() - 1 so that on systems where
// monotonic time resolution is fairly low (e.g. Windows 2008
// which appears to have a default resolution of 15ms),
// we avoid ever reporting a nanotime of 0.
// (Callers may want to use 0 as "time not set".)
var startNano int64 = nanotime() - 1
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Declarations for operating systems implementing time.now directly in assembly. // Declarations for operating systems implementing time.now directly in assembly.
// Those systems are also expected to have nanotime subtract startNano,
// so that time.now and nanotime return the same monotonic clock readings.
// +build windows // +build windows
......
...@@ -14,5 +14,5 @@ import _ "unsafe" // for go:linkname ...@@ -14,5 +14,5 @@ import _ "unsafe" // for go:linkname
//go:linkname time_now time.now //go:linkname time_now time.now
func time_now() (sec int64, nsec int32, mono int64) { func time_now() (sec int64, nsec int32, mono int64) {
sec, nsec = walltime() sec, nsec = walltime()
return sec, nsec, nanotime() - startNano return sec, nsec, nanotime()
} }
...@@ -8,9 +8,6 @@ package time ...@@ -8,9 +8,6 @@ package time
// A negative or zero duration causes Sleep to return immediately. // A negative or zero duration causes Sleep to return immediately.
func Sleep(d Duration) func Sleep(d Duration)
// runtimeNano returns the current value of the runtime clock in nanoseconds.
func runtimeNano() int64
// Interface to timers implemented in package runtime. // Interface to timers implemented in package runtime.
// Must be in sync with ../runtime/time.go:/^type timer // Must be in sync with ../runtime/time.go:/^type timer
type runtimeTimer struct { type runtimeTimer struct {
......
...@@ -1050,9 +1050,21 @@ func daysIn(m Month, year int) int { ...@@ -1050,9 +1050,21 @@ func daysIn(m Month, year int) int {
// Provided by package runtime. // Provided by package runtime.
func now() (sec int64, nsec int32, mono int64) func now() (sec int64, nsec int32, mono int64)
// runtimeNano returns the current value of the runtime clock in nanoseconds.
func runtimeNano() int64
// Monotonic times are reported as offsets from startNano.
// We initialize startNano to runtimeNano() - 1 so that on systems where
// monotonic time resolution is fairly low (e.g. Windows 2008
// which appears to have a default resolution of 15ms),
// we avoid ever reporting a monotonic time of 0.
// (Callers may want to use 0 as "time not set".)
var startNano int64 = runtimeNano() - 1
// Now returns the current local time. // Now returns the current local time.
func Now() Time { func Now() Time {
sec, nsec, mono := now() sec, nsec, mono := now()
mono -= startNano
sec += unixToInternal - minWall sec += unixToInternal - minWall
if uint64(sec)>>33 != 0 { if uint64(sec)>>33 != 0 {
return Time{uint64(nsec), sec + minWall, Local} return Time{uint64(nsec), sec + minWall, Local}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment