Skip to main content

UniqueFrame

Struct UniqueFrame 

Source
pub struct UniqueFrame<M: AnyFrameMeta + ?Sized + Repr<MetaSlotStorage> + OwnerOf> {
    pub ptr: PPtr<MetaSlot>,
    pub _marker: PhantomData<M>,
    pub tracked_slot_perm: Tracked<&'static PointsTo<MetaSlot>>,
    pub tracked_metadata_perm: Tracked<Option<MetadataPerm>>,
}

Fields§

§ptr: PPtr<MetaSlot>§_marker: PhantomData<M>§tracked_slot_perm: Tracked<&'static PointsTo<MetaSlot>>

The permission to access the MetaSlot fields.

§tracked_metadata_perm: Tracked<Option<MetadataPerm>>

The complete permission for the currently installed metadata.

Implementations§

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> UniqueFrame<M>

Source

pub exec fn from_unused(paddr: Paddr, metadata: M) -> res : Result<Self, GetFrameError>

with
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(meta_own_in): Tracked<M::Owner>,
Tracked(repr_perm_in): Tracked<M::ReprPerm>,
->
owner: Tracked<Option<UniqueFrameOwner<M>>>,
requires
old(regions).contains(frame_to_index(paddr)),
old(regions).slot_owner(paddr).usage is Unused,
old(regions).inv(),
<M as OwnerOf>::wf(metadata, meta_own_in),
ensures
res matches Ok(
    res,
) ==> {
    &&& owner@ is Some
    &&& res.wf(owner@->0)
    &&& res.wf_with_region(owner@->0, *final(regions))
    &&& owner@->0.meta_own == meta_own_in
    &&& res.meta_value(owner@->0) == metadata
    &&& res.inv()
    &&& res.start_paddr_spec() == paddr

},
res is Err
    ==> {
        &&& owner@ is None
        &&& *final(regions) == *old(regions)

    },
final(regions).inv(),

Gets a UniqueFrame with a specific usage from a raw, unused page.

The caller should provide the initial metadata of the page.

§Verified Properties
§Preconditions

The page must be unused and the metadata region must be well-formed.

§Postconditions

If the page is valid, the function returns a unique frame.

§Safety

If paddr is misaligned or out of bounds, the function will return an error. If it returns a frame, it also returns an owner for that frame, indicating that the caller now has exclusive ownership of it. See [Safe Encapsulation] for more details.

Source

pub open spec fn transmute_spec<M1: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf>( self, transmuted: UniqueFrame<M1>, ) -> bool

{
    &&& transmuted.ptr.addr() == self.ptr.addr()
    &&& transmuted._marker == PhantomData::<M1>
    &&& transmuted.tracked_slot_perm@ == self.tracked_slot_perm@
    &&& transmuted.tracked_metadata_perm@ == self.tracked_metadata_perm@

}
Source

pub exec fn transmute<M1: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf>( self, ) -> res : UniqueFrame<M1>

ensures
Self::transmute_spec(self, res),
Source

pub exec fn repurpose<M1: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf>( self, metadata: M1, ) -> res : UniqueFrame<M1>

with
Tracked(owner): Tracked<UniqueFrameOwner<M>>,
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(meta_own_in): Tracked<M1::Owner>,
Tracked(repr_perm_in): Tracked<M1::ReprPerm>,
->
new_owner: Tracked<UniqueFrameOwner<M1>>,
requires
self.wf_with_region(owner, *old(regions)),
old(regions).slot_owners[self.index()].in_list_perm.value() == 0,
old(regions).inv(),
self.inv(),
owner.inv(),
<M1 as OwnerOf>::wf(metadata, meta_own_in),
ensures
res.wf(new_owner@),
res.wf_with_region(new_owner@, *final(regions)),
new_owner@.meta_own == meta_own_in,
res.meta_value(new_owner@) == metadata,
final(regions).inv(),

Repurposes the frame with a new metadata.

§Verified Properties
§Preconditions
  • The caller must provide a valid owner for the frame, and the metadata region invariants must hold.
  • The meta slot’s reference count must be REF_COUNT_UNIQUE.
§Postconditions

The function returns a new owner for the frame with the new metadata, and the metadata region invariants are preserved.

§Safety

The existence of a valid owner guarantees that the memory is initialized with metadata of type M, and represents that the caller has exclusive ownership of the frame.

