pub(crate) struct GcStatusWord(AtomicUsize);Expand description
A lock-free, atomic encoding of GcStatus. This packs the variant tag into the low bits
of a usize and, for GcStatus::Disabled, the nesting depth into the remaining high bits,
so the whole status fits in a single machine word and can be updated with atomic operations
instead of behind a Mutex<GcStatus>.
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 6
variants, leaving the rest of the word for Disabled’s nesting depth.
const TAG_MASK: usize = 7usize
fn encode(status: GcStatus) -> usize
fn decode(bits: usize) -> GcStatus
pub(crate) fn new(status: GcStatus) -> Self
Sourcefn transition_inner<F: FnMut(GcStatus) -> GcStatus>(&self, f: F) -> GcStatus
fn transition_inner<F: FnMut(GcStatus) -> GcStatus>(&self, f: F) -> GcStatus
Inner implementation of Self::transition, handling encoding, decoding, and atomic RMW
operation.
Sourcefn transition<F: FnMut(GcStatus) -> GcStatus>(&self, f: F) -> GcStatus
fn transition<F: FnMut(GcStatus) -> GcStatus>(&self, f: F) -> GcStatus
Attempt to atomically transition the GC status using function f. Return the status
atomically transitioned from (not the new status). It will retry f if the status is
modified concurrently.
Note: 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.
Sourcefn try_transition_inner<F: FnMut(GcStatus) -> Option<GcStatus>>(
&self,
f: F,
) -> Result<GcStatus, GcStatus>
fn try_transition_inner<F: FnMut(GcStatus) -> Option<GcStatus>>( &self, f: F, ) -> Result<GcStatus, GcStatus>
Inner implementation of Self::try_transition, handling encoding, decoding, and atomic RMW
operation.
Sourcefn try_transition<F: FnMut(GcStatus) -> Option<GcStatus>>(
&self,
f: F,
) -> Result<GcStatus, GcStatus>
fn try_transition<F: FnMut(GcStatus) -> Option<GcStatus>>( &self, f: F, ) -> Result<GcStatus, GcStatus>
Attempt to atomically transition the GC status using function f. Return Ok(old_status)
if f returns Some(new_status), in which case it has atomically transitioned the state
from old_state to new_state. Return Err(old_status) if f returns None, in which
case old_status is the status passed to the last invocation of f. It will retry f if
f returns Some but the underlying status is modified concurrently.
pub(crate) fn is_initialized(&self) -> bool
pub(crate) fn is_disabled(&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 set_disabled(&self) -> Result<bool, GcStatus>
pub(crate) fn set_disabled(&self) -> Result<bool, GcStatus>
NotInGC/Disabled(depth) -> Disabled(depth + 1). Leaves the status unchanged if
collection cannot be disabled from the current status (e.g. a GC is in progress or has
been requested), and returns Err with the status that blocked the transition.
On success, returns Ok(true) if this call actually switched collection from enabled to
disabled (i.e. it was the outermost NotInGC -> Disabled(1) transition), Ok(false) if
it only increased the nesting depth of an already-disabled status. Mirrors the meaning of
GcStatusWord::set_enabled’s return value.
Sourcepub(crate) fn set_enabled(&self) -> bool
pub(crate) fn set_enabled(&self) -> bool
Disabled(depth) -> Disabled(depth - 1), or Disabled(1) -> NotInGC. If collection is
not currently disabled, this is a no-op (the status is left unchanged). Returns true if
this call actually re-enabled collection (i.e. it was the outermost Disabled(1) ->
NotInGC transition), false if it only decremented the nesting depth, or if collection
was already enabled.
Sourcepub(crate) fn try_request_pause(&self) -> Result<(), GcStatus>
pub(crate) fn try_request_pause(&self) -> Result<(), GcStatus>
NotInGC/InConcurrentGC -> PauseRequested, unless collection is disabled, MMTk is not
yet initialized, or a pause has already been requested, in which case Err is returned
with the status that prevented the transition (Disabled(_), Uninitialized, or
PauseRequested respectively).
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