Skip to content

Commit fe8ee9c

Browse files
committed
Auto merge of rust-lang#13744 - vtta:numthreads, r=Veykril
feat: add the ability to limit the number of threads launched by `main_loop` ## Motivation `main_loop` defaults to launch as many threads as cpus in one machine. When developing on multi-core remote servers on multiple projects, this will lead to thousands of idle threads being created. This is very annoying when one wants check whether his program under developing is running correctly via `htop`. <img width="756" alt="image" src="https://user-images.githubusercontent.com/41831480/206656419-fa3f0dd2-e554-4f36-be1b-29d54739930c.png"> ## Contribution This patch introduce the configuration option `rust-analyzer.numThreads` to set the desired thread number used by the main thread pool. This should have no effects on the performance as not all threads are actually used. <img width="1325" alt="image" src="https://user-images.githubusercontent.com/41831480/206656834-fe625c4c-b993-4771-8a82-7427c297fd41.png"> ## Demonstration The following is a snippet of `lunarvim` configuration using my own build. ```lua vim.list_extend(lvim.lsp.automatic_configuration.skipped_servers, { "rust_analyzer" }) require("lvim.lsp.manager").setup("rust_analyzer", { cmd = { "env", "RA_LOG=debug", "RA_LOG_FILE=/tmp/ra-test.log", "/home/jlhu/Projects/rust-analyzer/target/debug/rust-analyzer", }, init_options = { numThreads = 4, }, settings = { cachePriming = { numThreads = 8, }, }, }) ``` ## Limitations The `numThreads` can only be modified via `initializationOptions` in early initialisation because everything has to wait until the thread pool starts including the dynamic settings modification support. The `numThreads` also does not reflect the end results of how many threads is actually created, because I have not yet tracked down everything that spawns threads.
2 parents 1e20bf3 + 9f5a547 commit fe8ee9c

File tree

5 files changed

+24
-2
lines changed

5 files changed

+24
-2
lines changed

crates/rust-analyzer/src/config.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@ config_data! {
409409
/// Whether to show `can't find Cargo.toml` error message.
410410
notifications_cargoTomlNotFound: bool = "true",
411411

412+
/// How many worker threads in the main loop. The default `null` means to pick automatically.
413+
numThreads: Option<usize> = "null",
414+
412415
/// Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set.
413416
procMacro_attributes_enable: bool = "true",
414417
/// Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`.
@@ -1482,6 +1485,10 @@ impl Config {
14821485
}
14831486
}
14841487

1488+
pub fn main_loop_num_threads(&self) -> usize {
1489+
self.data.numThreads.unwrap_or(num_cpus::get_physical().try_into().unwrap_or(1))
1490+
}
1491+
14851492
pub fn typing_autoclose_angle(&self) -> bool {
14861493
self.data.typing_autoClosingAngleBrackets_enable
14871494
}

crates/rust-analyzer/src/global_state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl GlobalState {
134134

135135
let task_pool = {
136136
let (sender, receiver) = unbounded();
137-
let handle = TaskPool::new(sender);
137+
let handle = TaskPool::new_with_threads(sender, config.main_loop_num_threads());
138138
Handle { handle, receiver }
139139
};
140140

crates/rust-analyzer/src/task_pool.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ pub(crate) struct TaskPool<T> {
88
}
99

1010
impl<T> TaskPool<T> {
11-
pub(crate) fn new(sender: Sender<T>) -> TaskPool<T> {
11+
pub(crate) fn new_with_threads(sender: Sender<T>, threads: usize) -> TaskPool<T> {
1212
const STACK_SIZE: usize = 8 * 1024 * 1024;
1313

1414
let inner = threadpool::Builder::new()
1515
.thread_name("Worker".into())
1616
.thread_stack_size(STACK_SIZE)
17+
.num_threads(threads)
1718
.build();
1819
TaskPool { sender, inner }
1920
}

docs/user/generated_config.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,11 @@ Number of syntax trees rust-analyzer keeps in memory. Defaults to 128.
619619
--
620620
Whether to show `can't find Cargo.toml` error message.
621621
--
622+
[[rust-analyzer.numThreads]]rust-analyzer.numThreads (default: `null`)::
623+
+
624+
--
625+
How many worker threads in the main loop. The default `null` means to pick automatically.
626+
--
622627
[[rust-analyzer.procMacro.attributes.enable]]rust-analyzer.procMacro.attributes.enable (default: `true`)::
623628
+
624629
--

editors/code/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,15 @@
11771177
"default": true,
11781178
"type": "boolean"
11791179
},
1180+
"rust-analyzer.numThreads": {
1181+
"markdownDescription": "How many worker threads in the main loop. The default `null` means to pick automatically.",
1182+
"default": null,
1183+
"type": [
1184+
"null",
1185+
"integer"
1186+
],
1187+
"minimum": 0
1188+
},
11801189
"rust-analyzer.procMacro.attributes.enable": {
11811190
"markdownDescription": "Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set.",
11821191
"default": true,

0 commit comments

Comments
 (0)