Skip to content

Commit 47d2f9e

Browse files
committed
Return join handles when spawning GC threads
1 parent 5d6b0fa commit 47d2f9e

File tree

3 files changed

+55
-30
lines changed

3 files changed

+55
-30
lines changed

mmtk/src/collection.rs

+31-30
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::abi::GCThreadTLS;
22

33
use crate::api::RubyMutator;
4+
use crate::gc_thread::RubyGCThreadJoinHandle;
45
use crate::{mmtk, upcalls, Ruby};
56
use mmtk::memory_manager;
67
use mmtk::scheduler::*;
@@ -31,36 +32,36 @@ impl Collection<Ruby> for VMCollection {
3132
(upcalls().block_for_gc)(tls);
3233
}
3334

34-
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-
}
63-
}
35+
fn spawn_gc_thread(_tls: VMThread, ctx: GCThreadContext<Ruby>) -> RubyGCThreadJoinHandle {
36+
let rust_join_handle = match ctx {
37+
GCThreadContext::Worker(mut worker) => 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+
};
63+
64+
RubyGCThreadJoinHandle::new(rust_join_handle)
6465
}
6566

6667
fn vm_live_bytes() -> usize {

mmtk/src/gc_thread.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use mmtk::vm::gc_thread::GCThreadJoinHandle;
2+
use std::thread::JoinHandle;
3+
4+
/// We implement `GCThreadJoinHandle` using Rust's own `JoinHandle` because we create GC worker
5+
/// threads directly using the thread support in Rust's standard library.
6+
pub struct RubyGCThreadJoinHandle {
7+
rust_join_handle: JoinHandle<()>,
8+
}
9+
10+
impl RubyGCThreadJoinHandle {
11+
pub fn new(rust_join_handle: JoinHandle<()>) -> Self {
12+
Self { rust_join_handle }
13+
}
14+
}
15+
16+
impl GCThreadJoinHandle for RubyGCThreadJoinHandle {
17+
fn join_native_thread(self) {
18+
self.rust_join_handle.join().unwrap();
19+
}
20+
}

mmtk/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::thread::ThreadId;
1212

1313
use abi::RubyUpcalls;
1414
use binding::{RubyBinding, RubyBindingFast};
15+
use gc_thread::RubyGCThreadJoinHandle;
1516
use mmtk::vm::edge_shape::{SimpleEdge, UnimplementedMemorySlice};
1617
use mmtk::vm::VMBinding;
1718
use mmtk::MMTK;
@@ -22,6 +23,7 @@ pub mod active_plan;
2223
pub mod api;
2324
pub mod binding;
2425
pub mod collection;
26+
pub mod gc_thread;
2527
pub mod object_model;
2628
pub mod ppp;
2729
pub mod reference_glue;
@@ -50,6 +52,8 @@ impl VMBinding for Ruby {
5052

5153
type VMEdge = RubyEdge;
5254
type VMMemorySlice = RubyMemorySlice;
55+
56+
type VMGCThreadJoinHandle = RubyGCThreadJoinHandle;
5357
}
5458

5559
/// The singleton object for the Ruby binding itself.

0 commit comments

Comments
 (0)