pub struct VmWriter<'a, Fallibility = Fallible> { /* private fields */ }
Expand description
VmWriter
is a writer for writing data to a contiguous range of memory.
The memory range write by VmWriter
can be in either kernel space or user space.
When the operating range is in kernel space, the memory within that range
is guaranteed to be valid, and the corresponding memory writes are infallible.
When the operating range is in user space, it is ensured that the page table of
the process creating the VmWriter
is active for the duration of 'a
,
and the corresponding memory writes are considered fallible.
When perform writing with a VmReader
, if one of them represents typed memory,
it can ensure that the writing range in this writer and reading range in the
reader are not overlapped.
NOTE: The overlap mentioned above is at both the virtual address level
and physical address level. There is not guarantee for the operation results
of VmReader
and VmWriter
in overlapping untyped addresses, and it is
the user’s responsibility to handle this situation.
Implementations§
Source§impl<'a> VmWriter<'a, Infallible>
impl<'a> VmWriter<'a, Infallible>
Sourcepub unsafe fn from_kernel_space(ptr: *mut u8, len: usize) -> Self
pub unsafe fn from_kernel_space(ptr: *mut u8, len: usize) -> Self
Sourcepub fn write(&mut self, reader: &mut VmReader<'_, Infallible>) -> usize
pub fn write(&mut self, reader: &mut VmReader<'_, Infallible>) -> usize
Writes all data from the reader until one of the two conditions is met:
- The reader has no remaining data.
- The writer has no available space.
Returns the number of bytes written.
Sourcepub fn write_val<T: Pod>(&mut self, new_val: &T) -> Result<()>
pub fn write_val<T: Pod>(&mut self, new_val: &T) -> Result<()>
Writes a value of Pod
type.
If the length of the Pod
type exceeds self.avail()
,
this method will return Err
.
Sourcepub fn write_once<T: PodOnce>(&mut self, new_val: &T) -> Result<()>
pub fn write_once<T: PodOnce>(&mut self, new_val: &T) -> Result<()>
Writes a value of the PodOnce
type using one non-tearing memory store.
If the length of the PodOnce
type exceeds self.remain()
, this method will return Err
.
§Panics
This method will panic if the current position of the writer does not meet the alignment
requirements of type T
.
Sourcepub fn fill_zeros(&mut self, len: usize) -> usize
pub fn fill_zeros(&mut self, len: usize) -> usize
Writes len
zeros to the target memory.
This method attempts to fill up to len
bytes with zeros. If the available
memory from the current cursor position is less than len
, it will only fill
the available space.
Sourcepub fn to_fallible(self) -> VmWriter<'a, Fallible>
pub fn to_fallible(self) -> VmWriter<'a, Fallible>
Converts to a fallible writer.
Source§impl VmWriter<'_, Fallible>
impl VmWriter<'_, Fallible>
Sourcepub unsafe fn from_user_space(ptr: *mut u8, len: usize) -> Self
pub unsafe fn from_user_space(ptr: *mut u8, len: usize) -> Self
Constructs a VmWriter
from a pointer and a length, which represents
a memory range in user space.
The current context should be consistently associated with valid user space during the
entire lifetime 'a
. This is for correct semantics and is not a safety requirement.
§Safety
ptr
must be in user space for len
bytes.
Sourcepub fn write_val<T: Pod>(&mut self, new_val: &T) -> Result<()>
pub fn write_val<T: Pod>(&mut self, new_val: &T) -> Result<()>
Writes a value of Pod
type.
If the length of the Pod
type exceeds self.avail()
,
or the value can not be write completely,
this method will return Err
.
If the memory write failed, this method will return Err
and the current writer’s cursor remains pointing to
the original starting position.
Sourcepub fn atomic_compare_exchange<T>(
&self,
reader: &VmReader<'_>,
old_val: T,
new_val: T,
) -> Result<(T, bool)>where
T: PodAtomic + Eq,
pub fn atomic_compare_exchange<T>(
&self,
reader: &VmReader<'_>,
old_val: T,
new_val: T,
) -> Result<(T, bool)>where
T: PodAtomic + Eq,
Atomically compares and exchanges a PodAtomic
value.
This method compares old_val
with the value pointed by self
and, if they are equal,
updates it with new_val
.
The value that was previously in memory will be returned, along with a boolean denoting whether the compare-and-exchange succeeds. The caller usually wants to retry if this flag is false, passing the most recent value that was returned by this method.
The caller is required to provide a reader which points to the exact same memory location to ensure that reading from the memory is allowed.
Regardless of whether it is successful, the cursors of the reader and writer will not move.
This method only guarantees the atomicity of the specific operation. There are no synchronization constraints on other memory accesses. This aligns with the Relaxed ordering specified in the C++11 memory model.
Since the operation does not involve memory locks, it can’t prevent the ABA problem.
This method will fail with errors if:
- the remaining space of the reader or the available space of the writer are less than
size_of::<T>()
bytes, or - the memory operation fails due to an unresolvable page fault.
§Panics
This method will panic if:
- the reader and the writer does not point to the same memory location, or
- the memory location is not aligned on an
align_of::<T>()
-byte boundary.
Sourcepub fn fill_zeros(&mut self, len: usize) -> Result<usize, (Error, usize)>
pub fn fill_zeros(&mut self, len: usize) -> Result<usize, (Error, usize)>
Writes len
zeros to the target memory.
This method attempts to fill up to len
bytes with zeros. If the available
memory from the current cursor position is less than len
, it will only fill
the available space.
If the memory write failed due to an unresolvable page fault, this method
will return Err
with the length set so far.
Source§impl<Fallibility> VmWriter<'_, Fallibility>
impl<Fallibility> VmWriter<'_, Fallibility>
Trait Implementations§
Source§impl<'a> FallibleVmWrite<Fallible> for VmWriter<'a, Infallible>
impl<'a> FallibleVmWrite<Fallible> for VmWriter<'a, Infallible>
Source§impl<'a> FallibleVmWrite<Infallible> for VmWriter<'a, Fallible>
impl<'a> FallibleVmWrite<Infallible> for VmWriter<'a, Fallible>
Source§fn write_fallible(
&mut self,
reader: &mut VmReader<'_, Infallible>,
) -> Result<usize, (Error, usize)>
fn write_fallible( &mut self, reader: &mut VmReader<'_, Infallible>, ) -> Result<usize, (Error, usize)>
Auto Trait Implementations§
impl<'a, Fallibility> Freeze for VmWriter<'a, Fallibility>
impl<'a, Fallibility> RefUnwindSafe for VmWriter<'a, Fallibility>where
Fallibility: RefUnwindSafe,
impl<'a, Fallibility = Fallible> !Send for VmWriter<'a, Fallibility>
impl<'a, Fallibility = Fallible> !Sync for VmWriter<'a, Fallibility>
impl<'a, Fallibility> Unpin for VmWriter<'a, Fallibility>where
Fallibility: Unpin,
impl<'a, Fallibility = Fallible> !UnwindSafe for VmWriter<'a, Fallibility>
Blanket Implementations§
§impl<T> Any for Twhere
T: 'static + ?Sized,
impl<T> Any for Twhere
T: 'static + ?Sized,
§impl<T> Borrow<T> for Twhere
T: ?Sized,
impl<T> Borrow<T> for Twhere
T: ?Sized,
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.Source§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.§impl<T, U> Into<U> for Twhere
U: From<T>,
impl<T, U> Into<U> for Twhere
U: From<T>,
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§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 moreSource§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 moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
self
, then passes self.as_ref()
into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
self
, then passes self.as_mut()
into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere
Self: Deref<Target = T>,
T: 'a + ?Sized,
R: 'a,
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere
Self: Deref<Target = T>,
T: 'a + ?Sized,
R: 'a,
self
, then passes self.deref()
into the pipe function.Source§fn pipe_deref_mut<'a, T, R>(
&'a mut self,
func: impl FnOnce(&'a mut T) -> R,
) -> Rwhere
Self: DerefMut<Target = T> + Deref,
T: 'a + ?Sized,
R: 'a,
fn pipe_deref_mut<'a, T, R>(
&'a mut self,
func: impl FnOnce(&'a mut T) -> R,
) -> Rwhere
Self: DerefMut<Target = T> + Deref,
T: 'a + ?Sized,
R: 'a,
self
, then passes self.deref_mut()
into the pipe
function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
Borrow<B>
of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
BorrowMut<B>
of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
AsRef<R>
view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
AsMut<R>
view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
Deref::Target
of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
Deref::Target
of a value. Read moreSource§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.Source§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.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
.tap_borrow()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
.tap_ref()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
.tap_ref_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
.tap_deref()
only in debug builds, and is erased in release
builds.Source§fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
.tap_deref_mut()
only in debug builds, and is erased in release
builds.