Skip to content

Fix GC controller thread context #135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mmtk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ lazy_static = "1.1"
# - change branch
# - change repo name
# But other changes including adding/removing whitespaces in commented lines may break the CI.
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "4ebb6b68f54a55bf8794ea01db3f2d0f28d15f4d" }
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "29afb0c2fc8896db95e967062a892d39589bae4d" }
# Uncomment the following to build locally
# mmtk = { path = "../repos/mmtk-core" }

Expand Down
19 changes: 13 additions & 6 deletions mmtk/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::UPCALLS;
use libc::c_char;
use mmtk::memory_manager;
use mmtk::plan::BarrierSelector;
use mmtk::scheduler::GCController;
use mmtk::scheduler::GCWorker;
use mmtk::util::alloc::AllocatorSelector;
use mmtk::util::opaque_pointer::*;
Expand Down Expand Up @@ -49,11 +50,6 @@ pub extern "C" fn openjdk_gc_init(calls: *const OpenJDK_Upcalls, heap_size: usiz
memory_manager::gc_init(singleton_mut, heap_size);
}

#[no_mangle]
pub extern "C" fn start_control_collector(tls: VMWorkerThread) {
memory_manager::start_control_collector(&SINGLETON, tls);
}

#[no_mangle]
pub extern "C" fn bind_mutator(tls: VMMutatorThread) -> *mut Mutator<OpenJDK> {
Box::into_raw(memory_manager::bind_mutator(&SINGLETON, tls))
Expand Down Expand Up @@ -116,12 +112,23 @@ pub extern "C" fn will_never_move(object: ObjectReference) -> bool {
!object.is_movable()
}

#[no_mangle]
// We trust the gc_collector pointer is valid.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn start_control_collector(
tls: VMWorkerThread,
gc_controller: *mut GCController<OpenJDK>,
) {
let mut gc_controller = unsafe { Box::from_raw(gc_controller) };
memory_manager::start_control_collector(&SINGLETON, tls, &mut gc_controller);
}

#[no_mangle]
// We trust the worker pointer is valid.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn start_worker(tls: VMWorkerThread, worker: *mut GCWorker<OpenJDK>) {
let mut worker = unsafe { Box::from_raw(worker) };
memory_manager::start_worker::<OpenJDK>(tls, &mut worker, &SINGLETON)
memory_manager::start_worker::<OpenJDK>(&SINGLETON, tls, &mut worker)
}

#[no_mangle]
Expand Down
23 changes: 15 additions & 8 deletions mmtk/src/collection.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use mmtk::scheduler::{GCWorker, WorkBucketStage};
use mmtk::scheduler::WorkBucketStage;
use mmtk::scheduler::{ProcessEdgesWork, ScanStackRoot};
use mmtk::util::opaque_pointer::*;
use mmtk::vm::{Collection, Scanning, VMBinding};
use mmtk::vm::{Collection, GCThreadContext, Scanning, VMBinding};
use mmtk::{Mutator, MutatorContext};

use crate::OpenJDK;
Expand All @@ -19,6 +19,9 @@ extern "C" fn create_mutator_scan_work<E: ProcessEdgesWork<VM = OpenJDK>>(
);
}

const GC_THREAD_KIND_CONTROLLER: libc::c_int = 0;
const GC_THREAD_KIND_WORKER: libc::c_int = 1;

impl Collection<OpenJDK> for VMCollection {
/// With the presence of the "VM companion thread",
/// the OpenJDK binding allows any MMTk GC thread to stop/start the world.
Expand Down Expand Up @@ -49,14 +52,18 @@ impl Collection<OpenJDK> for VMCollection {
}
}

