From d2923e5a77b318300c9d35d63d594125b8b9a43f Mon Sep 17 00:00:00 2001 From: John Kåre Alsaker Date: Sat, 23 Feb 2019 16:47:13 +0100 Subject: Run the first block in a parallel! macro directly in the scope which guarantees that it will run immediately --- src/librustc_data_structures/sync.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/librustc_data_structures') diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index ba1f6eb56fe..14e625af299 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -280,21 +280,22 @@ cfg_if! { #[macro_export] macro_rules! parallel { - (impl [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => { - parallel!(impl [$block, $($c,)*] [$($rest),*]) + (impl $fblock:tt [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => { + parallel!(impl $fblock [$block, $($c,)*] [$($rest),*]) }; - (impl [$($blocks:tt,)*] []) => { + (impl $fblock:tt [$($blocks:tt,)*] []) => { ::rustc_data_structures::sync::scope(|s| { $( s.spawn(|_| $blocks); )* + $fblock; }) }; - ($($blocks:tt),*) => { + ($fblock:tt, $($blocks:tt),*) => { // Reverse the order of the blocks since Rayon executes them in reverse order // when using a single thread. This ensures the execution order matches that // of a single threaded rustc - parallel!(impl [] [$($blocks),*]); + parallel!(impl $fblock [] [$($blocks),*]); }; } -- cgit 1.4.1-3-g733a5 From 7cc7b8f190565af501b0b4eda7be18f029a5d676 Mon Sep 17 00:00:00 2001 From: John Kåre Alsaker Date: Sun, 24 Feb 2019 22:37:55 +0100 Subject: Execute all parallel blocks even if they panic in a single-threaded compiler --- src/librustc/hir/mod.rs | 8 +++---- src/librustc_data_structures/sync.rs | 42 +++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 5 deletions(-) (limited to 'src/librustc_data_structures') diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 2d0296aa38c..80d9c1e2998 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -30,7 +30,7 @@ use syntax::util::parser::ExprPrecedence; use crate::ty::AdtKind; use crate::ty::query::Providers; -use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync}; +use rustc_data_structures::sync::{par_for_each_in, Send, Sync}; use rustc_data_structures::thin_vec::ThinVec; use serialize::{self, Encoder, Encodable, Decoder, Decodable}; @@ -782,15 +782,15 @@ impl Crate { where V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send { parallel!({ - par_iter(&self.items).for_each(|(_, item)| { + par_for_each_in(&self.items, |(_, item)| { visitor.visit_item(item); }); }, { - par_iter(&self.trait_items).for_each(|(_, trait_item)| { + par_for_each_in(&self.trait_items, |(_, trait_item)| { visitor.visit_trait_item(trait_item); }); }, { - par_iter(&self.impl_items).for_each(|(_, impl_item)| { + par_for_each_in(&self.impl_items, |(_, impl_item)| { visitor.visit_impl_item(impl_item); }); }); diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 14e625af299..f006a95f3fa 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -65,6 +65,7 @@ cfg_if! { } use std::ops::Add; + use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe}; #[derive(Debug)] pub struct Atomic(Cell); @@ -130,7 +131,19 @@ cfg_if! { #[macro_export] macro_rules! parallel { ($($blocks:tt),*) => { - $($blocks)*; + let mut panic = None; + $( + if let Err(p) = ::std::panic::catch_unwind( + ::std::panic::AssertUnwindSafe(|| $blocks) + ) { + if panic.is_none() { + panic = Some(p); + } + } + )* + if let Some(panic) = panic { + ::std::panic::resume_unwind(panic); + } } } @@ -140,6 +153,24 @@ cfg_if! { t.into_iter() } + pub fn par_for_each_in( + t: T, + for_each: + impl Fn(<::IntoIter as Iterator>::Item) + Sync + Send + ) { + let mut panic = None; + t.into_iter().for_each(|i| { + if let Err(p) = catch_unwind(AssertUnwindSafe(|| for_each(i))) { + if panic.is_none() { + panic = Some(p); + } + } + }); + if let Some(panic) = panic { + resume_unwind(panic); + } + } + pub type MetadataRef = OwningRef, [u8]>; pub use std::rc::Rc as Lrc; @@ -308,6 +339,15 @@ cfg_if! { t.into_par_iter() } + pub fn par_for_each_in( + t: T, + for_each: impl Fn( + <::Iter as ParallelIterator>::Item + ) + Sync + Send + ) { + t.into_par_iter().for_each(for_each) + } + pub type MetadataRef = OwningRef, [u8]>; /// This makes locks panic if they are already held. -- cgit 1.4.1-3-g733a5 From db9a1c1aaf261c8505d09ac6bd3364ef0d19ee71 Mon Sep 17 00:00:00 2001 From: John Kåre Alsaker Date: Wed, 6 Mar 2019 04:46:46 +0100 Subject: Add some comments --- src/librustc_data_structures/sync.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/librustc_data_structures') diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index f006a95f3fa..73247c1469e 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -131,6 +131,8 @@ cfg_if! { #[macro_export] macro_rules! parallel { ($($blocks:tt),*) => { + // We catch panics here ensuring that all the blocks execute. + // This makes behavior consistent with the parallel compiler. let mut panic = None; $( if let Err(p) = ::std::panic::catch_unwind( @@ -158,6 +160,8 @@ cfg_if! { for_each: impl Fn(<::IntoIter as Iterator>::Item) + Sync + Send ) { + // We catch panics here ensuring that all the loop iterations execute. + // This makes behavior consistent with the parallel compiler. let mut panic = None; t.into_iter().for_each(|i| { if let Err(p) = catch_unwind(AssertUnwindSafe(|| for_each(i))) { @@ -309,6 +313,8 @@ cfg_if! { use std::thread; pub use rayon::{join, scope}; + /// Runs a list of blocks in parallel. The first block is executed immediately on + /// the current thread. Use that for the longest running block. #[macro_export] macro_rules! parallel { (impl $fblock:tt [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => { @@ -323,7 +329,7 @@ cfg_if! { }) }; ($fblock:tt, $($blocks:tt),*) => { - // Reverse the order of the blocks since Rayon executes them in reverse order + // Reverse the order of the later blocks since Rayon executes them in reverse order // when using a single thread. This ensures the execution order matches that // of a single threaded rustc parallel!(impl $fblock [] [$($blocks),*]); -- cgit 1.4.1-3-g733a5