Struct State

Source
struct State {
    global: Global,
    accounts: SlotMap<AId, ARecord>,
}
Expand description

Memory tracker inner, including mutable state

§Module internal documentation

§Data structure

The handles Account, WeakAccount, and Participation, each contain a reference (Arc/Weak) to the MemoryQuotaTracker, and the necessary slotmap keys.

The ARecord and PRecord each contain a reference count, which is used to clean up when all the handles are gone.

The slotmap keys which count for the reference count (ie, strong references) are stored as refcount::Ref, which helps assure correct reference counting. (Bare ids AId and PId are weak references.)

§Data structure lookup

Given a reference to the tracker, and some ids, the macro find_in_tracker! is used to obtain mutable references to the ARecord and (if applicable) PRecord.

§Bookkeeping

We use separate types for quantities of memory in various “states”, rather than working with raw quantities.

The types, and the legitimate transactions, are in bookkeeping.

§Reentrancy (esp. Drop and Clone)

When the handle structs are dropped or cloned, they must manipulate the refcount(s). So they must take the lock. Therefore, an Account and Participation may not be dropped with the lock held!

Internally, this is actually fairly straightforward: we take handles by reference, and constructors only make them at the last moment on return, so our internal code here, in this module, doesn’t have owned handles.

We also need to worry about reentrantly reentering the tracker code, from user code. The user supplies a dyn IsParticipant. The principal methods are from IsParticipant, for which we handle reentrancy in the docs. But we also implicitly invoke its Drop impl, which might in turn drop stuff of ours, such as Accounts and Participations, whose Drop impls need to take our lock. To make sure this isn’t done reentrantly, we have a special newtype around it, and defer some of our drops during reclaim. That’s in drop_reentrancy and tracker::reclaim::deferred_drop.

The Debug impl isn’t of concern, since we don’t call it ourselves. And we don’t rely on it being Clone, since it’s in an Arc.

§Drop bombs

With #[cfg(test)], several of our types have “drop bombs”: they cause a panic if dropped inappropriately. This is intended to detect bad code paths during testing.

Fields§

§global: Global

Global parts of state

Broken out to allow passing both &mut Global and &mut ARecord/&mut PRecord to some function(s).

§accounts: SlotMap<AId, ARecord>

Accounts

Implementations§

Source§

impl State

Source

fn get_aid_and_children_recursively(&self, parent_aid: AId) -> HashSet<AId>

Obtain all of the descendants of parent_aid according to the Child relation

The returned HashSet includes parent_aid, its children, their children, and so on.

Used in the reclamation algorithm in reclaim.

Trait Implementations§

Source§

impl Debug for State

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Deref for State

Source§

type Target = Global

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl DerefMut for State

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.

Auto Trait Implementations§

§

impl Freeze for State

§

impl !RefUnwindSafe for State

§

impl Send for State

§

impl Sync for State

§

impl Unpin for State

§

impl !UnwindSafe for State

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ErasedDestructor for T
where T: 'static,