Struct frame_allocator::Frames

source ·
pub struct Frames<const S: MemoryState, P: PageSize = Page4K> { /* private fields */ }
Expand description

A range of contiguous frames in physical memory.

Each Frames object is globally unique, meaning that the owner of a Frames object has globally-exclusive access to the range of frames it contains.

A Frames object can be in one of four states:

  • Free: frames are owned by the frame allocator and have not been allocated for any use.
  • Allocated: frames have been removed from the allocator’s free list and are owned elsewhere; they can now be used for mapping purposes.
  • Mapped: frames have been (and are currently) mapped by a range of virtual memory pages.
  • Unmapped: frames have been unmapped and can be returned to the frame allocator.

The drop behavior for a Frames object is based on its state:

  • Free: the frames will be added back to the frame allocator’s free list.
  • Allocated: the frames will be transitioned into the Free state.
  • Unmapped: the frames will be transitioned into the Allocated state.
  • Mapped: currently, Theseus does not actually drop mapped Frames, but rather they are forgotten when they are mapped by virtual pages, and then re-created in the Unmapped state after being unmapped from the page tables.

As such, one can visualize the Frames state diagram as such:

(Free) <---> (Allocated) --> (Mapped) --> (Unmapped) --> (Allocated) <---> (Free)

Ordering and Equality

Frames implements the Ord trait, and its total ordering is ONLY based on its starting Frame. This is useful so we can store Frames in a sorted collection.

Similarly, Frames implements equality traits, Eq and PartialEq, both of which are also based ONLY on the starting Frame of the Frames. Thus, comparing two Frames with the == or != operators may not work as expected. since it ignores their actual range of frames.

Similarly, Frames implements the Borrow trait to return a Frame, not a FrameRange. This is required so we can search for Frames in a sorted collection using a Frame value. It differs from the behavior of the Deref trait which returns a FrameRange.

Implementations§

source§

impl Frames<{MemoryState::Free}, Page4K>

source

pub fn into_allocated_frames(self) -> AllocatedFrames<Page4K>

Consumes this Frames in the Free state and converts them into the Allocated state.

source§

impl<P: PageSize> Frames<{MemoryState::Allocated}, P>

source

pub fn into_mapped_frames(self) -> MappedFrames<P>

Consumes this Frames in the Allocated state and converts them into the Mapped state. This should only be called once a MappedPages has been created from the Frames.

source

pub fn as_allocated_frame(&self) -> AllocatedFrame<'_, P>

Returns an AllocatedFrame if this AllocatedFrames object contains only one frame.

Panic

Panics if this AllocatedFrame contains multiple frames or zero frames.

source§

impl Frames<{MemoryState::Unmapped}, Page4K>

source

pub fn into_allocated_frames(self) -> AllocatedFrames

Consumes this Frames in the Unmapped state and converts them into the Allocated state.

source§

impl<const S: MemoryState, P: PageSize> Frames<S, P>

source

pub const fn empty() -> Frames<S, P>

Returns a new Frames with an empty range of frames. Can be used as a placeholder, but will not permit any real usage.

source

pub fn merge(&mut self, other: Self) -> Result<(), Self>

Merges the given other Frames object into this Frames object (self).

This function performs no allocation or re-mapping, it exists for convenience and usability purposes.

The given other must be physically contiguous with self, i.e., come immediately before or after self. That is, either self.start == other.end + 1 or self.end + 1 == other.start must be true.

If either of those conditions are met, self is modified and Ok(()) is returned, otherwise Err(other) is returned.

source

pub fn split_range( self, frames_to_extract: FrameRange<P> ) -> Result<SplitFrames<S, P>, Self>

Splits up the given Frames into multiple smaller Frames.

Returns a SplitFrames instance containing three Frames:

  1. The range of frames in self that are before the beginning of frames_to_extract.
  2. The Frames containing the requested range of frames, frames_to_extract.
  3. The range of frames in self that are after the end of frames_to_extract.

If frames_to_extract is not contained within self, then self is returned unchanged within an Err.

source

pub fn split_at(self, at_frame: Frame<P>) -> Result<(Self, Self), Self>

Splits this Frames into two separate Frames objects:

  • [beginning : at_frame - 1]
  • [at_frame : end]

This function follows the behavior of core::slice::split_at(), thus, either one of the returned Frames objects may be empty.

  • If at_frame == self.start, the first returned Frames object will be empty.
  • If at_frame == self.end + 1, the second returned Frames object will be empty.

Returns an Err containing this Frames if at_frame is otherwise out of bounds, or if self was empty.

