Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/stdx/src/thread/pool.rs')
-rw-r--r--crates/stdx/src/thread/pool.rs31
1 files changed, 14 insertions, 17 deletions
diff --git a/crates/stdx/src/thread/pool.rs b/crates/stdx/src/thread/pool.rs
index b4ab9cb292..2ddd7da74c 100644
--- a/crates/stdx/src/thread/pool.rs
+++ b/crates/stdx/src/thread/pool.rs
@@ -1,6 +1,7 @@
//! [`Pool`] implements a basic custom thread pool
//! inspired by the [`threadpool` crate](http://docs.rs/threadpool).
-//! It allows the spawning of tasks under different QoS classes.
+//! When you spawn a task you specify a thread intent
+//! so the pool can schedule it to run on a thread with that intent.
//! rust-analyzer uses this to prioritize work based on latency requirements.
//!
//! The thread pool is implemented entirely using
@@ -13,10 +14,7 @@ use std::sync::{
use crossbeam_channel::{Receiver, Sender};
-use super::{
- get_current_thread_qos_class, set_current_thread_qos_class, Builder, JoinHandle, QoSClass,
- IS_QOS_AVAILABLE,
-};
+use super::{Builder, JoinHandle, ThreadIntent};
pub struct Pool {
// `_handles` is never read: the field is present
@@ -32,32 +30,32 @@ pub struct Pool {
}
struct Job {
- requested_qos_class: QoSClass,
+ requested_intent: ThreadIntent,
f: Box<dyn FnOnce() + Send + 'static>,
}
impl Pool {
pub fn new(threads: usize) -> Pool {
const STACK_SIZE: usize = 8 * 1024 * 1024;
- const INITIAL_QOS_CLASS: QoSClass = QoSClass::Utility;
+ const INITIAL_INTENT: ThreadIntent = ThreadIntent::Worker;
let (job_sender, job_receiver) = crossbeam_channel::unbounded();
let extant_tasks = Arc::new(AtomicUsize::new(0));
let mut handles = Vec::with_capacity(threads);
for _ in 0..threads {
- let handle = Builder::new(INITIAL_QOS_CLASS)
+ let handle = Builder::new(INITIAL_INTENT)
.stack_size(STACK_SIZE)
.name("Worker".into())
.spawn({
let extant_tasks = Arc::clone(&extant_tasks);
let job_receiver: Receiver<Job> = job_receiver.clone();
move || {
- let mut current_qos_class = INITIAL_QOS_CLASS;
+ let mut current_intent = INITIAL_INTENT;
for job in job_receiver {
- if job.requested_qos_class != current_qos_class {
- set_current_thread_qos_class(job.requested_qos_class);
- current_qos_class = job.requested_qos_class;
+ if job.requested_intent != current_intent {
+ job.requested_intent.apply_to_current_thread();
+ current_intent = job.requested_intent;
}
extant_tasks.fetch_add(1, Ordering::SeqCst);
(job.f)();
@@ -73,19 +71,18 @@ impl Pool {
Pool { _handles: handles, extant_tasks, job_sender }
}
- pub fn spawn<F>(&self, qos_class: QoSClass, f: F)
+ pub fn spawn<F>(&self, intent: ThreadIntent, f: F)
where
F: FnOnce() + Send + 'static,
{
let f = Box::new(move || {
- if IS_QOS_AVAILABLE {
- debug_assert_eq!(get_current_thread_qos_class(), Some(qos_class));
+ if cfg!(debug_assertions) {
+ intent.assert_is_used_on_current_thread();
}
-
f()
});
- let job = Job { requested_qos_class: qos_class, f };
+ let job = Job { requested_intent: intent, f };
self.job_sender.send(job).unwrap();
}