Auto merge of #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.
This commit is contained in:
bors 2023-01-09 11:53:23 +00:00
commit fe8ee9c43a
5 changed files with 24 additions and 2 deletions

View file

@ -409,6 +409,9 @@ config_data! {
/// Whether to show `can't find Cargo.toml` error message.
notifications_cargoTomlNotFound: bool = "true",
/// How many worker threads in the main loop. The default `null` means to pick automatically.
numThreads: Option<usize> = "null",
/// Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set.
procMacro_attributes_enable: bool = "true",
/// Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`.
@ -1482,6 +1485,10 @@ impl Config {
}
}
pub fn main_loop_num_threads(&self) -> usize {
self.data.numThreads.unwrap_or(num_cpus::get_physical().try_into().unwrap_or(1))
}
pub fn typing_autoclose_angle(&self) -> bool {
self.data.typing_autoClosingAngleBrackets_enable
}

View file

@ -134,7 +134,7 @@ impl GlobalState {
let task_pool = {
let (sender, receiver) = unbounded();
let handle = TaskPool::new(sender);
let handle = TaskPool::new_with_threads(sender, config.main_loop_num_threads());
Handle { handle, receiver }
};

View file

@ -8,12 +8,13 @@ pub(crate) struct TaskPool<T> {
}
impl<T> TaskPool<T> {
pub(crate) fn new(sender: Sender<T>) -> TaskPool<T> {
pub(crate) fn new_with_threads(sender: Sender<T>, threads: usize) -> TaskPool<T> {
const STACK_SIZE: usize = 8 * 1024 * 1024;
let inner = threadpool::Builder::new()
.thread_name("Worker".into())
.thread_stack_size(STACK_SIZE)
.num_threads(threads)
.build();
TaskPool { sender, inner }
}

View file

@ -619,6 +619,11 @@ Number of syntax trees rust-analyzer keeps in memory. Defaults to 128.
--
Whether to show `can't find Cargo.toml` error message.
--
[[rust-analyzer.numThreads]]rust-analyzer.numThreads (default: `null`)::
+
--
How many worker threads in the main loop. The default `null` means to pick automatically.
--
[[rust-analyzer.procMacro.attributes.enable]]rust-analyzer.procMacro.attributes.enable (default: `true`)::
+
--

View file

@ -1177,6 +1177,15 @@
"default": true,
"type": "boolean"
},
"rust-analyzer.numThreads": {
"markdownDescription": "How many worker threads in the main loop. The default `null` means to pick automatically.",
"default": null,
"type": [
"null",
"integer"
],
"minimum": 0
},
"rust-analyzer.procMacro.attributes.enable": {
"markdownDescription": "Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set.",
"default": true,