-
Notifications
You must be signed in to change notification settings - Fork 69
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
Ask from binding if GC is disabled #1075
Conversation
If the VM needs to disable GC to implement critical sections where GC activities such as moving object may affect the correctness of the program (usuallly due to native programs accessing buffers in heap objects), the easiest way is simply telling the current thread not to yield. Of course this approach only works for STW GC. p.s. It is always better to pin objects for this purpose instead of relying on disabling GC. The mechanism introduced in this PR (i.e. letting mmtk-core ask the binding whether it should trigger GC) is still not sound for implementing critical sections. For example,
The problem is that one mutator is still active after another mutator triggered GC and a GC thread responded. |
I don't think this PR is trying to introduce something that can be used for implementing critical section. It is trying to replace the current |
@qinsoon is correct.
For critical sections, Julia has the notion of GC state. Essentially, if Mutator2 enters a critical section, Mutator1 should wait (when it's waiting for the world to stop) until Mutator2 leaves the critical section. |
Currently, If As long as mmtk-core doesn't need to enforce any sychronization between mutators, this PR should be OK. Specifically,
And the synchronization is left to the VM. The VM can duplicate the current behavior by adding an atomic boolean variable in the binding. And it is also up to the VM to define the semantics of disabling GC. For CRuby, the semantics of
But since CRuby uses global VM lock, the execution within one Ractor should be sequentially consistent by definition (because it is sequential). |
I'm a bit confused. Are you referring to
We can ask the Julia folks why they have it, but the semantics as far as I understand is that you may continue allocating (beyond any heap limit) and it will not trigger GC. Essentially disabling any GC pooling that may happen, including the case when the user asks for a GC.
I'll try to improve the documentation to include (1). For (2), it means that bindings for VMs that do not have such "feature" don't need to change anything. Again, if we're talking about |
…when_heap_is_full which are now redundant
Both. Ruby currently uses both // The threading system is ready. Initialize collection.
mmtk_initialize_collection(th);
// Bind the main thread.
rb_mmtk_bind_mutator(th);
// Temporarily disable GC.
mmtk_disable_collection();
// After lots of initialization, in another function
if (rb_mmtk_enabled_p()) {
// Now that the VM says it's time to enable GC, we enable GC for MMTk, too.
mmtk_enable_collection();
} Given that the only thing |
Is this PR ready for review? I would prefer @wks to review this. I will remove myself from the reviewer list. |
Here is a PR for the Ruby binding: mmtk/mmtk-ruby#52 |
binding-refs |
The merge check somehow failed, which is strange. It seems observing extended tests from previous runs (not the most recent runs). [2024-02-01 01:57:33.902814] wait.DEBUG: Check "extended-tests-ruby (release)" has the following status "completed" and conclusion "failure"
[2024-02-01 01:57:33.902824] wait.DEBUG: Check (extended-tests-ruby (release)) failed, marking resolve and failure
[2024-02-01 01:57:33.902834] wait.DEBUG: Check "extended-tests-ruby (debug)" has the following status "completed" and conclusion "cancelled"
[2024-02-01 01:57:33.902843] wait.DEBUG: Check (extended-tests-ruby (debug)) failed, marking resolve and failure
[2024-02-01 01:57:33.902853] wait.DEBUG: Check "extended-tests-jikesrvm" has the following status "completed" and conclusion "failure"
[2024-02-01 01:57:33.902862] wait.DEBUG: Check (extended-tests-jikesrvm) failed, marking resolve and failure
[2024-02-01 01:57:33.902871] wait.DEBUG: Check "extended-tests-julia" has the following status "completed" and conclusion "failure"
[2024-02-01 01:57:33.902881] wait.DEBUG: Check (extended-tests-julia) failed, marking resolve and failure Those tests passed in the most recent run. |
@wks I've just re-requested a review in case you have further comments. |
Did you observe this? If so, it sounds like a bug. Without |
src/vm/tests/mock_tests/mock_test_allocate_with_re_enable_collection.rs
Outdated
Show resolved
Hide resolved
src/vm/tests/mock_tests/mock_test_allocate_with_re_enable_collection.rs
Outdated
Show resolved
Hide resolved
Co-authored-by: Kunshan Wang <[email protected]>
No. This is purely hypothetical. I see that // Is a GC allowed here? If we should poll but are not allowed to poll, we will panic.
// initialize_collection() has to be called so we know GC is initialized.
let allow_gc = should_poll && self.common().global_state.is_initialized(); And this: if should_poll && self.get_gc_trigger().poll(false, Some(self.as_space())) {
debug!("Collection required");
assert!(allow_gc, "GC is not allowed here: collection is not initialized (did you call initialize_collection()?).");
// ...
VM::VMCollection::block_for_gc(VMMutatorThread(tls)); // We have checked that this is mutator
unsafe { Address::zero() } So if It looks like the actual contract of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
The "Merge Check" failed for the reason of "Status checks failed". That's strange. |
I think the first attempt to run Julia tests failed, which caused the merge check fail. When we reran the failed tests (Julia tests), the merge check did not get a rerun and its status won't change. |
Upstream PR: mmtk/mmtk-core#1075 --------- Co-authored-by: Eduardo Souza <[email protected]> Co-authored-by: mmtkgc-bot <[email protected]>
Upstream PR: mmtk/mmtk-core#1075 Julia PR: mmtk/julia#35 --------- Co-authored-by: mmtkgc-bot <[email protected]>
Upstream PR: mmtk/mmtk-core#1075 Julia PR: mmtk/julia#35 --------- Co-authored-by: mmtkgc-bot <[email protected]> (cherry picked from commit eac7e88) # Conflicts: # mmtk/Cargo.lock # mmtk/Cargo.toml # mmtk/api/mmtk.h # mmtk/src/api.rs # mmtk/src/collection.rs
Upstream PR: mmtk/mmtk-core#1075 Julia PR: mmtk/julia#35 --------- Co-authored-by: mmtkgc-bot <[email protected]> (cherry picked from commit eac7e88) # Conflicts: # mmtk/Cargo.lock # mmtk/Cargo.toml # mmtk/src/collection.rs
MMTk currently supports disabling GC (a.k.a. allowing the heap to grow above its limit) via two api functions:
disable_collection
andenable_collection
.This PR replaces this strategy since currently, MMTk relies on the binding ensuring thread safety when calling those functions. In this refactoring, MMTk asks if GC is disabled in
VM::VMCollection::is_collection_disabled()
function, and expects any thread safety logic to be implemented in the VM itself, and not necessarily depend on MMTk.