Source

pub exec fn meta<'a>(&'a self) -> l : &'a M

with
Tracked(owner): Tracked<&'a UniqueFrameOwner<M>>,
requires
owner.inv(),
self.inv(),
self.wf(*owner),
self.meta_wf(*owner),
ensures
self.meta_value(*owner) == l,

Gets the metadata of this page.

§Verified Properties
§Preconditions

The caller must provide a valid owner for the frame.

§Postconditions

The function returns the metadata of the frame.

§Safety

The existence of a valid owner guarantees that the memory is initialized with metadata of type M, and represents that the caller has exclusive ownership of the frame.

Source

pub exec fn meta_mut<'a>(&'a mut self) -> res : &'a mut M

with
Tracked(owner): Tracked<&'a mut UniqueFrameOwner<M>>,
requires
old(self).inv(),
old(self).wf(*owner),
old(self).meta_wf(*owner),
owner.inv(),
ensures
*res == old(self).meta_value(*old(owner)),
*final(res) == final(self).meta_value(*final(owner)),
final(self).inv(),
final(self).ptr == old(self).ptr,
final(self).tracked_slot_perm@ == old(self).tracked_slot_perm@,
final(owner).meta_own == old(owner).meta_own,
final(owner).slot_index == old(owner).slot_index,
final(owner).inv(),
final(self).meta_wf(*final(owner)),
(*final(self)).wf(*final(owner)),

Gets the mutable metadata of this page. Verified Properties

§Preconditions

The caller must provide a valid owner for the frame.

§Postconditions

The function returns the mutable metadata of the frame.

§Safety

The existence of a valid owner guarantees that the memory is initialized with metadata of type M, and represents that the caller has exclusive ownership of the frame. (See [Safe Encapsulation])

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf + ?Sized> UniqueFrame<M>

Source

pub const exec fn size(&self) -> usize

returns
PAGE_SIZE,

Gets the size of this page in bytes.

Source

pub const exec fn level(&self) -> PagingLevel

returns
1u8,

Gets the paging level of this page.

This is the level of the page table entry that maps the frame, which determines the size of the frame.

Currently, the level is always 1, which means the frame is a regular page frame.

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf + ?Sized> UniqueFrame<M>

Source

pub exec fn start_paddr(&self) -> Paddr

requires
self.ptr_inv(),
returns
meta_to_frame(self.ptr.addr()),

Gets the physical address of the start of the frame.

Source

pub exec fn reset_as_unused(self)

with
Tracked(owner): Tracked<UniqueFrameOwner<M>>,
Tracked(regions): Tracked<&mut MetaRegionOwners>,
requires
self.inv(),
owner.inv(),
regions.inv(),
self.wf_with_region(owner, *old(regions)),
old(regions).slot_owners[owner.slot_index].in_list_perm.value() == 0,
ensures
final(regions).inv(),

Resets the frame to unused without up-calling the allocator.

This is solely useful for the allocator implementation/testing and is highly experimental. Usage of this function is discouraged.

Usage of this function other than the allocator would actually leak the frame since the allocator would not be aware of the frame.

Source

pub exec fn slot<'a>(&self) -> &'a MetaSlot

requires
self.ptr_inv(),
returns
self.tracked_slot_perm@.value(),
Source§

impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> UniqueFrame<M>

Source

pub exec fn try_from_shared(frame: Frame<M>) -> res : Result<Self, Frame<M>>

with
Tracked(regions): Tracked<&mut MetaRegionOwners>,
requires
frame.inv(),
old(regions).inv(),
frame.wf_with_region(*old(regions)),
ensures
final(regions).slots == old(regions).slots,
final(regions).slot_owners.dom() == old(regions).slot_owners.dom(),

Tries to convert a shared frame into a unique one by CAS’ing ref_count from 1 to REF_COUNT_UNIQUE. Inherent sibling of TryFrom<Frame<M>> for UniqueFrame<M>.

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> UniqueFrame<Link<M>>

{
    &&& self.meta_value(owner).prev is None
    &&& self.meta_value(owner).next is None
    &&& owner.meta_own.paddr == regions.slots[owner.slot_index].addr()
    &&& regions.slot_owners[owner.slot_index].in_list_perm.value() == 0

}
Source§

impl<M: AnyFrameMeta + ?Sized + Repr<MetaSlotStorage> + OwnerOf> UniqueFrame<M>

Source

pub open spec fn start_paddr_spec(self) -> Paddr

{ meta_to_frame(self.ptr.addr()) }
Source

pub open spec fn index(self) -> int

{ frame_to_index(self.start_paddr_spec()) }
Source

pub open spec fn metadata_perm(self) -> MetadataPerm

{ self.tracked_metadata_perm@->0 }

The complete metadata permission carried by this unique handle.

Source

pub open spec fn slot_perm(self) -> PointsTo<MetaSlot>

{ *self.tracked_slot_perm@ }

The metadata-slot permission carried by this unique handle.

Source

pub open spec fn ptr_inv(self) -> bool

{
    &&& valid_frame_paddr(self.start_paddr_spec())
    &&& self.ptr.addr() % META_SLOT_SIZE == 0
    &&& FRAME_METADATA_RANGE.start <= self.ptr.addr()
        < FRAME_METADATA_RANGE.start + MAX_NR_PAGES * META_SLOT_SIZE
    &&& self.slot_perm().pptr() == self.ptr
    &&& self.slot_perm().is_init()

}
Source§

impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> UniqueFrame<M>

Source

pub open spec fn meta_wf(self, owner: UniqueFrameOwner<M>) -> bool

{ typed_meta_wf::<M>(self.slot_perm(), self.metadata_perm(), owner.repr_perm->0) }
Source

pub open spec fn meta_value(self, owner: UniqueFrameOwner<M>) -> M

{ typed_meta_value::<M>(self.metadata_perm(), owner.repr_perm->0) }
Source

pub open spec fn wf_with_region( self, owner: UniqueFrameOwner<M>, s: MetaRegionOwners, ) -> bool

{
    let idx = owner.slot_index;
    let so = s.slot_owners[idx];
    &&& self.wf(owner)
    &&& s.contains(idx)
    &&& self.tracked_slot_perm@ == s.slots[idx]
    &&& self.meta_wf(owner)
    &&& self.meta_value(owner).wf(owner.meta_own)
    &&& so.metadata_perm.is_resource_vacant()
    &&& so.ref_count() == REF_COUNT_UNIQUE
    &&& so.usage is Frame
    &&& so.paths_in_pt.is_empty()

}

Cross-object validity of a live UNIQUE handle against the region map — the UniqueFrame analog of Frame::wf_with_region (which covers the SHARED state).

Trait Implementations§

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> From<UniqueFrame<M>> for Frame<M>

Source§

exec fn from(unique: UniqueFrame<M>) -> Self

Source§

impl<M: AnyFrameMeta + ?Sized + Repr<MetaSlotStorage> + OwnerOf> Inv for UniqueFrame<M>

Source§

open spec fn inv(self) -> bool

{
    &&& self.ptr_inv()
    &&& self.tracked_metadata_perm@ is Some
    &&& MetaSlot::perms_related(self.slot_perm(), self.metadata_perm())

}
Source§

impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> OwnerOf for UniqueFrame<M>

Source§

open spec fn wf(self, owner: Self::Owner) -> bool

{
    &&& self.ptr.addr() == index_to_meta(owner.slot_index)

}
Source§

type Owner = UniqueFrameOwner<M>

The owner of the concrete type. The Owner must implement Inv, indicating that it must has a consistent state.
Source§

impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf + Send> Send for UniqueFrame<M>

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf + Sync> Sync for UniqueFrame<M>

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> TryFrom<Frame<M>> for UniqueFrame<M>

Source§

exec fn try_from(frame: Frame<M>) -> Result<Self, Self::Error>

Tries to get a unique frame from a shared frame.

If the reference count is not 1, the frame is returned back.

Source§

type Error = Frame<M>

The type returned in the event of a conversion error.

Auto Trait Implementations§

§

impl<M> !RefUnwindSafe for UniqueFrame<M>

§

impl<M> !UnwindSafe for UniqueFrame<M>

§

impl<M> Freeze for UniqueFrame<M>

§

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

§

impl<M> UnsafeUnpin for UniqueFrame<M>

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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

§

impl<T> FromSpecImpl<T> for T

§

fn obeys_from_spec() -> bool

§

fn from_spec(v: T) -> T

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

§

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

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

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

§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
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>