pub(crate) struct GcStatusWord(AtomicUsize);Expand description
A lock-free, atomic encoding of GcStatus. This packs the variant tag into a usize so
the whole status fits in a single machine word and can be updated with compare-and-swap
instead of behind a Mutex<GcStatus>. The tag is kept to Self::TAG_BITS bits (rather than
using the whole word) to leave room for a payload-carrying variant (e.g. a nesting depth) to
be added later without needing to re-encode the rest.
GcStatus is a state machine: only a handful of transitions between its variants are legal.
Every legal transition is exposed here as its own method, each performing its own
compare-and-swap retry loop and asserting that the transition is legal for the status it
finds. Do not add a generic “set the status to X” method: doing so would make it possible to
bypass the state machine’s invariants.
Tuple Fields§
§0: AtomicUsizeImplementations§
Source§impl GcStatusWord
impl GcStatusWord
Sourceconst TAG_BITS: u32 = 3u32
const TAG_BITS: u32 = 3u32
Number of bits used to encode the variant tag. 3 bits is enough to distinguish the 5 variants, leaving the rest of the word free for a future payload-carrying variant.
const TAG_MASK: usize = 7usize
fn encode(status: GcStatus) -> usize
fn decode(bits: usize) -> GcStatus
pub(crate) fn new(status: GcStatus) -> Self
Sourcefn transition<F: FnMut(GcStatus) -> GcStatus>(&self, f: F) -> GcStatus
fn transition<F: FnMut(GcStatus) -> GcStatus>(&self, f: F) -> GcStatus
Retry f (a pure function of the current status) via AtomicUsize::fetch_update until
it succeeds, and return the status it transitioned from (not the new status). Returning
the old status (rather than the new one) lets a caller tell whether it “won” the race when
multiple threads concurrently drive the same transition: only the thread whose CAS
actually moved the status away from a given old value can be sure it is the one
responsible for that transition, so it is the one that should perform any side effect that
must happen exactly once (e.g. notifying the scheduler). If transition returned the new
status instead, every racing thread would observe the same new status and none could tell
which of them caused it. f may be invoked more than once under contention.
pub(crate) fn is_initialized(&self) -> bool
Sourcepub(crate) fn set_initialized(&self)
pub(crate) fn set_initialized(&self)
Uninitialized -> NotInGC.
Sourcepub(crate) fn set_uninitialized(&self)
pub(crate) fn set_uninitialized(&self)
Any status other than Uninitialized -> Uninitialized.
Sourcepub(crate) fn set_in_pause(&self)
pub(crate) fn set_in_pause(&self)
PauseRequested -> InPause.
Sourcepub(crate) fn set_in_concurrent_gc(&self)
pub(crate) fn set_in_concurrent_gc(&self)
InPause -> InConcurrentGC, e.g. once a GC pause has finished but concurrent work (such
as concurrent marking) was scheduled to continue after mutators resume.
Sourcepub(crate) fn set_not_in_gc(&self)
pub(crate) fn set_not_in_gc(&self)
InPause -> NotInGC, e.g. once a GC pause has finished and no concurrent work remains.
Sourcepub(crate) fn try_request_pause(&self) -> PauseRequestOutcome
pub(crate) fn try_request_pause(&self) -> PauseRequestOutcome
NotInGC/InConcurrentGC -> PauseRequested, unless MMTk is not yet initialized, or a
pause has already been requested. See PauseRequestOutcome.
Auto Trait Implementations§
impl !Freeze for GcStatusWord
impl RefUnwindSafe for GcStatusWord
impl Send for GcStatusWord
impl Sync for GcStatusWord
impl Unpin for GcStatusWord
impl UnwindSafe for GcStatusWord
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more