From b18a61a15ba5c267f7b25edebf3ff4aa7c3896f6 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Jul 2017 14:51:00 +0200 Subject: [PATCH] async-llvm(5): Do continuous error handling on main thread. --- src/librustc_trans/back/write.rs | 69 +++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 08eccd8fdf3..9e4c1b87aac 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -32,6 +32,7 @@ use rustc_demangle; use std::cmp; use std::ffi::CString; +use std::fmt; use std::fs; use std::io; use std::io::Write; @@ -777,7 +778,33 @@ pub fn run_passes(sess: &Session, Client::new(num_workers).expect("failed to create jobserver") }); - execute_work(sess, work_items, client, trans.exported_symbols.clone()); + let (shared_emitter, shared_emitter_main) = SharedEmitter::new(); + let (trans_worker_send, trans_worker_receive) = channel(); + + let coordinator_thread = start_executing_work(sess, + work_items, + shared_emitter, + trans_worker_send, + client, + trans.exported_symbols.clone()); + loop { + shared_emitter_main.check(sess); + + match trans_worker_receive.recv() { + Ok(Message::AllWorkDone) | + Err(_) => break, + + Ok(Message::CheckErrorMessages) => continue, + Ok(msg) => { + bug!("unexpected message {:?}", msg); + } + } + } + + coordinator_thread.join().unwrap(); + + // Just in case, check this on the way out. + sess.diagnostic().abort_if_errors(); // If in incr. comp. mode, preserve the `.o` files for potential re-use for mtrans in modules.iter() { @@ -975,12 +1002,18 @@ pub fn dump_incremental_data(trans: &CrateTranslation) { eprintln!("incremental: re-using {} out of {} modules", reuse, trans.modules.len()); } -struct WorkItem { +pub struct WorkItem { mtrans: ModuleTranslation, config: ModuleConfig, output_names: OutputFilenames } +impl fmt::Debug for WorkItem { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "WorkItem({})", self.mtrans.name) + } +} + fn build_work_item(sess: &Session, mtrans: ModuleTranslation, config: ModuleConfig, @@ -1041,21 +1074,29 @@ fn execute_work_item(cgcx: &CodegenContext, work_item: WorkItem) Ok(()) } +#[derive(Debug)] pub enum Message { Token(io::Result), Done { success: bool }, + WorkItem(WorkItem), + CheckErrorMessages, + AllWorkDone, } + pub struct Diagnostic { msg: String, code: Option, lvl: Level, } -fn execute_work(sess: &Session, - mut work_items: Vec, - jobserver: Client, - exported_symbols: Arc) { +fn start_executing_work(sess: &Session, + mut work_items: Vec, + shared_emitter: SharedEmitter, + trans_worker_send: Sender, + jobserver: Client, + exported_symbols: Arc) + -> thread::JoinHandle<()> { let (tx, rx) = channel(); let tx2 = tx.clone(); @@ -1076,8 +1117,6 @@ fn execute_work(sess: &Session, helper.request_token(); } - let (shared_emitter, shared_emitter_main) = SharedEmitter::new(); - let mut each_linked_rlib_for_lto = Vec::new(); drop(link::each_linked_rlib(sess, &mut |cnum, path| { if link::ignored_for_lto(sess, cnum) { @@ -1200,18 +1239,20 @@ fn execute_work(sess: &Session, Message::Done { success: true } => { drop(tokens.pop()); running -= 1; + trans_worker_send.send(Message::CheckErrorMessages).unwrap(); } Message::Done { success: false } => { shared_emitter.fatal("aborting due to worker thread panic".to_string()); + trans_worker_send.send(Message::CheckErrorMessages).unwrap(); + } + msg @ Message::WorkItem(_) | + msg @ Message::AllWorkDone | + msg @ Message::CheckErrorMessages => { + bug!("unexpected message: {:?}", msg); } } } - }).join().unwrap(); - - shared_emitter_main.check(sess); - - // Just in case, check this on the way out. - sess.diagnostic().abort_if_errors(); + }) } fn spawn_work(cgcx: CodegenContext, work: WorkItem) {