mirror of
https://github.com/servo/servo.git
synced 2025-08-14 09:55:35 +01:00
Auto merge of #15535 - froydnj:global-style-thread-pool, r=bholley
geckolib: use a global thread pool for styling By having a single thread pool, rather than one per document, we use less memory. This addresses https://bugzilla.mozilla.org/show_bug.cgi?id=1324250. This may be obvious to an experienced Rust programmer, but I went with raw pointers because trying to use `Option` global variables resulted in complaints about turning on feature flags in nightly Rust. Since this is for stylo, nightly features are not appropriate here. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15535) <!-- Reviewable:end -->
This commit is contained in:
commit
56a99577b3
9 changed files with 60 additions and 47 deletions
|
@ -23,6 +23,7 @@ libc = "0.2"
|
|||
log = {version = "0.3.5", features = ["release_max_level_info"]}
|
||||
num_cpus = "1.1.0"
|
||||
parking_lot = "0.3"
|
||||
rayon = "0.6"
|
||||
selectors = {path = "../../components/selectors"}
|
||||
servo_url = {path = "../../components/url"}
|
||||
style = {path = "../../components/style", features = ["gecko"]}
|
||||
|
|
|
@ -8,10 +8,13 @@ use cssparser::Parser;
|
|||
use cssparser::ToCss as ParserToCss;
|
||||
use env_logger::LogBuilder;
|
||||
use euclid::Size2D;
|
||||
use num_cpus;
|
||||
use parking_lot::RwLock;
|
||||
use rayon;
|
||||
use selectors::Element;
|
||||
use servo_url::ServoUrl;
|
||||
use std::borrow::Cow;
|
||||
use std::cmp;
|
||||
use std::env;
|
||||
use std::fmt::Write;
|
||||
use std::mem;
|
||||
|
@ -23,7 +26,7 @@ use style::context::{ThreadLocalStyleContext, ThreadLocalStyleContextCreationInf
|
|||
use style::data::{ElementData, ElementStyles, RestyleData};
|
||||
use style::dom::{ShowSubtreeData, TElement, TNode};
|
||||
use style::error_reporting::StdoutErrorReporter;
|
||||
use style::gecko::data::{NUM_THREADS, PerDocumentStyleData, PerDocumentStyleDataImpl};
|
||||
use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl};
|
||||
use style::gecko::restyle_damage::GeckoRestyleDamage;
|
||||
use style::gecko::selector_parser::{SelectorImpl, PseudoElement};
|
||||
use style::gecko::traversal::RecalcStyleOnly;
|
||||
|
@ -90,6 +93,45 @@ use stylesheet_loader::StylesheetLoader;
|
|||
* depend on but good enough for our purposes.
|
||||
*/
|
||||
|
||||
struct GlobalStyleData {
|
||||
// How many threads parallel styling can use.
|
||||
pub num_threads: usize,
|
||||
|
||||
// The parallel styling thread pool.
|
||||
pub style_thread_pool: Option<rayon::ThreadPool>,
|
||||
}
|
||||
|
||||
impl GlobalStyleData {
|
||||
pub fn new() -> Self {
|
||||
let stylo_threads = env::var("STYLO_THREADS")
|
||||
.map(|s| s.parse::<usize>().expect("invalid STYLO_THREADS value"));
|
||||
let num_threads = match stylo_threads {
|
||||
Ok(num) => num,
|
||||
_ => cmp::max(num_cpus::get() * 3 / 4, 1),
|
||||
};
|
||||
|
||||
let pool = if num_threads <= 1 {
|
||||
None
|
||||
} else {
|
||||
let configuration =
|
||||
rayon::Configuration::new().set_num_threads(num_threads);
|
||||
let pool = rayon::ThreadPool::new(configuration).ok();
|
||||
pool
|
||||
};
|
||||
|
||||
GlobalStyleData {
|
||||
num_threads: num_threads,
|
||||
style_thread_pool: pool,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref GLOBAL_STYLE_DATA: GlobalStyleData = {
|
||||
GlobalStyleData::new()
|
||||
};
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_Initialize() -> () {
|
||||
// Initialize logging.
|
||||
|
@ -148,7 +190,7 @@ fn traverse_subtree(element: GeckoElement, raw_data: RawServoStyleSetBorrowed,
|
|||
}
|
||||
}
|
||||
|
||||
let mut per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
||||
let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||
|
||||
let token = RecalcStyleOnly::pre_traverse(element, &per_doc_data.stylist, unstyled_children_only);
|
||||
if !token.should_traverse() {
|
||||
|
@ -159,7 +201,9 @@ fn traverse_subtree(element: GeckoElement, raw_data: RawServoStyleSetBorrowed,
|
|||
debug!("{:?}", ShowSubtreeData(element.as_node()));
|
||||
|
||||
let shared_style_context = create_shared_context(&per_doc_data);
|
||||
let traversal_driver = if per_doc_data.num_threads == 1 || per_doc_data.work_queue.is_none() {
|
||||
let ref global_style_data = *GLOBAL_STYLE_DATA;
|
||||
|
||||
let traversal_driver = if global_style_data.style_thread_pool.is_none() {
|
||||
TraversalDriver::Sequential
|
||||
} else {
|
||||
TraversalDriver::Parallel
|
||||
|
@ -169,7 +213,7 @@ fn traverse_subtree(element: GeckoElement, raw_data: RawServoStyleSetBorrowed,
|
|||
let known_depth = None;
|
||||
if traversal_driver.is_parallel() {
|
||||
parallel::traverse_dom(&traversal, element, known_depth, token,
|
||||
per_doc_data.work_queue.as_mut().unwrap());
|
||||
global_style_data.style_thread_pool.as_ref().unwrap());
|
||||
} else {
|
||||
sequential::traverse_dom(&traversal, element, token);
|
||||
}
|
||||
|
@ -334,7 +378,7 @@ pub extern "C" fn Servo_AnimationValues_Populate(anim: RawGeckoAnimationValueLis
|
|||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 {
|
||||
*NUM_THREADS as u32
|
||||
GLOBAL_STYLE_DATA.num_threads as u32
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
|
@ -9,9 +9,12 @@ extern crate atomic_refcell;
|
|||
extern crate cssparser;
|
||||
extern crate env_logger;
|
||||
extern crate euclid;
|
||||
#[macro_use] extern crate lazy_static;
|
||||
extern crate libc;
|
||||
#[macro_use] extern crate log;
|
||||
extern crate num_cpus;
|
||||
extern crate parking_lot;
|
||||
extern crate rayon;
|
||||
extern crate selectors;
|
||||
extern crate servo_url;
|
||||
extern crate style;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue