Skip to content

Commit f9ce939

Browse files
authored
perf: scheduler priority clamping on macOS neovim#35488
Problem: All of Nvim’s threads are clamped to the Default QoS class. This means that Nvim is forced to compete for CPU time with compilers and other batch work, and is even prioritized beneath user-initiated work in GUI apps like e.g. file imports. This significantly harms responsiveness. Solution: Tell the kernel that the Nvim process takes part in rendering a UI. Implementation: Remove the process-wide QoS clamp. This doesn’t directly do anything to the main thread, but rather has the side-effect of letting the main thread run at its actual QoS (User Interactive QoS).
1 parent 1ae09bf commit f9ce939

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

src/nvim/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ static bool event_teardown(void)
188188
/// Needed for unit tests.
189189
void early_init(mparm_T *paramp)
190190
{
191+
os_hint_priority();
191192
estack_init();
192193
cmdline_init();
193194
eval_init(); // init global variables

src/nvim/os/env.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
# include "nvim/fileio.h"
4040
#endif
4141

42+
#ifdef __APPLE__
43+
# include <mach/task.h>
44+
#endif
45+
4246
#ifdef HAVE__NSGETENVIRON
4347
# include <crt_externs.h>
4448
#endif
@@ -367,6 +371,18 @@ int64_t os_get_pid(void)
367371
#endif
368372
}
369373

374+
/// Signals to the OS that Nvim is an application for "interactive work"
375+
/// which should be prioritized similar to a GUI app.
376+
void os_hint_priority(void)
377+
{
378+
#ifdef __APPLE__
379+
// By default, processes have the TASK_UNSPECIFIED "role", which means all of its threads are
380+
// clamped to Default QoS. Setting the role to TASK_DEFAULT_APPLICATION removes this clamp.
381+
integer_t policy = TASK_DEFAULT_APPLICATION;
382+
task_policy_set(mach_task_self(), TASK_CATEGORY_POLICY, &policy, 1);
383+
#endif
384+
}
385+
370386
/// Gets the hostname of the current machine.
371387
///
372388
/// @param hostname Buffer to store the hostname.

0 commit comments

Comments
 (0)