From a5ecb9bca57a481113300642655045b02fc69b3c Mon Sep 17 00:00:00 2001 From: Jeff Erbrecht Date: Mon, 19 Dec 2022 11:43:31 -0500 Subject: [PATCH] [host] windows: use millisecond precision for BootTime() Previously, system uptime is truncated to seconds, and then the subtraction from `time.Now()` is performed. Because uptime does not roll over to the next second at the same instant as `time.Now()`, then `BootTime()` ends up not being precise, and often varies by 1 second. This commit does the subtraction before truncating to seconds, which results in a significantly lower chance of variance in `BootTime()`. --- host/host.go | 4 ++++ host/host_windows.go | 14 +++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/host/host.go b/host/host.go index 7c53e20..f363eed 100644 --- a/host/host.go +++ b/host/host.go @@ -155,3 +155,7 @@ func SensorsTemperatures() ([]TemperatureStat, error) { func timeSince(ts uint64) uint64 { return uint64(time.Now().Unix()) - ts } + +func timeSinceMillis(ts uint64) uint64 { + return uint64(time.Now().UnixMilli()) - ts +} diff --git a/host/host_windows.go b/host/host_windows.go index a16892d..1fe0551 100644 --- a/host/host_windows.go +++ b/host/host_windows.go @@ -103,6 +103,14 @@ func numProcs(ctx context.Context) (uint64, error) { } func UptimeWithContext(ctx context.Context) (uint64, error) { + up, err := uptimeMillis() + if err != nil { + return 0, err + } + return uint64((time.Duration(up) * time.Millisecond).Seconds()), nil +} + +func uptimeMillis() (uint64, error) { procGetTickCount := procGetTickCount64 err := procGetTickCount64.Find() if err != nil { @@ -112,7 +120,7 @@ func UptimeWithContext(ctx context.Context) (uint64, error) { if lastErr != 0 { return 0, lastErr } - return uint64((time.Duration(r1) * time.Millisecond).Seconds()), nil + return uint64(r1), nil } // cachedBootTime must be accessed via atomic.Load/StoreUint64 @@ -123,11 +131,11 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) { if t != 0 { return t, nil } - up, err := Uptime() + up, err := uptimeMillis() if err != nil { return 0, err } - t = timeSince(up) + t = uint64((time.Duration(timeSinceMillis(up)) * time.Millisecond).Seconds()) atomic.StoreUint64(&cachedBootTime, t) return t, nil }