@@ -10,6 +10,8 @@ use rustc_data_structures::stable_hasher::StableHasher;
1010use rustc_data_structures:: sync:: Lrc ;
1111use rustc_errors:: registry:: Registry ;
1212use rustc_metadata:: dynamic_lib:: DynamicLibrary ;
13+ #[ cfg( parallel_compiler) ]
14+ use rustc_middle:: ty:: tls;
1315use rustc_resolve:: { self , Resolver } ;
1416use rustc_session as session;
1517use rustc_session:: config:: { self , CrateType } ;
@@ -29,11 +31,12 @@ use std::io;
2931use std:: lazy:: SyncOnceCell ;
3032use std:: mem;
3133use std:: ops:: DerefMut ;
34+ #[ cfg( not( parallel_compiler) ) ]
35+ use std:: panic;
3236use std:: path:: { Path , PathBuf } ;
3337use std:: sync:: atomic:: { AtomicBool , Ordering } ;
3438use std:: sync:: { Arc , Mutex , Once } ;
35- #[ cfg( not( parallel_compiler) ) ]
36- use std:: { panic, thread} ;
39+ use std:: thread;
3740use tracing:: info;
3841
3942/// Adds `target_feature = "..."` cfgs for a variety of platform
@@ -156,22 +159,43 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
156159 scoped_thread ( cfg, main_handler)
157160}
158161
162+ /// Creates a new thread and forwards information in thread locals to it.
163+ /// The new thread runs the deadlock handler.
164+ /// Must only be called when a deadlock is about to happen.
165+ #[ cfg( parallel_compiler) ]
166+ unsafe fn handle_deadlock ( ) {
167+ let registry = rustc_rayon_core:: Registry :: current ( ) ;
168+
169+ let context = tls:: get_tlv ( ) ;
170+ assert ! ( context != 0 ) ;
171+ rustc_data_structures:: sync:: assert_sync :: < tls:: ImplicitCtxt < ' _ , ' _ > > ( ) ;
172+ let icx: & tls:: ImplicitCtxt < ' _ , ' _ > = & * ( context as * const tls:: ImplicitCtxt < ' _ , ' _ > ) ;
173+
174+ let session_globals = rustc_span:: SESSION_GLOBALS . with ( |sg| sg as * const _ ) ;
175+ let session_globals = & * session_globals;
176+ thread:: spawn ( move || {
177+ tls:: enter_context ( icx, |_| {
178+ rustc_span:: SESSION_GLOBALS
179+ . set ( session_globals, || tls:: with ( |tcx| tcx. queries . deadlock ( tcx, & registry) ) )
180+ } ) ;
181+ } ) ;
182+ }
183+
159184#[ cfg( parallel_compiler) ]
160185pub fn setup_callbacks_and_run_in_thread_pool_with_globals < F : FnOnce ( ) -> R + Send , R : Send > (
161186 edition : Edition ,
162187 threads : usize ,
163188 stderr : & Option < Arc < Mutex < Vec < u8 > > > > ,
164189 f : F ,
165190) -> R {
166- use rustc_middle:: ty;
167191 crate :: callbacks:: setup_callbacks ( ) ;
168192
169193 let mut config = rayon:: ThreadPoolBuilder :: new ( )
170194 . thread_name ( |_| "rustc" . to_string ( ) )
171195 . acquire_thread_handler ( jobserver:: acquire_thread)
172196 . release_thread_handler ( jobserver:: release_thread)
173197 . num_threads ( threads)
174- . deadlock_handler ( || unsafe { ty :: query :: handle_deadlock ( ) } ) ;
198+ . deadlock_handler ( || unsafe { handle_deadlock ( ) } ) ;
175199
176200 if let Some ( size) = get_stack_size ( ) {
177201 config = config. stack_size ( size) ;
0 commit comments