Methods from Deref<Target = FrameRange<P>>§

pub fn start(&self) -> &Frame<P>

Returns the starting [Frame] in this FrameRange.

pub fn end(&self) -> &Frame<P>

Returns the ending [Frame] in this FrameRange.

pub fn start_address(&self) -> PhysicalAddress

Returns the [PhysicalAddress] of the starting [Frame] in this FrameRange.

pub fn size_in_frames(&self) -> usize

Returns the number of [Frame]s covered by this iterator.

Use this instead of Iterator::count() method. This is instant, because it doesn’t need to iterate over each entry, unlike normal iterators.

pub fn size_in_bytes(&self) -> usize

Returns the size of this range in bytes.

pub fn contains_address(&self, addr: PhysicalAddress) -> bool

Returns true if this FrameRange contains the given [PhysicalAddress].

pub fn offset_of_address(&self, addr: PhysicalAddress) -> Option<usize>

Returns the offset of the given [PhysicalAddress] within this FrameRange, i.e., addr - self.start_address().

If the given addr is not covered by this range of [Frame]s, this returns None.

Examples

If the range covers addresses 0x2000 to 0x4000, then offset_of_address(0x3500) would return Some(0x1500).

pub fn address_at_offset(&self, offset: usize) -> Option<PhysicalAddress>

Returns the [PhysicalAddress] at the given offset into this FrameRangewithin this FrameRange, i.e., self.start_address() + offset.

If the given offset is not within this range of [Frame]s, this returns None.

Examples

If the range covers addresses 0x2000 through 0x3FFF, then address_at_offset(0x1500) would return Some(0x3500), and address_at_offset(0x2000) would return None.

pub fn to_extended(&self, to_include: Frame<P>) -> FrameRange<P>

Returns a new separate FrameRange that is extended to include the given [Frame].

pub fn contains_range(&self, other: &FrameRange<P>) -> bool

Returns true if the other FrameRange is fully contained within this FrameRange.

pub fn overlap(&self, other: &FrameRange<P>) -> Option<FrameRange<P>>

Returns an inclusive FrameRange representing the [Frame]s that overlap across this FrameRange and the given other FrameRange.

If there is no overlap between the two ranges, None is returned.

Methods from Deref<Target = RangeInclusive<Frame<P>>>§

source

pub fn start(&self) -> &Idx

Returns the lower bound of the range (inclusive).

source

pub fn end(&self) -> &Idx

Returns the upper bound of the range (inclusive).

source

pub fn is_empty(&self) -> bool

Returns true if the range contains no items.

source

pub fn iter(&self) -> RangeInclusiveIterator<Idx>

Returns an iterator with the same start and end values as the range.

source

pub fn contains<U>(&self, item: &U) -> boolwhere Idx: PartialOrd<U>, U: PartialOrd<Idx> + ?Sized,

Returns true if item is contained in the range.

Trait Implementations§

source§

impl<const S: MemoryState, P: PageSize> Borrow<Frame<P>> for &Frames<S, P>

source§

fn borrow(&self) -> &Frame<P>

Immutably borrows from an owned value. Read more
source§

impl<const S: MemoryState, P: PageSize> Debug for Frames<S, P>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<const S: MemoryState, P: PageSize> Deref for Frames<S, P>

§

type Target = FrameRange<P>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<const S: MemoryState, P: PageSize> Drop for Frames<S, P>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<const S: MemoryState, P: PageSize> Ord for Frames<S, P>

source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere Self: Sized + PartialOrd<Self>,

Restrict a value to a certain interval. Read more
source§

impl<const S: MemoryState, P: PageSize> PartialEq<Frames<S, P>> for Frames<S, P>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<const S: MemoryState, P: PageSize> PartialOrd<Frames<S, P>> for Frames<S, P>

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl<const S: MemoryState, P: Eq + PageSize> Eq for Frames<S, P>

source§

impl<const S: MemoryState, P: PageSize> StructuralEq for Frames<S, P>

Auto Trait Implementations§

§

impl<const S: MemoryState, P> RefUnwindSafe for Frames<S, P>where P: RefUnwindSafe,

§

impl<const S: MemoryState, P> Send for Frames<S, P>where P: Send,

§

impl<const S: MemoryState, P> Sync for Frames<S, P>where P: Sync,

§

impl<const S: MemoryState, P> Unpin for Frames<S, P>where P: Unpin,

§

impl<const S: MemoryState, P> UnwindSafe for Frames<S, P>where P: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere 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.

source§

impl<T, U> Into<U> for Twhere 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.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

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

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

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.