fn spawn_worker_thread(tls: VMThread, ctx: Option<Box<GCWorker<OpenJDK>>>) {
let ctx_ptr = if let Some(r) = ctx {
Box::into_raw(r)
} else {
std::ptr::null_mut()
fn spawn_gc_thread(tls: VMThread, ctx: GCThreadContext<OpenJDK>) {
let (ctx_ptr, kind) = match ctx {
GCThreadContext::Controller(c) => (
Box::into_raw(c) as *mut libc::c_void,
GC_THREAD_KIND_CONTROLLER,
),
GCThreadContext::Worker(w) => {
(Box::into_raw(w) as *mut libc::c_void, GC_THREAD_KIND_WORKER)
}
};
unsafe {
((*UPCALLS).spawn_worker_thread)(tls, ctx_ptr as usize as _);
((*UPCALLS).spawn_gc_thread)(tls, kind, ctx_ptr);
}
}

Expand Down
3 changes: 1 addition & 2 deletions mmtk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ extern crate lazy_static;
use std::ptr::null_mut;

use libc::{c_char, c_void, uintptr_t};
use mmtk::scheduler::GCWorker;
use mmtk::util::opaque_pointer::*;
use mmtk::util::{Address, ObjectReference};
use mmtk::vm::VMBinding;
Expand Down Expand Up @@ -45,7 +44,7 @@ pub struct OpenJDK_Upcalls {
create_stack_scan_work: *const extern "C" fn(&'static mut Mutator<OpenJDK>),
),
pub resume_mutators: extern "C" fn(tls: VMWorkerThread),
pub spawn_worker_thread: extern "C" fn(tls: VMThread, ctx: *mut GCWorker<OpenJDK>),
pub spawn_gc_thread: extern "C" fn(tls: VMThread, kind: libc::c_int, ctx: *mut libc::c_void),
pub block_for_gc: extern "C" fn(),
pub get_next_mutator: extern "C" fn() -> *mut Mutator<OpenJDK>,
pub reset_mutator_iterator: extern "C" fn(),
Expand Down
4 changes: 2 additions & 2 deletions openjdk/mmtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ extern bool process_bulk(char* options);
extern void scan_region();
extern void handle_user_collection_request(void *tls);

extern void start_control_collector(void *tls);
extern void start_control_collector(void *tls, void *context);
extern void start_worker(void *tls, void* worker);

/**
Expand All @@ -100,7 +100,7 @@ typedef NewBuffer (*ProcessEdgesFn)(void** buf, size_t len, size_t cap);
typedef struct {
void (*stop_all_mutators) (void *tls, void (*create_stack_scan_work)(void* mutator));
void (*resume_mutators) (void *tls);
void (*spawn_collector_thread) (void *tls, void *ctx);
void (*spawn_collector_thread) (void *tls, int kind, void *ctx);
void (*block_for_gc) ();
void* (*get_next_mutator) ();
void (*reset_mutator_iterator) ();
Expand Down
4 changes: 2 additions & 2 deletions openjdk/mmtkContextThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
#include "mmtk.h"
#include "mmtkContextThread.hpp"

MMTkContextThread::MMTkContextThread() : NamedThread() {
MMTkContextThread::MMTkContextThread(void *context) : NamedThread(), context_(context) {
set_name("MMTk Controller Context Thread");
}

void MMTkContextThread::run() {
this->initialize_named_thread();
start_control_collector((void*) this);
start_control_collector((void*) this, context_);
}
3 changes: 2 additions & 1 deletion openjdk/mmtkContextThread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@
#include "runtime/thread.hpp"

class MMTkContextThread: public NamedThread {
void* context_;
public:
// Constructor
MMTkContextThread();
MMTkContextThread(void* context);

// No destruction allowed
~MMTkContextThread() {
Expand Down
37 changes: 24 additions & 13 deletions openjdk/mmtkUpcalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,33 @@ static void mmtk_resume_mutators(void *tls) {
log_debug(gc)("Mutators notified.");
}

static void mmtk_spawn_collector_thread(void* tls, void* ctx) {
if (ctx == NULL) {
MMTkContextThread* t = new MMTkContextThread();
if (!os::create_thread(t, os::pgc_thread)) {
printf("Failed to create thread");
guarantee(false, "panic");
static const int GC_THREAD_KIND_CONTROLLER = 0;
static const int GC_THREAD_KIND_WORKER = 1;
static void mmtk_spawn_collector_thread(void* tls, int kind, void* ctx) {
switch (kind) {
case GC_THREAD_KIND_CONTROLLER: {
MMTkContextThread* t = new MMTkContextThread(ctx);
if (!os::create_thread(t, os::pgc_thread)) {
printf("Failed to create thread");
guarantee(false, "panic");
}
os::start_thread(t);
break;
}
case GC_THREAD_KIND_WORKER: {
MMTkHeap::heap()->new_collector_thread();
MMTkCollectorThread* t = new MMTkCollectorThread(ctx);
if (!os::create_thread(t, os::pgc_thread)) {
printf("Failed to create thread");
guarantee(false, "panic");
}
os::start_thread(t);
break;
}
os::start_thread(t);
} else {
MMTkHeap::heap()->new_collector_thread();
MMTkCollectorThread* t = new MMTkCollectorThread(ctx);
if (!os::create_thread(t, os::pgc_thread)) {
printf("Failed to create thread");
default: {
printf("Unexpected thread kind: %d\n", kind);
guarantee(false, "panic");
}
os::start_thread(t);
}
}

Expand Down