diff options
author | bfredl <bjorn.linse@gmail.com> | 2023-04-25 12:32:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-25 12:32:06 +0200 |
commit | 965ad7726f91c2597ef6eb7a740ae024da99ec9b (patch) | |
tree | 431f38d607eb9b3f9b589cae64cf90e718fca42e | |
parent | a4b2400804355e99813f39a6b38d8f38667f8bdd (diff) | |
parent | 0d2fe7786537ef63d0d3ed1e94546eb3ee35a368 (diff) | |
download | rneovim-965ad7726f91c2597ef6eb7a740ae024da99ec9b.tar.gz rneovim-965ad7726f91c2597ef6eb7a740ae024da99ec9b.tar.bz2 rneovim-965ad7726f91c2597ef6eb7a740ae024da99ec9b.zip |
Merge pull request #23293 from bfredl/bigsleep
refactor(time): refactor delay with input checking
-rw-r--r-- | src/nvim/main.c | 3 | ||||
-rw-r--r-- | src/nvim/os/input.c | 10 | ||||
-rw-r--r-- | src/nvim/os/time.c | 63 | ||||
-rw-r--r-- | src/nvim/ui.c | 4 | ||||
-rw-r--r-- | src/nvim/ui_compositor.c | 2 | ||||
-rw-r--r-- | test/unit/helpers.lua | 1 |
6 files changed, 22 insertions, 61 deletions
diff --git a/src/nvim/main.c b/src/nvim/main.c index db366160f6..657f9c67f2 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -173,7 +173,7 @@ bool event_teardown(void) /// Performs early initialization. /// -/// Needed for unit tests. Must be called after `time_init()`. +/// Needed for unit tests. void early_init(mparm_T *paramp) { estack_init(); @@ -261,7 +261,6 @@ int main(int argc, char **argv) mparm_T params; // various parameters passed between // main() and other functions. char *cwd = NULL; // current working dir on startup - time_init(); // Many variables are in `params` so that we can pass them around easily. // `argc` and `argv` are also copied, so that they can be changed. diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index d472836d0a..e9f23eba40 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -441,7 +441,7 @@ bool input_blocking(void) // This is a replacement for the old `WaitForChar` function in os_unix.c static InbufPollResult inbuf_poll(int ms, MultiQueue *events) { - if (input_ready(events)) { + if (os_input_ready(events)) { return kInputAvail; } @@ -457,14 +457,14 @@ static InbufPollResult inbuf_poll(int ms, MultiQueue *events) DLOG("blocking... events_enabled=%d events_pending=%d", events != NULL, events && !multiqueue_empty(events)); LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, - input_ready(events) || input_eof); + os_input_ready(events) || input_eof); blocking = false; if (do_profiling == PROF_YES && ms) { prof_inchar_exit(); } - if (input_ready(events)) { + if (os_input_ready(events)) { return kInputAvail; } return input_eof ? kInputEof : kInputNone; @@ -530,8 +530,8 @@ static int push_event_key(uint8_t *buf, int maxlen) return buf_idx; } -// Check if there's pending input -static bool input_ready(MultiQueue *events) +/// Check if there's pending input already in typebuf or `events` +bool os_input_ready(MultiQueue *events) { return (typebuf_was_filled // API call filled typeahead || rbuffer_size(input_buffer) // Input buffer filled diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 873302a27d..8d77e58177 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -24,20 +24,10 @@ struct tm; -static uv_mutex_t delay_mutex; -static uv_cond_t delay_cond; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/time.c.generated.h" // IWYU pragma: export #endif -/// Initializes the time module -void time_init(void) -{ - uv_mutex_init(&delay_mutex); - uv_cond_init(&delay_cond); -} - /// Gets a high-resolution (nanosecond), monotonically-increasing time relative /// to an arbitrary time in the past. /// @@ -73,55 +63,28 @@ uint64_t os_now(void) void os_delay(uint64_t ms, bool ignoreinput) { DLOG("%" PRIu64 " ms", ms); - if (ignoreinput) { - if (ms > INT_MAX) { - ms = INT_MAX; - } - LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, (int)ms, got_int); - } else { - os_microdelay(ms * 1000U, ignoreinput); + if (ms > INT_MAX) { + ms = INT_MAX; } + LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, (int)ms, + ignoreinput ? got_int : os_input_ready(NULL)); } -/// Sleeps for `us` microseconds. +/// Sleeps for `ms` milliseconds without checking for events or interrupts. +/// +/// This blocks even "fast" events which is quite disruptive. This should only +/// be used in debug code. Prefer os_delay() and decide if the delay should be +/// interupted by input or only a CTRL-C. /// /// @see uv_sleep() (libuv v1.34.0) /// /// @param us Number of microseconds to sleep. -/// @param ignoreinput If true, ignore all input (including SIGINT/CTRL-C). -/// If false, waiting is aborted on any input. -void os_microdelay(uint64_t us, bool ignoreinput) +void os_sleep(uint64_t ms) { - uint64_t elapsed = 0U; - uint64_t base = uv_hrtime(); - // Convert microseconds to nanoseconds, or UINT64_MAX on overflow. - const uint64_t ns = (us < UINT64_MAX / 1000U) ? us * 1000U : UINT64_MAX; - - uv_mutex_lock(&delay_mutex); - - while (elapsed < ns) { - // If ignoring input, we simply wait the full delay. - // Else we check for input in ~100ms intervals. - const uint64_t ns_delta = ignoreinput - ? ns - elapsed - : MIN(ns - elapsed, 100000000U); // 100ms - - const int rv = uv_cond_timedwait(&delay_cond, &delay_mutex, ns_delta); - if (0 != rv && UV_ETIMEDOUT != rv) { - abort(); - break; - } // Else: Timeout proceeded normally. - - if (!ignoreinput && os_char_avail()) { - break; - } - - const uint64_t now = uv_hrtime(); - elapsed += now - base; - base = now; + if (ms > UINT_MAX) { + ms = UINT_MAX; } - - uv_mutex_unlock(&delay_mutex); + uv_sleep((unsigned)ms); } // Cache of the current timezone name as retrieved from TZ, or an empty string diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 45959b7b67..6d09b9f3a3 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -439,7 +439,7 @@ void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, MIN(clearcol, (int)grid->cols - 1)); ui_call_flush(); uint64_t wd = (uint64_t)labs(p_wd); - os_microdelay(wd * 1000U, true); + os_sleep(wd); pending_cursor_update = true; // restore the cursor later } } @@ -521,7 +521,7 @@ void ui_flush(void) ui_call_flush(); if (p_wd && (rdb_flags & RDB_FLUSH)) { - os_microdelay((uint64_t)labs(p_wd) * 1000U, true); + os_sleep((uint64_t)labs(p_wd)); } } diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index 9ff9eabff8..8d279aa998 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -467,7 +467,7 @@ static void debug_delay(Integer lines) ui_call_flush(); uint64_t wd = (uint64_t)labs(p_wd); uint64_t factor = (uint64_t)MAX(MIN(lines, 5), 1); - os_microdelay(factor * wd * 1000U, true); + os_sleep(factor * wd); } static void compose_area(Integer startrow, Integer endrow, Integer startcol, Integer endcol) diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua index 10b7594a88..8fa6378d10 100644 --- a/test/unit/helpers.lua +++ b/test/unit/helpers.lua @@ -97,7 +97,6 @@ local init = only_separate(function() for _, c in ipairs(child_calls_init) do c.func(unpack(c.args)) end - libnvim.time_init() libnvim.fs_init() libnvim.event_init() libnvim.early_init(nil) |