Skip to main content

SegmentOwner

Struct SegmentOwner 

Source
pub struct SegmentOwner<M: AnyFrameMeta + ?Sized> {
    pub range: Range<Paddr>,
    pub perms: Seq<PointsTo<MetaSlot>>,
    pub _marker: PhantomData<M>,
}
Expand description

A SegmentOwner<M> holds the permission tokens for all frames in the Segment<M> for verification purposes.

The range field tracks which physical-address range this owner corresponds to. It is a ghost-only field used by Self::inv to express the structural connection between perms and the segment’s frames.

Fields§

§range: Range<Paddr>

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

§perms: Seq<PointsTo<MetaSlot>>

The slot-pointer permissions for all frames in the segment. Inner permissions for each slot live exclusively in regions.slot_owners[idx].inner_perms; this Seq carries only the simple_pptr::PointsTo<MetaSlot> per frame.

§_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 < self.perms.len() as int
            ==> {
                let idx = frame_to_index((self.range.start + i * PAGE_SIZE) as usize);
                &&& regions.slot_owners.contains_key(idx)
                &&& !regions.slots.contains_key(idx)
                &&& regions.slot_owners[idx].raw_count == 1
                &&& 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
                &&& self.perms[i].value().wf(regions.slot_owners[idx])

            }
    }
    &&& forall |i: int, j: int| {
        0 <= i < j < self.perms.len() as int
            ==> 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 < self.perms.len() as int,
ensures
({
    let idx = frame_to_index((self.range.start + i * PAGE_SIZE) as usize);
    &&& regions.slot_owners.contains_key(idx)
    &&& !regions.slots.contains_key(idx)
    &&& regions.slot_owners[idx].raw_count == 1
    &&& 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
    &&& self.perms[i].value().wf(regions.slot_owners[idx])

}),

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

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
    &&& self.perms.len() * PAGE_SIZE == self.range.end - self.range.start
    &&& forall |i: int| {
        0 <= i < self.perms.len() as int
            ==> {
                &&& self.perms[i].addr()
                    == meta_addr(
                        frame_to_index((self.range.start + i * PAGE_SIZE) as usize),
                    )
                &&& self.perms[i].addr() % META_SLOT_SIZE == 0
                &&& self.perms[i].addr() < FRAME_METADATA_RANGE.end
                &&& self.perms[i].is_init()

            }
    }

}

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.

Auto Trait Implementations§

§

impl<M> Freeze for SegmentOwner<M>

§

impl<M> !RefUnwindSafe for SegmentOwner<M>

§

impl<M> Send for SegmentOwner<M>
where M: Send,

§

impl<M> Sync for SegmentOwner<M>
where M: Sync,

§

impl<M> Unpin for SegmentOwner<M>
where M: Unpin,

§

impl<M> UnsafeUnpin for SegmentOwner<M>

§

impl<M> UnwindSafe for SegmentOwner<M>
where M: UnwindSafe,

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>