aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2023-04-25 12:32:06 +0200
committerGitHub <noreply@github.com>2023-04-25 12:32:06 +0200
commit965ad7726f91c2597ef6eb7a740ae024da99ec9b (patch)
tree431f38d607eb9b3f9b589cae64cf90e718fca42e
parenta4b2400804355e99813f39a6b38d8f38667f8bdd (diff)
parent0d2fe7786537ef63d0d3ed1e94546eb3ee35a368 (diff)
downloadrneovim-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.c3
-rw-r--r--src/nvim/os/input.c10
-rw-r--r--src/nvim/os/time.c63
-rw-r--r--src/nvim/ui.c4
-rw-r--r--src/nvim/ui_compositor.c2
-rw-r--r--test/unit/helpers.lua1
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)