aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os/time.c
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2019-06-29 16:39:22 +0200
committerGitHub <noreply@github.com>2019-06-29 16:39:22 +0200
commite2ce5ff9d6168de0ffaf59d6bf20f20631a34a2d (patch)
tree937e9bb7204b5ed160feba358a95d5e036cedc7c /src/nvim/os/time.c
parent23a97949206bbe7dbbd3f7581bb2a24fabce116e (diff)
downloadrneovim-e2ce5ff9d6168de0ffaf59d6bf20f20631a34a2d.tar.gz
rneovim-e2ce5ff9d6168de0ffaf59d6bf20f20631a34a2d.tar.bz2
rneovim-e2ce5ff9d6168de0ffaf59d6bf20f20631a34a2d.zip
viml/profile: switch to uv_gettimeofday() #10356
Performance of high-resolution time (clock_gettime via uv_hrtime) is expensive on some systems. For profiling VimL, syntax, etc., we don't care about nanosecond-precision and monotonicity edge-cases, so avoid uv_hrtime(). closes #10328 From the uv__hrtime() source: https://github.com/libuv/libuv/blob/0cdb4a5b4b706d0e09413d9270da28f9a88dc083/src/unix/linux-core.c#L442-L462 /* Prefer CLOCK_MONOTONIC_COARSE if available but only when it has * millisecond granularity or better. CLOCK_MONOTONIC_COARSE is * serviced entirely from the vDSO, whereas CLOCK_MONOTONIC may * decide to make a costly system call. */ This micro-benchmark (Debug build) shows negligible differences on my system: #include <sys/time.h> ... proftime_T tm = profile_start(); int trials = 999999; int64_t t = 0; struct timeval tv; for (int i = 0; i < trials; i++) { t += gettimeofday(&tv,NULL); } tm = profile_end(tm); ILOG("%d trials of gettimeofday: %s", trials, profile_msg(tm)); tm = profile_start(); for (int i = 0; i < trials; i++) { t += os_hrtime(); } tm = profile_end(tm); ILOG("%d trials of os_hrtime: %s", trials, profile_msg(tm)); tm = profile_start(); for (int i = 0; i < trials; i++) { t += os_utime(); } tm = profile_end(tm); ILOG("%d trials of os_utime: %s", trials, profile_msg(tm)); ILOG("%zu", t);
Diffstat (limited to 'src/nvim/os/time.c')
-rw-r--r--src/nvim/os/time.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c
index 31ef1a0cd6..18239c5566 100644
--- a/src/nvim/os/time.c
+++ b/src/nvim/os/time.c
@@ -9,6 +9,7 @@
#include <uv.h>
+#include "nvim/assert.h"
#include "nvim/os/time.h"
#include "nvim/os/input.h"
#include "nvim/event/loop.h"
@@ -22,6 +23,7 @@ static uv_cond_t delay_cond;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/time.c.generated.h"
#endif
+
/// Initializes the time module
void time_init(void)
{
@@ -29,15 +31,53 @@ void time_init(void)
uv_cond_init(&delay_cond);
}
-/// Obtain a high-resolution timer value
+/// Gets the current time with microsecond (μs) precision.
+///
+/// Subject to system-clock quirks (drift, going backwards, skipping).
+/// But it is much faster than os_hrtime() on some systems. #10328
+///
+/// @see gettimeofday(2)
+///
+/// @return Current time in microseconds.
+uint64_t os_utime(void)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ uv_timeval64_t tm;
+ int e = uv_gettimeofday(&tm);
+ if (e != 0 || tm.tv_sec < 0 || tm.tv_usec < 0) {
+ return 0;
+ }
+ uint64_t rv = (uint64_t)tm.tv_sec * 1000 * 1000; // s => μs
+ STRICT_ADD(rv, tm.tv_usec, &rv, uint64_t);
+ return rv;
+}
+
+/// Gets a high-resolution (nanosecond), monotonically-increasing time relative
+/// to an arbitrary time in the past.
///
-/// @return a timer value, not related to the time of day and not subject
-/// to clock drift. The value is expressed in nanoseconds.
+/// Not related to the time of day and therefore not subject to clock drift.
+///
+/// @return Relative time value with nanosecond precision.
uint64_t os_hrtime(void)
+ FUNC_ATTR_WARN_UNUSED_RESULT
{
return uv_hrtime();
}
+/// Gets a millisecond-resolution, monotonically-increasing time relative to an
+/// arbitrary time in the past.
+///
+/// Not related to the time of day and therefore not subject to clock drift.
+/// The value is cached by the loop, it will not change until the next
+/// loop-tick (unless uv_update_time is called).
+///
+/// @return Relative time value with millisecond precision.
+uint64_t os_now(void)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return uv_now(&main_loop.uv);
+}
+
/// Sleeps for `ms` milliseconds.
///
/// @param ms Number of milliseconds to sleep