#[repr(C)]pub(in mm) struct MetaSlot {
storage: UnsafeCell<[u8; 40]>,
pub(super) ref_count: AtomicU64,
pub(super) vtable_ptr: UnsafeCell<MaybeUninit<DynMetadata<dyn AnyFrameMeta>>>,
pub(super) in_list: AtomicU64,
}
Fields§
§storage: UnsafeCell<[u8; 40]>
The metadata of a frame.
It is placed at the beginning of a slot because:
- the implementation can simply cast a
*const MetaSlot
to a*const AnyFrameMeta
for manipulation; - if the metadata need special alignment, we can provide
at most
PAGE_METADATA_ALIGN
bytes of alignment; - the subsequent fields can utilize the padding of the reference count to save space.
Don’t interpret this field as an array of bytes. It is a placeholder for the metadata of a frame.
ref_count: AtomicU64
The reference count of the page.
Specifically, the reference count has the following meaning:
REF_COUNT_UNUSED
: The page is not in use.REF_COUNT_UNIQUE
: The page is owned by aUniqueFrame
.0
: The page is being constructed (Frame::from_unused
) or destructured (drop_last_in_place
).1..REF_COUNT_MAX
: The page is in use.REF_COUNT_MAX..REF_COUNT_UNIQUE
: Illegal values to prevent the reference count from overflowing. Otherwise, overflowing the reference count will cause soundness issue.
vtable_ptr: UnsafeCell<MaybeUninit<DynMetadata<dyn AnyFrameMeta>>>
The virtual table that indicates the type of the metadata.
in_list: AtomicU64
This is only accessed by crate::mm::frame::linked_list
.
It stores 0 if the frame is not in any list, otherwise it stores the
ID of the list.
It is ugly but allows us to tell if a frame is in a specific list by
one relaxed read. Otherwise, if we store it conditionally in storage
we would have to ensure that the type is correct before the read, which
costs a synchronization.
Implementations§
Source§impl MetaSlot
impl MetaSlot
Sourcepub(super) fn get_from_unused<M: AnyFrameMeta>(
paddr: Paddr,
metadata: M,
as_unique_ptr: bool,
) -> Result<*const Self, GetFrameError>
pub(super) fn get_from_unused<M: AnyFrameMeta>( paddr: Paddr, metadata: M, as_unique_ptr: bool, ) -> Result<*const Self, GetFrameError>
Initializes the metadata slot of a frame assuming it is unused.
If successful, the function returns a pointer to the metadata slot. And the slot is initialized with the given metadata.
The resulting reference count held by the returned pointer is
REF_COUNT_UNIQUE
if as_unique_ptr
is true
, otherwise 1
.
Sourcepub(super) fn get_from_in_use(
paddr: Paddr,
) -> Result<*const Self, GetFrameError>
pub(super) fn get_from_in_use( paddr: Paddr, ) -> Result<*const Self, GetFrameError>
Gets another owning pointer to the metadata slot from the given page.
Sourcepub(super) unsafe fn inc_ref_count(&self)
pub(super) unsafe fn inc_ref_count(&self)
Increases the frame reference count by one. For a frame derived from Self
- The caller must have already held a reference to the frame.
Sourcepub(super) fn frame_paddr(&self) -> Paddr
pub(super) fn frame_paddr(&self) -> Paddr
Gets the corresponding frame’s physical address.
Sourcepub(super) unsafe fn dyn_meta_ptr(&self) -> *mut dyn AnyFrameMeta
pub(super) unsafe fn dyn_meta_ptr(&self) -> *mut dyn AnyFrameMeta
Gets a dynamically typed pointer to the stored metadata.
-
The stored metadata should be validly derived from Self :: write_meta.
-
mutating through the returned pointer should have exclusive mutable access to The metadata slot.
Sourcepub(super) fn as_meta_ptr<M: AnyFrameMeta>(&self) -> *mut M
pub(super) fn as_meta_ptr<M: AnyFrameMeta>(&self) -> *mut M
Gets the stored metadata as type M
.
Calling the method should be safe, but using the returned pointer would be unsafe. Specifically, the derefernecer should ensure that:
- the stored metadata is initialized (by
Self::write_meta
) and valid; - the initialized metadata is of type
M
; - the returned pointer should not be dereferenced as mutable unless having exclusive access to the metadata slot.
Sourcepub(super) unsafe fn write_meta<M: AnyFrameMeta>(&self, metadata: M)
pub(super) unsafe fn write_meta<M: AnyFrameMeta>(&self, metadata: M)
Writes the metadata to the slot without reading or dropping the previous value.
-
should have exclusive mutable access to self.vtable_ptr.
-
should have exclusive mutable access to self.storage.
Sourcepub(super) unsafe fn drop_last_in_place(&self)
pub(super) unsafe fn drop_last_in_place(&self)
Drops the metadata and deallocates the frame.
-
self.ref_count should equal to 0.
-
the meta data should be validly derived from Self :: write_meta.
Sourcepub(super) unsafe fn drop_meta_in_place(&self)
pub(super) unsafe fn drop_meta_in_place(&self)
Drops the metadata of a slot in place.
After this operation, the metadata becomes uninitialized. Any access to the
metadata is undefined behavior unless it is re-initialized by Self::write_meta
.
-
self.ref_count should equal to 0.
-
the meta data should be validly derived from Self :: write_meta.
Auto Trait Implementations§
impl !Freeze for MetaSlot
impl !RefUnwindSafe for MetaSlot
impl Send for MetaSlot
impl !Sync for MetaSlot
impl Unpin for MetaSlot
impl !UnwindSafe for MetaSlot
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
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) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
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
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
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
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
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
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Pointee for T
impl<T> Pointee for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.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
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.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
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.