Skip to main content

SegmentOwner

Struct SegmentOwner 

Source
pub struct SegmentOwner<M: AnyFrameMeta + ?Sized> {
    pub range: Range<Paddr>,
    pub _marker: PhantomData<M>,
}

Fields§

§range: Range<Paddr>

The physical-address range of the segment that this owner corresponds to.

Design B (Arc-style): the owner no longer holds the per-frame slot permissions. Each frame’s simple_pptr::PointsTo<MetaSlot> stays canonical in regions.slots[idx] and is borrowed on drop/next; the segment merely contributes one (forgotten) reference per frame.

Per-frame linear-drop: the owner carries no obligation token. The segment’s “must drop” guarantee is enforced entirely by the per-frame regions.frame_obligations multiset (one count per segment frame, see SegmentOwner::relate_regions) combined with the boundary clean_inv() check — silently dropping a SegmentOwner leaves those counts outstanding and breaks clean_inv(). Redeem-time tokens are fabricated on demand via DropObligation::tracked_mint, so no token needs to travel with the owner.

§_marker: PhantomData<M>

Implementations§

Source§

impl<M: AnyFrameMeta + ?Sized> SegmentOwner<M>

Source

pub open spec fn relate_regions(self, regions: MetaRegionOwners) -> bool

{
    &&& forall |i: int| {
        0 <= i < seg_nframes(self.range)
            ==> {
                let idx = frame_to_index((self.range.start + i * PAGE_SIZE) as usize);
                &&& regions.frame_obligations.count(idx) >= 1
                &&& regions.slot_owners.contains_key(idx)
                &&& regions.slots.contains_key(idx)
                &&& regions.slot_owners[idx].self_addr == meta_addr(idx)
                &&& regions.slot_owners[idx].inner_perms.ref_count.value() > 0
                &&& regions.slot_owners[idx].inner_perms.ref_count.value()
                    <= crate::mm::frame::meta::REF_COUNT_MAX
                &&& regions.slot_owners[idx].paths_in_pt.is_empty()
                &&& regions.slot_owners[idx].usage
                    == crate::specs::mm::frame::meta_owners::PageUsage::Frame

            }
    }
    &&& forall |i: int, j: int| {
        0 <= i < j < seg_nframes(self.range)
            ==> frame_to_index((self.range.start + i * PAGE_SIZE) as usize)
                != frame_to_index((self.range.start + j * PAGE_SIZE) as usize)
    }

}

The cross-object relation between a SegmentOwner and the global MetaRegionOwners.

For every frame i in the segment, this asserts:

  • the slot owner is present in regions and the perm matches it,
  • the slot’s self_addr is consistent with its index,
  • the slot has a live, non-UNUSED reference count,
  • raw_count == 1 (the segment holds one forgotten reference per frame),
  • the slot’s perm is not in regions.slots (it lives in self.perms),
  • distinct frames in the segment map to distinct slot indices.

This is an invariant preserved by every operation that transforms a SegmentOwner together with MetaRegionOwners — analogous to crate::specs::mm::frame::unique::UniqueFrameOwner::global_inv but spanning all frames in a segment.

Source

pub proof fn relate_regions_at(self, regions: MetaRegionOwners, i: int)

requires
self.relate_regions(regions),
0 <= i < seg_nframes(self.range),
ensures
({
    let idx = frame_to_index((self.range.start + i * PAGE_SIZE) as usize);
    &&& regions.frame_obligations.count(idx) >= 1
    &&& regions.slot_owners.contains_key(idx)
    &&& regions.slots.contains_key(idx)
    &&& regions.slot_owners[idx].self_addr == meta_addr(idx)
    &&& regions.slot_owners[idx].inner_perms.ref_count.value() > 0
    &&& regions.slot_owners[idx].inner_perms.ref_count.value()
        <= crate::mm::frame::meta::REF_COUNT_MAX
    &&& regions.slot_owners[idx].paths_in_pt.is_empty()
    &&& regions.slot_owners[idx].usage
        == crate::specs::mm::frame::meta_owners::PageUsage::Frame

}),

Manually instantiates the [relate_regions] forall at a specific index. Use this to extract per-frame facts (slot_owner present, slot perm in regions.slots, raw_count == 1, ref_count > 0, etc.) without fighting trigger inference.

Source

pub proof fn relate_regions_distinct(self, regions: MetaRegionOwners, i: int, j: int)

requires
self.relate_regions(regions),
0 <= i < j < seg_nframes(self.range),
ensures
frame_to_index((self.range.start + i * PAGE_SIZE) as usize)
    != frame_to_index((self.range.start + j * PAGE_SIZE) as usize),

Manually instantiates the [relate_regions] distinctness forall at a specific index pair: distinct in-range frames map to distinct slot indices. Reusable lever for from_unused/split/slice proofs.

Trait Implementations§

Source§

impl<M: AnyFrameMeta + ?Sized> Inv for SegmentOwner<M>

Source§

open spec fn inv(self) -> bool

{
    &&& self.range.start % PAGE_SIZE == 0
    &&& self.range.end % PAGE_SIZE == 0
    &&& self.range.start <= self.range.end <= MAX_PADDR

}

The invariant of a SegmentOwner:

  • the tracked range is page-aligned and within bounds;
  • the number of permissions matches the number of frames in the range;
  • each permission’s address corresponds to the meta slot of its frame (so consecutive permissions are spaced by META_SLOT_SIZE);
  • each permission is initialized and individually well-formed.
  • the bundled obligation token is keyed to this owner’s range.

Auto Trait Implementations§

§

impl<M> Freeze for SegmentOwner<M>
where M: ?Sized,

§

impl<M> RefUnwindSafe for SegmentOwner<M>
where M: RefUnwindSafe + ?Sized,

§

impl<M> Send for SegmentOwner<M>
where M: Send + ?Sized,

§

impl<M> Sync for SegmentOwner<M>
where M: Sync + ?Sized,

§

impl<M> Unpin for SegmentOwner<M>
where M: Unpin + ?Sized,

§

impl<M> UnsafeUnpin for SegmentOwner<M>
where M: ?Sized,

§

impl<M> UnwindSafe for SegmentOwner<M>
where M: UnwindSafe + ?Sized,

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, VERUS_SPEC__A> FromSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: From<T>,

§

fn obeys_from_spec() -> bool

§

fn from_spec(v: T) -> VERUS_SPEC__A

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.

§

impl<T, VERUS_SPEC__A> IntoSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: Into<T>,

§

fn obeys_into_spec() -> bool

§

fn into_spec(self) -> T

§

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

§

fn obeys_into_spec() -> bool

§

fn into_spec(self) -> U

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.
§

impl<T, VERUS_SPEC__A> TryFromSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: TryFrom<T>,

§

fn obeys_try_from_spec() -> bool

§

fn try_from_spec( v: T, ) -> Result<VERUS_SPEC__A, <VERUS_SPEC__A as TryFrom<T>>::Error>

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<T, VERUS_SPEC__A> TryIntoSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: TryInto<T>,

§

fn obeys_try_into_spec() -> bool

§

fn try_into_spec(self) -> Result<T, <VERUS_SPEC__A as TryInto<T>>::Error>

§

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

§

fn obeys_try_into_spec() -> bool

§

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

§

impl<A> SpecEq<&A> for A
where A: ?Sized,

§

impl<A> SpecEq<&mut A> for A
where A: ?Sized,

§

impl<A> SpecEq<A> for A
where A: ?Sized,

§

impl<A> SpecEq<Ghost<A>> for A

§

impl<A> SpecEq<Tracked<A>> for A