mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #23293 from bfredl/bigsleep
refactor(time): refactor delay with input checking
This commit is contained in:
commit
965ad7726f
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user