diff --git a/mmtk/Cargo.lock b/mmtk/Cargo.lock index daa074c..55b8518 100644 --- a/mmtk/Cargo.lock +++ b/mmtk/Cargo.lock @@ -74,7 +74,7 @@ checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -168,9 +168,9 @@ dependencies = [ [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "either" @@ -195,7 +195,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -359,8 +359,8 @@ dependencies = [ [[package]] name = "mmtk" -version = "0.23.0" -source = "git+https://github.com/mmtk/mmtk-core.git?rev=dd84218933deab50196fc77828cc1446cb829881#dd84218933deab50196fc77828cc1446cb829881" +version = "0.24.0" +source = "git+https://github.com/mmtk/mmtk-core.git?rev=5ab62f96c006475285b00b6d20a8b1bf83b74a4d#5ab62f96c006475285b00b6d20a8b1bf83b74a4d" dependencies = [ "atomic", "atomic-traits", @@ -394,13 +394,13 @@ dependencies = [ [[package]] name = "mmtk-macros" -version = "0.23.0" -source = "git+https://github.com/mmtk/mmtk-core.git?rev=dd84218933deab50196fc77828cc1446cb829881#dd84218933deab50196fc77828cc1446cb829881" +version = "0.24.0" +source = "git+https://github.com/mmtk/mmtk-core.git?rev=5ab62f96c006475285b00b6d20a8b1bf83b74a4d#5ab62f96c006475285b00b6d20a8b1bf83b74a4d" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -459,9 +459,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" dependencies = [ "memchr", "thiserror", @@ -588,9 +588,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" [[package]] name = "scopeguard" @@ -647,7 +647,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -663,9 +663,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.55" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -713,7 +713,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] diff --git a/mmtk/Cargo.toml b/mmtk/Cargo.toml index 6a1bca5..5b87d08 100644 --- a/mmtk/Cargo.toml +++ b/mmtk/Cargo.toml @@ -12,7 +12,7 @@ edition = "2021" # Metadata for the Ruby repository [package.metadata.ci-repos.ruby] repo = "mmtk/ruby" # This is used by actions/checkout, so the format is "owner/repo", not URL. -rev = "6d1596f7a4401d267d2b208c42521edc35020a8e " +rev = "e173f879e6e4f1566cca83513e7bfeb4f39331a8" [lib] name = "mmtk_ruby" @@ -37,7 +37,7 @@ features = ["is_mmtk_object", "object_pinning"] # Uncomment the following lines to use mmtk-core from the official repository. git = "https://github.com/mmtk/mmtk-core.git" -rev = "dd84218933deab50196fc77828cc1446cb829881" +rev = "5ab62f96c006475285b00b6d20a8b1bf83b74a4d" # Uncomment the following line to use mmtk-core from a local repository. #path = "../../mmtk-core" diff --git a/mmtk/src/abi.rs b/mmtk/src/abi.rs index 1eac22c..fe298ff 100644 --- a/mmtk/src/abi.rs +++ b/mmtk/src/abi.rs @@ -1,13 +1,12 @@ use crate::api::RubyMutator; use crate::{upcalls, Ruby}; -use mmtk::scheduler::{GCController, GCWorker}; +use mmtk::scheduler::GCWorker; use mmtk::util::{Address, ObjectReference, VMMutatorThread, VMWorkerThread}; // For the C binding pub const OBJREF_OFFSET: usize = 8; pub const MIN_OBJ_ALIGN: usize = 8; // Even on 32-bit machine. A Ruby object is at least 40 bytes large. -pub const GC_THREAD_KIND_CONTROLLER: libc::c_int = 0; pub const GC_THREAD_KIND_WORKER: libc::c_int = 1; const HAS_MOVED_GIVTBL: usize = 1 << 63; @@ -244,10 +243,6 @@ impl GCThreadTLS { } } - pub fn for_controller(gc_context: *mut GCController) -> Self { - Self::new(GC_THREAD_KIND_CONTROLLER, gc_context as *mut libc::c_void) - } - pub fn for_worker(gc_context: *mut GCWorker) -> Self { Self::new(GC_THREAD_KIND_WORKER, gc_context as *mut libc::c_void) } @@ -266,7 +261,7 @@ impl GCThreadTLS { let result = &mut *ptr; debug_assert!({ let kind = result.kind; - kind == GC_THREAD_KIND_CONTROLLER || kind == GC_THREAD_KIND_WORKER + kind == GC_THREAD_KIND_WORKER }); result } diff --git a/mmtk/src/api.rs b/mmtk/src/api.rs index 3d1d255..1be3a0b 100644 --- a/mmtk/src/api.rs +++ b/mmtk/src/api.rs @@ -156,6 +156,17 @@ pub extern "C" fn mmtk_initialize_collection(tls: VMThread) { memory_manager::initialize_collection(mmtk(), tls) } +#[no_mangle] +pub extern "C" fn mmtk_prepare_to_fork() { + mmtk().prepare_to_fork(); + binding().join_all_gc_threads(); +} + +#[no_mangle] +pub extern "C" fn mmtk_after_fork(tls: VMThread) { + mmtk().after_fork(tls); +} + #[no_mangle] pub extern "C" fn mmtk_enable_collection() { BINDING_FAST.gc_enabled.store(true, Ordering::Relaxed); diff --git a/mmtk/src/binding.rs b/mmtk/src/binding.rs index 6ef1d7e..9f7e6f5 100644 --- a/mmtk/src/binding.rs +++ b/mmtk/src/binding.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::ffi::CString; use std::sync::atomic::AtomicBool; use std::sync::Mutex; +use std::thread::JoinHandle; use libc::c_void; use mmtk::util::ObjectReference; @@ -50,6 +51,7 @@ pub struct RubyBinding { pub weak_proc: WeakProcessor, pub ppp_registry: PPPRegistry, pub(crate) moved_givtbl: Mutex>, + pub gc_thread_join_handles: Mutex>>, } unsafe impl Sync for RubyBinding {} @@ -72,6 +74,7 @@ impl RubyBinding { weak_proc: WeakProcessor::new(), ppp_registry: PPPRegistry::new(), moved_givtbl: Default::default(), + gc_thread_join_handles: Default::default(), } } @@ -89,4 +92,20 @@ impl RubyBinding { } plan_name.as_deref().unwrap().as_ptr() } + + pub fn join_all_gc_threads(&self) { + let handles = { + let mut guard = self.gc_thread_join_handles.lock().unwrap(); + std::mem::take(&mut *guard) + }; + + debug!("Joining GC threads..."); + let total = handles.len(); + let mut joined = 0; + for handle in handles { + handle.join().unwrap(); + joined += 1; + debug!("{joined}/{total} GC threads joined."); + } + } } diff --git a/mmtk/src/collection.rs b/mmtk/src/collection.rs index 3995975..ad4da8b 100644 --- a/mmtk/src/collection.rs +++ b/mmtk/src/collection.rs @@ -37,53 +37,37 @@ impl Collection for VMCollection { } fn spawn_gc_thread(_tls: VMThread, ctx: GCThreadContext) { - match ctx { - GCThreadContext::Controller(mut controller) => { - thread::Builder::new() - .name("MMTk Controller Thread".to_string()) - .spawn(move || { - debug!("Hello! This is MMTk Controller Thread running!"); - crate::register_gc_thread(thread::current().id()); - let ptr_controller = &mut *controller as *mut GCController; - let gc_thread_tls = - Box::into_raw(Box::new(GCThreadTLS::for_controller(ptr_controller))); - (upcalls().init_gc_worker_thread)(gc_thread_tls); - memory_manager::start_control_collector( - mmtk(), - GCThreadTLS::to_vwt(gc_thread_tls), - &mut controller, - ); + let join_handle = match ctx { + GCThreadContext::Worker(mut worker) => thread::Builder::new() + .name("MMTk Worker Thread".to_string()) + .spawn(move || { + let ordinal = worker.ordinal; + debug!( + "Hello! This is MMTk Worker Thread running! ordinal: {}", + ordinal + ); + crate::register_gc_thread(thread::current().id()); + let ptr_worker = &mut *worker as *mut GCWorker; + let gc_thread_tls = + Box::into_raw(Box::new(GCThreadTLS::for_worker(ptr_worker))); + (upcalls().init_gc_worker_thread)(gc_thread_tls); + memory_manager::start_worker( + mmtk(), + GCThreadTLS::to_vwt(gc_thread_tls), + worker, + ); + debug!( + "An MMTk Worker Thread is quitting. Good bye! ordinal: {}", + ordinal + ); + crate::unregister_gc_thread(thread::current().id()); + }) + .unwrap(), + }; - // Currently the MMTk controller thread should run forever. - // This is an unlikely event, but we log it anyway. - warn!("The MMTk Controller Thread is quitting!"); - crate::unregister_gc_thread(thread::current().id()); - }) - .unwrap(); - } - GCThreadContext::Worker(mut worker) => { - thread::Builder::new() - .name("MMTk Worker Thread".to_string()) - .spawn(move || { - debug!("Hello! This is MMTk Worker Thread running!"); - crate::register_gc_thread(thread::current().id()); - let ptr_worker = &mut *worker as *mut GCWorker; - let gc_thread_tls = - Box::into_raw(Box::new(GCThreadTLS::for_worker(ptr_worker))); - (upcalls().init_gc_worker_thread)(gc_thread_tls); - memory_manager::start_worker( - mmtk(), - GCThreadTLS::to_vwt(gc_thread_tls), - &mut worker, - ); - - // Currently all MMTk worker threads should run forever. - // This is an unlikely event, but we log it anyway. - warn!("An MMTk Worker Thread is quitting!"); - crate::unregister_gc_thread(thread::current().id()); - }) - .unwrap(); - } + { + let mut handles = crate::binding().gc_thread_join_handles.lock().unwrap(); + handles.push(join_handle); } }