From 493a903f226d148fec4b539f65b78a408e4dcb2c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 26 Jan 2020 12:02:56 +0100 Subject: [PATCH] Bump main thread priority on windows --- Cargo.lock | 1 + crates/ra_lsp_server/Cargo.toml | 3 +++ crates/ra_lsp_server/src/main_loop.rs | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 07fff9af5d..8e320458bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1079,6 +1079,7 @@ dependencies = [ "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "test_utils 0.1.0", "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index 5df0496dd7..fdf81ed87c 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml @@ -30,6 +30,9 @@ env_logger = { version = "0.7.1", default-features = false } ra_cargo_watch = { path = "../ra_cargo_watch" } either = "1.5" +[target.'cfg(windows)'.dependencies] +winapi = "0.3" + [dev-dependencies] tempfile = "3" test_utils = { path = "../test_utils" } diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 315f4a4d60..15bf519c9a 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -57,6 +57,25 @@ pub fn main_loop( ) -> Result<()> { log::info!("server_config: {:#?}", config); + // Windows scheduler implements priority boosts: if thread waits for an + // event (like a condvar), and event fires, priority of the thread is + // temporary bumped. This optimization backfires in our case: each time the + // `main_loop` schedules a task to run on a threadpool, the worker threads + // gets a higher priority, and (on a machine with fewer cores) displaces the + // main loop! We work-around this by marking the main loop as a + // higher-priority thread. + // + // https://docs.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities + // https://docs.microsoft.com/en-us/windows/win32/procthread/priority-boosts + // https://github.com/rust-analyzer/rust-analyzer/issues/2835 + #[cfg(windows)] + unsafe { + use winapi::um::processthreadsapi::*; + let thread = GetCurrentThread(); + let thread_priority_above_normal = 1; + SetThreadPriority(thread, thread_priority_above_normal); + } + let mut loop_state = LoopState::default(); let mut world_state = { let feature_flags = {