diff options
Diffstat (limited to 'components/layout/parallel.rs')
-rw-r--r-- | components/layout/parallel.rs | 115 |
1 files changed, 73 insertions, 42 deletions
diff --git a/components/layout/parallel.rs b/components/layout/parallel.rs index b555a9f51dc..d8f46a0f83c 100644 --- a/components/layout/parallel.rs +++ b/components/layout/parallel.rs @@ -70,56 +70,57 @@ impl FlowParallelInfo { /// /// The only communication between siblings is that they both /// fetch-and-subtract the parent's children count. -fn bottom_up_flow(mut unsafe_flow: UnsafeFlow, - assign_bsize_traversal: &AssignBSizes) { +fn bottom_up_flow(mut unsafe_flow: UnsafeFlow, assign_bsize_traversal: &AssignBSizes) { loop { // Get a real flow. - let flow: &mut Flow = unsafe { - mem::transmute(unsafe_flow) - }; + let flow: &mut Flow = unsafe { mem::transmute(unsafe_flow) }; // Perform the appropriate traversal. if assign_bsize_traversal.should_process(flow) { assign_bsize_traversal.process(flow); } - let base = flow.mut_base(); // Reset the count of children for the next layout traversal. - base.parallel.children_count.store(base.children.len() as isize, - Ordering::Relaxed); + base.parallel + .children_count + .store(base.children.len() as isize, Ordering::Relaxed); // Possibly enqueue the parent. let unsafe_parent = base.parallel.parent; if unsafe_parent == null_unsafe_flow() { // We're done! - break + break; } // No, we're not at the root yet. Then are we the last child // of our parent to finish processing? If so, we can continue // on with our parent; otherwise, we've gotta wait. - let parent: &mut Flow = unsafe { - &mut *(unsafe_parent.0 as *mut Flow) - }; + let parent: &mut Flow = unsafe { &mut *(unsafe_parent.0 as *mut Flow) }; let parent_base = parent.mut_base(); - if parent_base.parallel.children_count.fetch_sub(1, Ordering::Relaxed) == 1 { + if parent_base + .parallel + .children_count + .fetch_sub(1, Ordering::Relaxed) == + 1 + { // We were the last child of our parent. Reflow our parent. unsafe_flow = unsafe_parent } else { // Stop. - break + break; } } } -fn top_down_flow<'scope>(unsafe_flows: &[UnsafeFlow], - pool: &'scope rayon::ThreadPool, - scope: &rayon::Scope<'scope>, - assign_isize_traversal: &'scope AssignISizes, - assign_bsize_traversal: &'scope AssignBSizes) -{ +fn top_down_flow<'scope>( + unsafe_flows: &[UnsafeFlow], + pool: &'scope rayon::ThreadPool, + scope: &rayon::Scope<'scope>, + assign_isize_traversal: &'scope AssignISizes, + assign_bsize_traversal: &'scope AssignBSizes, +) { let mut discovered_child_flows = FlowList::new(); for unsafe_flow in unsafe_flows { @@ -127,8 +128,7 @@ fn top_down_flow<'scope>(unsafe_flows: &[UnsafeFlow], unsafe { // Get a real flow. let flow: &mut Flow = mem::transmute(*unsafe_flow); - flow.mut_base().thread_id = - pool.current_thread_index().unwrap() as u8; + flow.mut_base().thread_id = pool.current_thread_index().unwrap() as u8; if assign_isize_traversal.should_process(flow) { // Perform the appropriate traversal. @@ -149,16 +149,18 @@ fn top_down_flow<'scope>(unsafe_flows: &[UnsafeFlow], } if discovered_child_flows.is_empty() { - return + return; } if discovered_child_flows.len() <= CHUNK_SIZE { // We can handle all the children in this work unit. - top_down_flow(&discovered_child_flows, - pool, - scope, - &assign_isize_traversal, - &assign_bsize_traversal); + top_down_flow( + &discovered_child_flows, + pool, + scope, + &assign_isize_traversal, + &assign_bsize_traversal, + ); } else { // Spawn a new work unit for each chunk after the first. let mut chunks = discovered_child_flows.chunks(CHUNK_SIZE); @@ -166,37 +168,66 @@ fn top_down_flow<'scope>(unsafe_flows: &[UnsafeFlow], for chunk in chunks { let nodes = chunk.iter().cloned().collect::<FlowList>(); scope.spawn(move |scope| { - top_down_flow(&nodes, pool, scope, &assign_isize_traversal, &assign_bsize_traversal); + top_down_flow( + &nodes, + pool, + scope, + &assign_isize_traversal, + &assign_bsize_traversal, + ); }); } if let Some(chunk) = first_chunk { - top_down_flow(chunk, pool, scope, &assign_isize_traversal, &assign_bsize_traversal); + top_down_flow( + chunk, + pool, + scope, + &assign_isize_traversal, + &assign_bsize_traversal, + ); } } } /// Run the main layout passes in parallel. pub fn reflow( - root: &mut Flow, - profiler_metadata: Option<TimerMetadata>, - time_profiler_chan: time::ProfilerChan, - context: &LayoutContext, - queue: &rayon::ThreadPool) { + root: &mut Flow, + profiler_metadata: Option<TimerMetadata>, + time_profiler_chan: time::ProfilerChan, + context: &LayoutContext, + queue: &rayon::ThreadPool, +) { if opts::get().bubble_inline_sizes_separately { - let bubble_inline_sizes = BubbleISizes { layout_context: &context }; + let bubble_inline_sizes = BubbleISizes { + layout_context: &context, + }; bubble_inline_sizes.traverse(root); } - let assign_isize_traversal = &AssignISizes { layout_context: &context }; - let assign_bsize_traversal = &AssignBSizes { layout_context: &context }; + let assign_isize_traversal = &AssignISizes { + layout_context: &context, + }; + let assign_bsize_traversal = &AssignBSizes { + layout_context: &context, + }; let nodes = [UnsafeFlow(root)]; queue.install(move || { rayon::scope(move |scope| { - profile(time::ProfilerCategory::LayoutParallelWarmup, - profiler_metadata, time_profiler_chan, move || { - top_down_flow(&nodes, queue, scope, assign_isize_traversal, assign_bsize_traversal); - }); + profile( + time::ProfilerCategory::LayoutParallelWarmup, + profiler_metadata, + time_profiler_chan, + move || { + top_down_flow( + &nodes, + queue, + scope, + assign_isize_traversal, + assign_bsize_traversal, + ); + }, + ); }); }); } |