Skip to content

Commit 01aec71

Browse files
committed
address review comments
1 parent 423ad8f commit 01aec71

File tree

2 files changed

+24
-17
lines changed

2 files changed

+24
-17
lines changed

src/concurrency/thread.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10511051
// See if this thread can do something else.
10521052
match this.run_on_stack_empty()? {
10531053
Poll::Pending => {} // keep going
1054-
Poll::Ready(()) => this.terminate_active_thread(false)?,
1054+
Poll::Ready(()) =>
1055+
this.terminate_active_thread(TerminatedThreadTls::Deallocate)?,
10551056
}
10561057
}
10571058
}
@@ -1066,12 +1067,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10661067
}
10671068

10681069
/// Handles thread termination of the active thread: wakes up threads joining on this one,
1069-
/// and deallocates thread-local statics (unless `leak_tls` is set, in which case the thread's
1070-
/// TLS are marked as static roots for leakage analysis).
1070+
/// and deals with the thread's thread-local statics according to `tls`.
10711071
///
10721072
/// This is called by the eval loop when a thread's on_stack_empty returns `Ready`.
10731073
#[inline]
1074-
fn terminate_active_thread(&mut self, leak_tls: bool) -> InterpResult<'tcx> {
1074+
fn terminate_active_thread(&mut self, tls: TerminatedThreadTls) -> InterpResult<'tcx> {
10751075
let this = self.eval_context_mut();
10761076
let thread = this.active_thread_mut();
10771077
assert!(thread.stack.is_empty(), "only threads with an empty stack can be terminated");
@@ -1080,20 +1080,26 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10801080
let current_span = this.machine.current_span();
10811081
let thread_local_allocations =
10821082
this.machine.threads.thread_terminated(this.machine.data_race.as_mut(), current_span);
1083-
if leak_tls {
1084-
// Add thread-local statics to static roots and skip deallocating backing memory
1085-
for ptr in thread_local_allocations {
1086-
if let Some(alloc) = ptr.provenance.get_alloc_id() {
1087-
trace!("Thread-local static leaked and stored as static root: {:?}", alloc);
1088-
this.machine.static_roots.push(alloc);
1089-
}
1090-
}
1091-
} else {
1092-
// Deallocate backing memory of thread-local statics
1093-
for ptr in thread_local_allocations {
1094-
this.deallocate_ptr(ptr.into(), None, MiriMemoryKind::Tls.into())?;
1083+
for ptr in thread_local_allocations {
1084+
match tls {
1085+
TerminatedThreadTls::Deallocate =>
1086+
this.deallocate_ptr(ptr.into(), None, MiriMemoryKind::Tls.into())?,
1087+
TerminatedThreadTls::Leak =>
1088+
if let Some(alloc) = ptr.provenance.get_alloc_id() {
1089+
trace!("Thread-local static leaked and stored as static root: {:?}", alloc);
1090+
this.machine.static_roots.push(alloc);
1091+
},
10951092
}
10961093
}
10971094
Ok(())
10981095
}
10991096
}
1097+
1098+
/// What to do with TLS allocations from terminated threads
1099+
pub enum TerminatedThreadTls {
1100+
/// Deallocate backing memory of thread-local statics as usual
1101+
Deallocate,
1102+
/// Skip deallocating backing memory of thread-local statics and consider all memory reachable
1103+
/// from them as not leaked (like global `static`s).
1104+
Leak,
1105+
}

src/eval.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use log::info;
1111
use rustc_middle::ty::Ty;
1212

1313
use crate::borrow_tracker::RetagFields;
14+
use crate::concurrency::thread::TerminatedThreadTls;
1415
use crate::diagnostics::report_leaks;
1516
use rustc_data_structures::fx::FxHashSet;
1617
use rustc_hir::def::Namespace;
@@ -246,7 +247,7 @@ impl MainThreadState {
246247
let exit_code = this.read_target_isize(&ret_place)?;
247248
// Deal with our thread-local memory. We do *not* want to actually free it, instead we consider TLS
248249
// to be like a global `static`, so that all memory reached by it is considered to "not leak".
249-
this.terminate_active_thread(true)?;
250+
this.terminate_active_thread(TerminatedThreadTls::Leak)?;
250251
// Stop interpreter loop.
251252
throw_machine_stop!(TerminationInfo::Exit { code: exit_code, leak_check: true });
252253
}

0 commit comments

Comments
 (0)