From 4c8486e1f2b99f7f19d8a6556933b23e7f7fe1cb Mon Sep 17 00:00:00 2001 From: Luna Razzaghipour Date: Wed, 3 Sep 2025 11:34:46 +1000 Subject: [PATCH] perf: scheduler priority clamping on macOS #35488 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). (cherry picked from commit f9ce939bf53b84f7e6e4ecca3875dd0c378991db) --- src/nvim/main.c | 1 + src/nvim/os/env.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/nvim/main.c b/src/nvim/main.c index 387523c571..5c1e415cb7 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -190,6 +190,7 @@ static bool event_teardown(void) /// Needed for unit tests. void early_init(mparm_T *paramp) { + os_hint_priority(); estack_init(); cmdline_init(); eval_init(); // init global variables diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 21da64a1ee..940d2236a7 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -39,6 +39,10 @@ # include "nvim/fileio.h" #endif +#ifdef __APPLE__ +# include +#endif + #ifdef HAVE__NSGETENVIRON # include #endif @@ -352,6 +356,18 @@ int64_t os_get_pid(void) #endif } +/// Signals to the OS that Nvim is an application for "interactive work" +/// which should be prioritized similar to a GUI app. +void os_hint_priority(void) +{ +#ifdef __APPLE__ + // By default, processes have the TASK_UNSPECIFIED "role", which means all of its threads are + // clamped to Default QoS. Setting the role to TASK_DEFAULT_APPLICATION removes this clamp. + integer_t policy = TASK_DEFAULT_APPLICATION; + task_policy_set(mach_task_self(), TASK_CATEGORY_POLICY, &policy, 1); +#endif +} + /// Gets the hostname of the current machine. /// /// @param hostname Buffer to store the hostname.