diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index c9a80b7ddd8..64ef126b79e 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -461,7 +461,8 @@ impl LayoutThread { ScaleFactor::new(opts::get().device_pixels_per_px.unwrap_or(1.0))); let configuration = - rayon::Configuration::new().num_threads(layout_threads); + rayon::Configuration::new().num_threads(layout_threads) + .start_handler(|_| thread_state::initialize_layout_worker_thread()); let parallel_traversal = if layout_threads > 1 { Some(rayon::ThreadPool::new(configuration).expect("ThreadPool creation failed")) } else { diff --git a/components/style/gecko/global_style_data.rs b/components/style/gecko/global_style_data.rs index a4812b95a4f..4a6dcc21805 100644 --- a/components/style/gecko/global_style_data.rs +++ b/components/style/gecko/global_style_data.rs @@ -15,6 +15,7 @@ use shared_lock::SharedRwLock; use std::cmp; use std::env; use std::ffi::CString; +use thread_state; /// Global style data pub struct GlobalStyleData { @@ -39,6 +40,7 @@ fn thread_name(index: usize) -> String { } fn thread_startup(index: usize) { + thread_state::initialize_layout_worker_thread(); unsafe { Gecko_SetJemallocThreadLocalArena(true); } diff --git a/components/style/thread_state.rs b/components/style/thread_state.rs index ab0672e2503..894cdb4a813 100644 --- a/components/style/thread_state.rs +++ b/components/style/thread_state.rs @@ -2,15 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -//! Supports dynamic assertions in debug builds about what sort of thread is -//! running and what state it's in. -//! -//! In release builds, `get` returns 0. All of the other functions inline -//! away to nothing. +//! Supports dynamic assertions in about what sort of thread is running and +//! what state it's in. #![deny(missing_docs)] -pub use self::imp::{enter, exit, get, initialize}; +use std::cell::RefCell; bitflags! { /// A thread state flag, used for multiple assertions. @@ -37,22 +34,12 @@ macro_rules! thread_types ( ( $( $fun:ident = $flag:ident ; )* ) => ( } $( - #[cfg(debug_assertions)] #[allow(missing_docs)] pub fn $fun(self) -> bool { self.contains($flag) } - #[cfg(not(debug_assertions))] - #[allow(missing_docs)] - pub fn $fun(self) -> bool { - true - } )* } - - #[cfg(debug_assertions)] - static TYPES: &'static [ThreadState] = - &[ $( $flag ),* ]; )); thread_types! { @@ -60,64 +47,49 @@ thread_types! { is_layout = LAYOUT; } -#[cfg(debug_assertions)] -mod imp { - use std::cell::RefCell; - use super::{TYPES, ThreadState}; +thread_local!(static STATE: RefCell> = RefCell::new(None)); - thread_local!(static STATE: RefCell> = RefCell::new(None)); - - /// Initialize the current thread state. - pub fn initialize(x: ThreadState) { - STATE.with(|ref k| { - if let Some(ref s) = *k.borrow() { - panic!("Thread state already initialized as {:?}", s); - } - *k.borrow_mut() = Some(x); - }); - get(); // check the assertion below - } - - /// Get the current thread state. - pub fn get() -> ThreadState { - let state = STATE.with(|ref k| { - match *k.borrow() { - // This is one of the layout threads, that use rayon. - None => super::LAYOUT | super::IN_WORKER, - Some(s) => s, - } - }); - - // Exactly one of the thread type flags should be set. - assert_eq!(1, TYPES.iter().filter(|&&ty| state.contains(ty)).count()); - state - } - - /// Enter into a given temporary state. Panics if re-entring. - pub fn enter(x: ThreadState) { - let state = get(); - assert!(!state.intersects(x)); - STATE.with(|ref k| { - *k.borrow_mut() = Some(state | x); - }) - } - - /// Exit a given temporary state. - pub fn exit(x: ThreadState) { - let state = get(); - assert!(state.contains(x)); - STATE.with(|ref k| { - *k.borrow_mut() = Some(state & !x); - }) - } +/// Initializes the current thread state. +pub fn initialize(x: ThreadState) { + STATE.with(|ref k| { + if let Some(ref s) = *k.borrow() { + panic!("Thread state already initialized as {:?}", s); + } + *k.borrow_mut() = Some(x); + }); } -#[cfg(not(debug_assertions))] -#[allow(missing_docs)] -mod imp { - use super::ThreadState; - #[inline(always)] pub fn initialize(_: ThreadState) { } - #[inline(always)] pub fn get() -> ThreadState { ThreadState::empty() } - #[inline(always)] pub fn enter(_: ThreadState) { } - #[inline(always)] pub fn exit(_: ThreadState) { } +/// Initializes the current thread as a layout worker thread. +pub fn initialize_layout_worker_thread() { + initialize(LAYOUT | IN_WORKER); +} + +/// Gets the current thread state. +pub fn get() -> ThreadState { + let state = STATE.with(|ref k| { + match *k.borrow() { + None => ThreadState::empty(), // Unknown thread. + Some(s) => s, + } + }); + + state +} + +/// Enters into a given temporary state. Panics if re-entring. +pub fn enter(x: ThreadState) { + let state = get(); + debug_assert!(!state.intersects(x)); + STATE.with(|ref k| { + *k.borrow_mut() = Some(state | x); + }) +} + +/// Exits a given temporary state. +pub fn exit(x: ThreadState) { + let state = get(); + debug_assert!(state.contains(x)); + STATE.with(|ref k| { + *k.borrow_mut() = Some(state & !x); + }) }