Cursor

Struct Cursor 

Source
pub struct Cursor<'a, A: InAtomicMode>(pub Cursor<'a, UserPtConfig, A>);
Expand description

The cursor for querying over the VM space without modifying it.

It exclusively owns a sub-tree of the page table, preventing others from reading or modifying the same sub-tree. Two read-only cursors can not be created from the same virtual address range either.

Tuple Fields§

§0: Cursor<'a, UserPtConfig, A>

Implementations§

Source§

impl<'rcu, A: InAtomicMode> Cursor<'rcu, A>

Source

pub open spec fn invariants( self, owner: CursorOwner<'rcu, UserPtConfig>, regions: MetaRegionOwners, guards: Guards<'rcu, UserPtConfig>, ) -> bool

{
    &&& self.0.inv()
    &&& self.0.wf(owner)
    &&& owner.inv()
    &&& regions.inv()
    &&& owner.children_not_locked(guards)
    &&& owner.nodes_locked(guards)
    &&& owner.relate_region(regions)
    &&& !owner.popped_too_high

}
Source

pub open spec fn query_success_requires(self) -> bool

{ self.0.barrier_va.start <= self.0.va < self.0.barrier_va.end }
Source

pub open spec fn query_success_ensures( self, view: CursorView<UserPtConfig>, range: Range<Vaddr>, item: Option<MappedItem>, ) -> bool

{
    if view.present() {
        let found_item = view.query_item_spec();
        &&& range.start == found_item.va_range.start
        &&& range.end == found_item.va_range.end
        &&& item is Some
        &&& meta_to_frame(item.unwrap().frame.ptr.addr()) == found_item.pa_range.start

    } else {
        &&& range.start == self.0.va
        &&& item is None

    }
}
Source

pub exec fn query(&mut self) -> r : Result<(Range<Vaddr>, Option<MappedItem>), Error>

with
Tracked(owner): Tracked <& mut CursorOwner <'rcu,UserPtConfig>>,
Tracked(regions): Tracked <& mut MetaRegionOwners>,
Tracked(guards): Tracked <& mut Guards <'rcu,UserPtConfig>>,
requires
old(self).invariants(*old(owner), *old(regions), *old(guards)),
ensures
self.invariants(*owner, *regions, *guards),
self.query_success_requires()
    ==> {
        &&& r is Ok
        &&& self.query_success_ensures(self.0.model(*owner), r.unwrap().0, r.unwrap().1)

    },

Queries the mapping at the current virtual address.

If the cursor is pointing to a valid virtual address that is locked, it will return the virtual address range and the mapped item.

§Preconditions

In addition to the standard well-formedness conditions, the function will give an error if the cursor is outside of the locked range.

§Postconditions

If the cursor is valid, the result of the lookup is given by query_success_ensures. The mapping that is returned corresponds to the abstract mapping given by query_item_spec.

Source

pub exec fn find_next(&mut self, len: usize) -> res : Option<Vaddr>

with
Tracked(owner): Tracked <& mut CursorOwner <'rcu,UserPtConfig>>,
Tracked(regions): Tracked <& mut MetaRegionOwners>,
Tracked(guards): Tracked <& mut Guards <'rcu,UserPtConfig>>,
requires
old(owner).inv(),
old(self).0.wf(*old(owner)),
old(regions).inv(),
old(self).0.level < old(self).0.guard_level,
old(self).0.inv(),
old(owner).in_locked_range(),
old(owner).children_not_locked(*old(guards)),
old(owner).nodes_locked(*old(guards)),
old(owner).relate_region(*old(regions)),
!old(owner).popped_too_high,
len % PAGE_SIZE() == 0,
old(self).0.va + len <= old(self).0.barrier_va.end,
ensures
owner.inv(),
self.0.wf(*owner),
regions.inv(),

Moves the cursor forward to the next mapped virtual address.

If there is mapped virtual address following the current address within next len bytes, it will return that mapped address. In this case, the cursor will stop at the mapped address.

Otherwise, it will return None. And the cursor may stop at any address after len bytes.

§Panics

Panics if the length is longer than the remaining range of the cursor.

Source

pub exec fn jump(&mut self, va: Vaddr) -> Result<(), Error>

with
Tracked(owner): Tracked <& mut CursorOwner <'rcu,UserPtConfig>>,
Tracked(regions): Tracked <& mut MetaRegionOwners>,
Tracked(guards): Tracked <& mut Guards <'rcu,UserPtConfig>>,
requires
old(owner).inv(),
old(self).0.wf(*old(owner)),
old(self).0.level < old(self).0.guard_level,
old(self).0.inv(),
old(owner).in_locked_range(),
old(owner).children_not_locked(*old(guards)),
old(owner).nodes_locked(*old(guards)),
old(owner).relate_region(*old(regions)),

Jump to the virtual address.

Source

pub exec fn virt_addr(&self) -> Vaddr

Get the virtual address of the current slot.

Auto Trait Implementations§

§

impl<'a, A> Freeze for Cursor<'a, A>

§

impl<'a, A> !RefUnwindSafe for Cursor<'a, A>

§

impl<'a, A> Send for Cursor<'a, A>
where A: Sync,

§

impl<'a, A> Sync for Cursor<'a, A>
where A: Sync,

§

impl<'a, A> Unpin for Cursor<'a, A>

§

impl<'a, A> !UnwindSafe for Cursor<'a, A>

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>