mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Add prefs to limit threadpool sizes (#34478)
* Add prefs to limit threadpool sizes Add preferences to control the size of threadpools, so that we can easily reduce the amount of runtime threads and test which pools benefit from more threads. Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com> * Add pref for Webrender threadpool Add a preference to limit the size of the webrender threadpool. Note: WebRender by default calls hooks which register the threads with a profiler instance that the embedder can register with webrender. Servo currently doesn't register such a profiler with webrender, but in the future we might also want to profile the webrender threadpool. Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com> --------- Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
parent
4242ff9626
commit
68a27946bf
11 changed files with 82 additions and 14 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -4131,6 +4131,7 @@ dependencies = [
|
|||
"net_traits",
|
||||
"profile",
|
||||
"profile_traits",
|
||||
"rayon",
|
||||
"script",
|
||||
"script_layout_interface",
|
||||
"script_traits",
|
||||
|
|
|
@ -198,6 +198,28 @@ mod gen {
|
|||
#[serde(rename = "fonts.default-monospace-size")]
|
||||
default_monospace_size: i64,
|
||||
},
|
||||
/// Allows customizing the different threadpools used by servo
|
||||
threadpools: {
|
||||
/// Number of workers per threadpool, if we fail to detect how much
|
||||
/// parallelism is available at runtime.
|
||||
fallback_worker_num: i64,
|
||||
image_cache_workers: {
|
||||
/// Maximum number of workers for the Image Cache thread pool
|
||||
max: i64,
|
||||
},
|
||||
async_runtime_workers: {
|
||||
/// Maximum number of workers for the Networking async runtime thread pool
|
||||
max: i64
|
||||
},
|
||||
resource_workers: {
|
||||
/// Maximum number of workers for the Core Resource Manager
|
||||
max: i64,
|
||||
},
|
||||
webrender_workers: {
|
||||
/// Maximum number of workers for webrender
|
||||
max: i64,
|
||||
},
|
||||
},
|
||||
css: {
|
||||
animations: {
|
||||
testing: {
|
||||
|
|
|
@ -1,10 +1,32 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::cmp::Ord;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::{LazyLock, Mutex};
|
||||
use std::thread;
|
||||
|
||||
use tokio::runtime::Runtime;
|
||||
use tokio::runtime::{Builder, Runtime};
|
||||
|
||||
pub static HANDLE: LazyLock<Mutex<Option<Runtime>>> =
|
||||
LazyLock::new(|| Mutex::new(Some(Runtime::new().unwrap())));
|
||||
pub static HANDLE: LazyLock<Mutex<Option<Runtime>>> = LazyLock::new(|| {
|
||||
Mutex::new(Some(
|
||||
Builder::new_multi_thread()
|
||||
.thread_name_fn(|| {
|
||||
static ATOMIC_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
let id = ATOMIC_ID.fetch_add(1, Ordering::Relaxed);
|
||||
format!("tokio-runtime-{}", id)
|
||||
})
|
||||
.worker_threads(
|
||||
thread::available_parallelism()
|
||||
.map(|i| i.get())
|
||||
.unwrap_or(servo_config::pref!(threadpools.fallback_worker_num) as usize)
|
||||
.min(
|
||||
servo_config::pref!(threadpools.async_runtime_workers.max).max(1) as usize,
|
||||
),
|
||||
)
|
||||
.enable_io()
|
||||
.enable_time()
|
||||
.build()
|
||||
.unwrap(),
|
||||
))
|
||||
});
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::collections::HashMap;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{mem, thread};
|
||||
|
||||
|
@ -425,8 +424,9 @@ impl ImageCache for ImageCacheImpl {
|
|||
// See https://doc.rust-lang.org/stable/std/thread/fn.available_parallelism.html
|
||||
// If no information can be obtained about the system, uses 4 threads as a default
|
||||
let thread_count = thread::available_parallelism()
|
||||
.unwrap_or(NonZeroUsize::new(4).unwrap())
|
||||
.get();
|
||||
.map(|i| i.get())
|
||||
.unwrap_or(servo_config::pref!(threadpools.fallback_worker_num) as usize)
|
||||
.min(servo_config::pref!(threadpools.async_runtime_workers.max).max(1) as usize);
|
||||
|
||||
ImageCacheImpl {
|
||||
store: Arc::new(Mutex::new(ImageCacheStore {
|
||||
|
@ -436,7 +436,7 @@ impl ImageCache for ImageCacheImpl {
|
|||
placeholder_url: ServoUrl::parse("chrome://resources/rippy.png").unwrap(),
|
||||
compositor_api,
|
||||
})),
|
||||
thread_pool: CoreResourceThreadPool::new(thread_count),
|
||||
thread_pool: CoreResourceThreadPool::new(thread_count, "ImageCache".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -559,9 +559,10 @@ pub struct CoreResourceThreadPool {
|
|||
}
|
||||
|
||||
impl CoreResourceThreadPool {
|
||||
pub fn new(num_threads: usize) -> CoreResourceThreadPool {
|
||||
pub fn new(num_threads: usize, pool_name: String) -> CoreResourceThreadPool {
|
||||
debug!("Creating new CoreResourceThreadPool with {num_threads} threads!");
|
||||
let pool = rayon::ThreadPoolBuilder::new()
|
||||
.thread_name(|i| format!("CoreResourceThread#{i}"))
|
||||
.thread_name(move |i| format!("{pool_name}#{i}"))
|
||||
.num_threads(num_threads)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
@ -645,7 +646,11 @@ impl CoreResourceManager {
|
|||
ca_certificates: CACertificates,
|
||||
ignore_certificate_errors: bool,
|
||||
) -> CoreResourceManager {
|
||||
let pool = CoreResourceThreadPool::new(16);
|
||||
let num_threads = thread::available_parallelism()
|
||||
.map(|i| i.get())
|
||||
.unwrap_or(servo_config::pref!(threadpools.fallback_worker_num) as usize)
|
||||
.min(servo_config::pref!(threadpools.resource_workers.max).max(1) as usize);
|
||||
let pool = CoreResourceThreadPool::new(num_threads, "CoreResourceThreadPool".to_string());
|
||||
let pool_handle = Arc::new(pool);
|
||||
CoreResourceManager {
|
||||
user_agent,
|
||||
|
|
|
@ -226,7 +226,7 @@ fn test_file() {
|
|||
.origin(url.origin())
|
||||
.build();
|
||||
|
||||
let pool = CoreResourceThreadPool::new(1);
|
||||
let pool = CoreResourceThreadPool::new(1, "CoreResourceTestPool".to_string());
|
||||
let pool_handle = Arc::new(pool);
|
||||
let mut context = new_fetch_context(None, None, Some(Arc::downgrade(&pool_handle)));
|
||||
let fetch_response = fetch_with_context(&mut request, &mut context);
|
||||
|
|
|
@ -21,7 +21,7 @@ use crate::create_embedder_proxy;
|
|||
|
||||
#[test]
|
||||
fn test_filemanager() {
|
||||
let pool = CoreResourceThreadPool::new(1);
|
||||
let pool = CoreResourceThreadPool::new(1, "CoreResourceTestPool".to_string());
|
||||
let pool_handle = Arc::new(pool);
|
||||
let filemanager = FileManager::new(create_embedder_proxy(), Arc::downgrade(&pool_handle));
|
||||
set_pref!(dom.testing.html_input_element.select_files.enabled, true);
|
||||
|
|
|
@ -73,6 +73,7 @@ media = { path = "../media" }
|
|||
mozangle = { workspace = true }
|
||||
net = { path = "../net" }
|
||||
net_traits = { workspace = true }
|
||||
rayon = { workspace = true }
|
||||
profile = { path = "../profile" }
|
||||
profile_traits = { workspace = true }
|
||||
script = { path = "../script" }
|
||||
|
|
|
@ -22,6 +22,7 @@ use std::cmp::max;
|
|||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::vec::Drain;
|
||||
|
||||
pub use base::id::TopLevelBrowsingContextId;
|
||||
|
@ -352,6 +353,17 @@ where
|
|||
} else {
|
||||
UploadMethod::PixelBuffer(ONE_TIME_USAGE_HINT)
|
||||
};
|
||||
let worker_threads = thread::available_parallelism()
|
||||
.map(|i| i.get())
|
||||
.unwrap_or(pref!(threadpools.fallback_worker_num) as usize)
|
||||
.min(pref!(threadpools.webrender_workers.max).max(1) as usize);
|
||||
let workers = Some(Arc::new(
|
||||
rayon::ThreadPoolBuilder::new()
|
||||
.num_threads(worker_threads)
|
||||
.thread_name(|idx| format!("WRWorker#{}", idx))
|
||||
.build()
|
||||
.unwrap(),
|
||||
));
|
||||
webrender::create_webrender_instance(
|
||||
webrender_gl.clone(),
|
||||
render_notifier,
|
||||
|
@ -374,6 +386,7 @@ where
|
|||
allow_texture_swizzling: pref!(gfx.texture_swizzling.enabled),
|
||||
clear_color,
|
||||
upload_method,
|
||||
workers,
|
||||
..Default::default()
|
||||
},
|
||||
None,
|
||||
|
|
|
@ -102,7 +102,6 @@ surfman = { workspace = true, features = ["sm-angle-default"] }
|
|||
serde_json = { workspace = true }
|
||||
webxr = { workspace = true, optional = true }
|
||||
|
||||
|
||||
[target.'cfg(not(any(target_os = "android", target_env = "ohos")))'.dependencies]
|
||||
# For optional feature servo_allocator/use-system-allocator
|
||||
servo_allocator = { path = "../../components/allocator" }
|
||||
|
|
|
@ -124,5 +124,10 @@
|
|||
"shell.native-orientation": "both",
|
||||
"shell.native-titlebar.enabled": true,
|
||||
"shell.searchpage": "https://duckduckgo.com/html/?q=%s",
|
||||
"threadpools.async_runtime_workers.max": 6,
|
||||
"threadpools.fallback_worker_num": 3,
|
||||
"threadpools.image_cache_workers.max": 4,
|
||||
"threadpools.resource_workers.max": 4,
|
||||
"threadpools.webrender_workers.max": 4,
|
||||
"webgl.testing.context_creation_error": false
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue