Skip to content

Rename Workbucket's active flag to open, add enable flag#1373

Merged
qinsoon merged 7 commits intommtk:masterfrom
qinsoon:bucket-disable-refactoring
Aug 25, 2025
Merged

Rename Workbucket's active flag to open, add enable flag#1373
qinsoon merged 7 commits intommtk:masterfrom
qinsoon:bucket-disable-refactoring

Conversation

@qinsoon
Copy link
Copy Markdown
Member

@qinsoon qinsoon commented Aug 22, 2025

This PR refactors work bucket to allow disabling a bucket and to support concurrent GC.

  • Add a field WorkBucket::enabled: if a bucket is disabled, it behaves the same as if the bucket/stage does not exist for scheduling, except that users can add work to a disabled bucket. There are mostly two use cases for this: 1. a plan can disable buckets that the plan does not use, and 2. a concurrent plan may push concurrent work to the disabled concurrent bucket during STW, and enable the bucket at the end of a STW.
  • Add WorkBucketStage::Concurrent: this is unused in this PR.
  • Clean up most checks about stages in scheduler.rs, and move them to work_bucket.rs.
  • Add a reference to the scheduler in BasePlan.

@qinsoon qinsoon force-pushed the bucket-disable-refactoring branch from e49253d to c1489fe Compare August 22, 2025 05:01
@qinsoon qinsoon added the PR-extended-testing Run extended tests for the pull request label Aug 22, 2025
@qinsoon qinsoon marked this pull request as ready for review August 22, 2025 06:01
@qinsoon qinsoon requested a review from wks August 22, 2025 06:01
Copy link
Copy Markdown
Collaborator

@wks wks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The algorithm should be OK because we haven't actually added concurrent GC, and I think this PR is compatible with existing plans.

One problem is that the newly introduced terms "enabled/disabled" is somewhat confusing when used together with "active/inactive" or "activated/deactivated". The doc comment of WorkBucket::deactivate even says "disable the bucket". I suggest renaming "active" to "open". Then "open/closed" means if the bucket is open during a GC as a result of, for example, draining previous buckets. Meanwhile, "enabled/disabled" means whether we hide a bucket from mutators as if the bucket doesn't exist.

Comment thread src/scheduler/work_bucket.rs Outdated
!self.is_concurrent()
}

/// Is this stage concurrent (which may be executedd during mutator time)?
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Is this stage concurrent (which may be executedd during mutator time)?
/// Is this stage concurrent (which may be executed during mutator time)?

Comment thread src/scheduler/work_bucket.rs Outdated
self.is_disabled() || (self.is_activated() && self.is_empty())
}

/// Disable the bucket
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment says "disable the bucket"

Comment on lines +45 to +77
let mut items = Vec::new();

{
// Drain queue by stealing until empty
loop {
match self.queue.steal() {
crossbeam::deque::Steal::Success(work) => {
items.push(work);
}
crossbeam::deque::Steal::Retry => continue,
crossbeam::deque::Steal::Empty => break,
}
}
}

// Format collected items (just type names or Debug, depending on GCWork)
let debug_items: Vec<String> = items
.iter()
.map(|i| i.get_type_name().to_string()) // placeholder since GCWork isn’t Debug
.collect();

// Push items back into the queue
{
for work in items {
self.queue.push(work);
}
}

f.debug_struct("BucketQueue")
.field("queue", &debug_items)
.finish()
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part drains the bucket to print the packets, and re-fill the packets. If this happens while some GC workers are fetching packets, the other worker may erroneously think the bucket is already drained.

If we really want to debug work buckets in such a detail, we should add a dedicated method, such as BucketQueue::debug_dump_packets. The Debug trait should be side-effect-free.

}
if let Some(id) = error_example {
panic!("Some active buckets (such as {:?}) are not empty.", id);
panic!("Some open buckets (such as {:?}) are not empty.", id);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This says "open".

continue;
}
debug!("Checking if {:?} can be opened...", id);
let bucket_opened = bucket.update(self);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line also says "opened".

Comment thread src/scheduler/work_bucket.rs Outdated

pub struct WorkBucket<VM: VMBinding> {
/// Whether this bucket has been opened. Work from an open bucket can be fetched by workers.
active: AtomicBool,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this to "open".

Comment thread src/scheduler/work_bucket.rs Outdated
Comment on lines +396 to +398
pub const fn is_always_activated(&self) -> bool {
matches!(self, WorkBucketStage::Unconstrained)
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub const fn is_always_activated(&self) -> bool {
matches!(self, WorkBucketStage::Unconstrained)
}
pub const fn is_always_open(&self) -> bool {
matches!(self, WorkBucketStage::Unconstrained)
}

Comment thread src/scheduler/work_bucket.rs Outdated
}

/// Is this stage activated by default?
pub const fn is_activated_by_default(&self) -> bool {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub const fn is_activated_by_default(&self) -> bool {
pub const fn is_open_by_default(&self) -> bool {

Comment thread src/scheduler/work_bucket.rs Outdated
Comment on lines +409 to +411
pub const fn is_disabled_by_default(&self) -> bool {
matches!(self, WorkBucketStage::Concurrent)
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub const fn is_disabled_by_default(&self) -> bool {
matches!(self, WorkBucketStage::Concurrent)
}
pub const fn is_enabled_by_default(&self) -> bool {
!matches!(self, WorkBucketStage::Concurrent)
}

Comment thread src/scheduler/work_bucket.rs Outdated
Comment on lines 112 to 114
pub(crate) fn new(stage: WorkBucketStage, active: bool, monitor: Arc<WorkerMonitor>) -> Self {
Self {
active: AtomicBool::new(active),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a stage knows if the bucket at that stage is open by default, we can just initialize it here.

Suggested change
pub(crate) fn new(stage: WorkBucketStage, active: bool, monitor: Arc<WorkerMonitor>) -> Self {
Self {
active: AtomicBool::new(active),
pub(crate) fn new(stage: WorkBucketStage, monitor: Arc<WorkerMonitor>) -> Self {
Self {
active: AtomicBool::new(stage.is_open_by_default()),

@qinsoon qinsoon force-pushed the bucket-disable-refactoring branch from 1a3e5ea to 0f64b73 Compare August 25, 2025 04:09
@qinsoon
Copy link
Copy Markdown
Member Author

qinsoon commented Aug 25, 2025

@wks I have made changes as suggested. Can you review again?

Copy link
Copy Markdown
Collaborator

@wks wks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are still other places in the comments that mention "activated buckets". We should grep the word "activate" and change it to "open" or "opened", depending on the context.

We should update the pull request description #1373 (comment), too, as it will become the commit log.

Comment thread src/scheduler/work_bucket.rs Outdated
Comment thread src/scheduler/work_bucket.rs Outdated
@qinsoon qinsoon changed the title Refactoring to support disabling work bucket and concurrent GC Rename Workbucket's active flag to open, add enable flag Aug 25, 2025
@qinsoon
Copy link
Copy Markdown
Member Author

qinsoon commented Aug 25, 2025

There are still other places in the comments that mention "activated buckets". We should grep the word "activate" and change it to "open" or "opened", depending on the context.

We should update the pull request description #1373 (comment), too, as it will become the commit log.

Done.

Copy link
Copy Markdown
Collaborator

@wks wks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

I also pushed some pedantic changes and synchronized with master. You can merge this PR when you think it is appropriate.

@qinsoon qinsoon added this pull request to the merge queue Aug 25, 2025
Merged via the queue into mmtk:master with commit 6eb1328 Aug 25, 2025
31 of 33 checks passed
@qinsoon qinsoon deleted the bucket-disable-refactoring branch August 25, 2025 10:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR-extended-testing Run extended tests for the pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants