pub struct UniqueFrame<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> {
pub ptr: PPtr<MetaSlot>,
pub _marker: PhantomData<M>,
}Fields§
§ptr: PPtr<MetaSlot>§_marker: PhantomData<M>Implementations§
Source§impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> UniqueFrame<M>
impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> UniqueFrame<M>
Sourcepub exec fn from_unused(paddr: Paddr, metadata: M) -> res : Result<Self, GetFrameError>
pub exec fn from_unused(paddr: Paddr, metadata: M) -> res : Result<Self, GetFrameError>
Tracked(regions): Tracked<&mut MetaRegionOwners>,
->
owner: Tracked<Option<UniqueFrameOwner<M>>>,requiresold(regions).slots.contains_key(frame_to_index(paddr)),old(regions).slot_owners.contains_key(frame_to_index(paddr)),old(regions).slot_owners[frame_to_index(paddr)].usage is Unused,old(regions).inv(),ensures!has_safe_slot(paddr) ==> res is Err,res is Ok ==> res.unwrap().wf(owner@.unwrap()),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.
Sourcepub open spec fn transmute_spec<M1: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf>(
self,
transmuted: UniqueFrame<M1>,
) -> bool
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>
}Sourcepub exec fn transmute<M1: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf>(
self,
) -> res : UniqueFrame<M1>
pub exec fn transmute<M1: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf>( self, ) -> res : UniqueFrame<M1>
Self::transmute_spec(self, res),Sourcepub exec fn repurpose<M1: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf>(
self,
metadata: M1,
) -> res : UniqueFrame<M1>
pub exec fn repurpose<M1: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf>( self, metadata: M1, ) -> res : UniqueFrame<M1>
Tracked(owner): Tracked<UniqueFrameOwner<M>>,
Tracked(regions): Tracked<&mut MetaRegionOwners>,
->
new_owner: Tracked<UniqueFrameOwner<M1>>,requiresself.wf(owner),owner.inv(),old(regions).slot_owners.contains_key(frame_to_index(meta_to_frame(self.ptr.addr()))),old(regions)
.slot_owners[frame_to_index(meta_to_frame(self.ptr.addr()))]
.inner_perms
.ref_count
.value() == REF_COUNT_UNIQUE,old(regions).inv(),ensuresres.wf(new_owner@),new_owner@.meta_perm.value().metadata == metadata,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.
Sourcepub exec fn meta<'a>(&self) -> l : &'a M
pub exec fn meta<'a>(&self) -> l : &'a M
Tracked(owner): Tracked<&'a UniqueFrameOwner<M>>,requiresowner.inv(),self.wf(*owner),ensuresowner.meta_perm.mem_contents().value().metadata == l,Gets the metadata of this page.
Note that this function body differs from the original, because as_meta_ptr returns
a ReprPtr<MetaSlot, Metadata<M>> instead of a *M. So in order to keep the immutable borrow, we
borrow the metadata value from that pointer.
§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.
Sourcepub exec fn meta_mut(&mut self) -> res : ReprPtr<MetaSlot, Metadata<M>>
pub exec fn meta_mut(&mut self) -> res : ReprPtr<MetaSlot, Metadata<M>>
Tracked(owner): Tracked<&UniqueFrameOwner<M>>,requiresowner.inv(),old(self).wf(*owner),ensuresres.addr() == self.ptr.addr(),res.ptr.addr() == self.ptr.addr(),*self == *old(self),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>
impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf + ?Sized> UniqueFrame<M>
Sourcepub exec fn start_paddr(&self) -> Paddr
pub exec fn start_paddr(&self) -> Paddr
Tracked(owner): Tracked<&UniqueFrameOwner<M>>,requiresowner.inv(),self.wf(*owner),Gets the physical address of the start of the frame.
Sourcepub const exec fn level(&self) -> PagingLevel
pub const exec fn level(&self) -> PagingLevel
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.
Sourcepub open spec fn into_raw_requires(self, regions: MetaRegionOwners) -> bool
pub open spec fn into_raw_requires(self, regions: MetaRegionOwners) -> bool
{
&&& regions.slot_owners.contains_key(frame_to_index(meta_to_frame(self.ptr.addr())))
&&& regions.slot_owners[frame_to_index(meta_to_frame(self.ptr.addr()))].raw_count
== 0
&&& regions.inv()
}Sourcepub open spec fn into_raw_ensures(
self,
old_regions: MetaRegionOwners,
regions: MetaRegionOwners,
r: Paddr,
) -> bool
pub open spec fn into_raw_ensures( self, old_regions: MetaRegionOwners, regions: MetaRegionOwners, r: Paddr, ) -> bool
{
&&& r == meta_to_frame(self.ptr.addr())
&&& regions.inv()
&&& regions.slots =~= old_regions.slots
&&& regions.slot_owners[frame_to_index(r)].raw_count == 1
&&& forall |i: usize| {
i != frame_to_index(r) ==> regions.slot_owners[i] == old_regions.slot_owners[i]
}
}Trait Implementations§
Source§impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> ModelOf for UniqueFrame<M>
impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> ModelOf for UniqueFrame<M>
Source§impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> OwnerOf for UniqueFrame<M>
impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> OwnerOf for UniqueFrame<M>
Source§impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> TrackDrop for UniqueFrame<M>
impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + OwnerOf> TrackDrop for UniqueFrame<M>
Source§open spec fn constructor_requires(self, s: Self::State) -> bool
open spec fn constructor_requires(self, s: Self::State) -> bool
{
&&& s.slot_owners.contains_key(frame_to_index(meta_to_frame(self.ptr.addr())))
&&& s.slot_owners[frame_to_index(meta_to_frame(self.ptr.addr()))].raw_count == 0
&&& s
.slot_owners[frame_to_index(meta_to_frame(self.ptr.addr()))]
.inner_perms
.ref_count
.value() != REF_COUNT_UNUSED
&&& s.inv()
}Source§open spec fn constructor_ensures(self, s0: Self::State, s1: Self::State) -> bool
open spec fn constructor_ensures(self, s0: Self::State, s1: Self::State) -> bool
{
&&& s1.slot_owners[frame_to_index(meta_to_frame(self.ptr.addr()))].raw_count == 1
&&& forall |i: usize| {
i != frame_to_index(meta_to_frame(self.ptr.addr()))
==> s1.slot_owners[i] == s0.slot_owners[i]
}
&&& s1.slots =~= s0.slots
&&& s1.inv()
}Source§proof fn constructor_spec(self, tracked s: &mut Self::State)
proof fn constructor_spec(self, tracked s: &mut Self::State)
Source§open spec fn drop_requires(self, s: Self::State) -> bool
open spec fn drop_requires(self, s: Self::State) -> bool
{
&&& s.slot_owners.contains_key(frame_to_index(meta_to_frame(self.ptr.addr())))
&&& s.slot_owners[frame_to_index(meta_to_frame(self.ptr.addr()))].raw_count > 0
&&& s.inv()
}Source§open spec fn drop_ensures(self, s0: Self::State, s1: Self::State) -> bool
open spec fn drop_ensures(self, s0: Self::State, s1: Self::State) -> bool
{
&&& s1.slot_owners[frame_to_index(meta_to_frame(self.ptr.addr()))].raw_count == 0
&&& forall |i: usize| {
i != frame_to_index(meta_to_frame(self.ptr.addr()))
==> s1.slot_owners[i] == s0.slot_owners[i]
}
&&& s1.slots =~= s0.slots
&&& s1.inv()
}