diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index d45c2bd765..447e607436 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -217,7 +217,7 @@ UI VIMSCRIPT • |v:exitreason| is set before |QuitPre|. -• |v:starttime| is the process start time (monotonic nanoseconds). +• |v:starttime| is the process start time (nanoseconds from UNIX epoch). ============================================================================== CHANGED FEATURES *news-changed* diff --git a/runtime/doc/vvars.txt b/runtime/doc/vvars.txt index 6a885f6a4f..5d7efac2c8 100644 --- a/runtime/doc/vvars.txt +++ b/runtime/doc/vvars.txt @@ -635,11 +635,11 @@ v:stacktrace *v:starttime* *starttime-variable* v:starttime - Timestamp (monotonic nanoseconds) when the Nvim process + Timestamp (nanoseconds from UNIX epoch) when the Nvim process started. To see the current "uptime": >lua - vim.print(('uptime: %d seconds'):format((vim.uv.hrtime() - vim.v.starttime) / 1e9)) + vim.print(('uptime: %d seconds'):format(os.time() - (vim.v.starttime / 1e9))) < Read-only. diff --git a/runtime/lua/vim/_core/ex_cmd.lua b/runtime/lua/vim/_core/ex_cmd.lua index bff960e39d..81232abf74 100644 --- a/runtime/lua/vim/_core/ex_cmd.lua +++ b/runtime/lua/vim/_core/ex_cmd.lua @@ -259,7 +259,9 @@ function M.ex_terminal(eap, shell_argv) end function M.ex_uptime() - local uptime = math.floor((uv.hrtime() - vim.v.starttime) / 1e9) + -- os.time() might lead to uptime == -1 when this is called too quickly after startup + local now = assert(uv.clock_gettime('realtime')) + local uptime = math.floor((now.sec * 1e9 + now.nsec - vim.v.starttime) / 1e9) local uptime_display = time.fmt_rtime(uptime) api.nvim_echo({ { N_('Up %s'):format(uptime_display) } }, true, {}) end diff --git a/runtime/lua/vim/_meta/vvars.gen.lua b/runtime/lua/vim/_meta/vvars.gen.lua index 7b5ca0e417..bee771bc23 100644 --- a/runtime/lua/vim/_meta/vvars.gen.lua +++ b/runtime/lua/vim/_meta/vvars.gen.lua @@ -667,13 +667,13 @@ vim.v.shell_error = ... --- @type table[] vim.v.stacktrace = ... ---- Timestamp (monotonic nanoseconds) when the Nvim process +--- Timestamp (nanoseconds from UNIX epoch) when the Nvim process --- started. --- --- To see the current "uptime": --- --- ```lua ---- vim.print(('uptime: %d seconds'):format((vim.uv.hrtime() - vim.v.starttime) / 1e9)) +--- vim.print(('uptime: %d seconds'):format(os.time() - (vim.v.starttime / 1e9))) --- ``` --- --- Read-only. diff --git a/src/nvim/main.c b/src/nvim/main.c index a1320648a4..4cfec6bd41 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -197,7 +197,7 @@ void early_init(mparm_T *paramp) estack_init(); cmdline_init(); eval_init(); // init global variables - set_vim_var_nr(VV_STARTTIME, (varnumber_T)os_hrtime()); + set_vim_var_nr(VV_STARTTIME, (varnumber_T)os_realtime()); init_path(argv0 ? argv0 : "nvim"); init_normal_cmds(); // Init the table of Normal mode commands. runtime_init(); diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index f243eda047..2e6bf3e56d 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -32,6 +32,25 @@ uint64_t os_hrtime(void) return uv_hrtime(); } +/// Obtain the current system time from a high-resolution +/// real-time clock source. +/// +/// The real-time clock counts from the UNIX epoch (1970-01-01) +/// and is subject to time adjustments; it can jump back in time. +/// +/// @return Nanoseconds since epoch or 0 +int64_t os_realtime(void) + FUNC_ATTR_WARN_UNUSED_RESULT +{ + uv_timespec64_t ts = { 0 }; + int error_number; + if ((error_number = uv_clock_gettime(UV_CLOCK_REALTIME, &ts)) != 0) { + ELOG("uv_clock_gettime failed: %d %s", error_number, uv_err_name(error_number)); + return 0; + } + return ts.tv_sec * 1000000000L + ts.tv_nsec; +} + /// Gets a millisecond-resolution, monotonically-increasing time relative to an /// arbitrary time in the past. /// diff --git a/src/nvim/vvars.lua b/src/nvim/vvars.lua index 648e5f1310..7096349125 100644 --- a/src/nvim/vvars.lua +++ b/src/nvim/vvars.lua @@ -756,11 +756,11 @@ M.vars = { starttime = { type = 'integer', desc = [=[ - Timestamp (monotonic nanoseconds) when the Nvim process + Timestamp (nanoseconds from UNIX epoch) when the Nvim process started. To see the current "uptime": >lua - vim.print(('uptime: %d seconds'):format((vim.uv.hrtime() - vim.v.starttime) / 1e9)) + vim.print(('uptime: %d seconds'):format(os.time() - (vim.v.starttime / 1e9))) < Read-only. ]=],