Skip to content

Commit 06753f0

Browse files
committed
Join GC threads
1 parent 5d6b0fa commit 06753f0

File tree

3 files changed

+51
-28
lines changed

3 files changed

+51
-28
lines changed

Diff for: mmtk/src/api.rs

+1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ pub extern "C" fn mmtk_initialize_collection(tls: VMThread) {
157157
#[no_mangle]
158158
pub extern "C" fn mmtk_prepare_to_fork() {
159159
mmtk().prepare_to_fork();
160+
binding().join_all_gc_threads();
160161
}
161162

162163
#[no_mangle]

Diff for: mmtk/src/binding.rs

+19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::collections::HashMap;
22
use std::ffi::CString;
33
use std::sync::Mutex;
4+
use std::thread::JoinHandle;
45

56
use libc::c_void;
67
use mmtk::util::ObjectReference;
@@ -36,6 +37,7 @@ pub struct RubyBinding {
3637
pub weak_proc: WeakProcessor,
3738
pub ppp_registry: PPPRegistry,
3839
pub(crate) moved_givtbl: Mutex<HashMap<ObjectReference, MovedGIVTblEntry>>,
40+
pub gc_thread_join_handles: Mutex<Vec<JoinHandle<()>>>
3941
}
4042

4143
unsafe impl Sync for RubyBinding {}
@@ -58,6 +60,7 @@ impl RubyBinding {
5860
weak_proc: WeakProcessor::new(),
5961
ppp_registry: PPPRegistry::new(),
6062
moved_givtbl: Default::default(),
63+
gc_thread_join_handles: Default::default(),
6164
}
6265
}
6366

@@ -75,4 +78,20 @@ impl RubyBinding {
7578
}
7679
plan_name.as_deref().unwrap().as_ptr()
7780
}
81+
82+
pub fn join_all_gc_threads(&self) {
83+
let handles = {
84+
let mut guard = self.gc_thread_join_handles.lock().unwrap();
85+
std::mem::take(&mut *guard)
86+
};
87+
88+
debug!("Joining GC threads...");
89+
let total = handles.len();
90+
let mut joined = 0;
91+
for handle in handles {
92+
handle.join().unwrap();
93+
joined += 1;
94+
debug!("{joined}/{total} GC threads joined.");
95+
}
96+
}
7897
}

Diff for: mmtk/src/collection.rs

+31-28
Original file line numberDiff line numberDiff line change
@@ -32,34 +32,37 @@ impl Collection<Ruby> for VMCollection {
3232
}
3333

3434
fn spawn_gc_thread(_tls: VMThread, ctx: GCThreadContext<Ruby>) {
35-
match ctx {
36-
GCThreadContext::Worker(mut worker) => {
37-
thread::Builder::new()
38-
.name("MMTk Worker Thread".to_string())
39-
.spawn(move || {
40-
let ordinal = worker.ordinal;
41-
debug!(
42-
"Hello! This is MMTk Worker Thread running! ordinal: {}",
43-
ordinal
44-
);
45-
crate::register_gc_thread(thread::current().id());
46-
let ptr_worker = &mut *worker as *mut GCWorker<Ruby>;
47-
let gc_thread_tls =
48-
Box::into_raw(Box::new(GCThreadTLS::for_worker(ptr_worker)));
49-
(upcalls().init_gc_worker_thread)(gc_thread_tls);
50-
memory_manager::start_worker(
51-
mmtk(),
52-
GCThreadTLS::to_vwt(gc_thread_tls),
53-
worker,
54-
);
55-
debug!(
56-
"An MMTk Worker Thread is quitting. Good bye! ordinal: {}",
57-
ordinal
58-
);
59-
crate::unregister_gc_thread(thread::current().id());
60-
})
61-
.unwrap();
62-
}
35+
let join_handle = match ctx {
36+
GCThreadContext::Worker(mut worker) => thread::Builder::new()
37+
.name("MMTk Worker Thread".to_string())
38+
.spawn(move || {
39+
let ordinal = worker.ordinal;
40+
debug!(
41+
"Hello! This is MMTk Worker Thread running! ordinal: {}",
42+
ordinal
43+
);
44+
crate::register_gc_thread(thread::current().id());
45+
let ptr_worker = &mut *worker as *mut GCWorker<Ruby>;
46+
let gc_thread_tls =
47+
Box::into_raw(Box::new(GCThreadTLS::for_worker(ptr_worker)));
48+
(upcalls().init_gc_worker_thread)(gc_thread_tls);
49+
memory_manager::start_worker(
50+
mmtk(),
51+
GCThreadTLS::to_vwt(gc_thread_tls),
52+
worker,
53+
);
54+
debug!(
55+
"An MMTk Worker Thread is quitting. Good bye! ordinal: {}",
56+
ordinal
57+
);
58+
crate::unregister_gc_thread(thread::current().id());
59+
})
60+
.unwrap(),
61+
};
62+
63+
{
64+
let mut handles = crate::binding().gc_thread_join_handles.lock().unwrap();
65+
handles.push(join_handle);
6366
}
6467
}
6568

0 commit comments

Comments
 (0)