Struct VolatileRef

Source
pub struct VolatileRef<'a, T, A = ReadWrite>
where T: ?Sized,
{ /* private fields */ }
Expand description

Volatile pointer type that respects Rust’s aliasing rules.

This pointer type behaves similar to Rust’s reference types:

  • it requires exclusive &mut self access for mutability
  • only read-only types implement Clone and Copy
  • Send and Sync are implemented if T: Sync

However, trait implementations like fmt::Debug and Eq behave like they do on pointer types and don’t access the referenced value.

To perform volatile operations on VolatileRef types, use the as_ptr or as_mut_ptr methods to create a temporary VolatilePtr instance.

Since not all volatile resources (e.g. memory mapped device registers) are both readable and writable, this type supports limiting the allowed access types through an optional second generic parameter A that can be one of ReadWrite, ReadOnly, or WriteOnly. It defaults to ReadWrite, which allows all operations.

The size of this struct is the same as the size of the contained reference.

Implementations§

Source§

impl<'a, T> VolatileRef<'a, T>
where T: ?Sized,

Constructor functions.

These functions construct new VolatileRef values. While the new function creates a VolatileRef instance with unrestricted access, there are also functions for creating read-only or write-only instances.

Source

pub unsafe fn new(pointer: NonNull<T>) -> Self

Turns the given pointer into a VolatileRef.

§Safety
  • The pointer must be properly aligned.
  • It must be “dereferenceable” in the sense defined in the core::ptr documentation.
  • The pointer must point to an initialized instance of T.
  • You must enforce Rust’s aliasing rules, since the returned lifetime ’a is arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. In particular, while this VolatileRef exists, the memory the pointer points to must not get accessed (read or written) through any other pointer.
Source

pub const unsafe fn new_read_only( pointer: NonNull<T>, ) -> VolatileRef<'a, T, ReadOnly>

Turns the given pointer into a read-only VolatileRef.

§Safety
  • The pointer must be properly aligned.
  • It must be “dereferenceable” in the sense defined in the core::ptr documentation.
  • The pointer must point to an initialized instance of T.
  • You must enforce Rust’s aliasing rules, since the returned lifetime ’a is arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. In particular, while this VolatileRef exists, the memory the pointer points to must not get mutated.
Source

pub const unsafe fn new_restricted<A>( access: A, pointer: NonNull<T>, ) -> VolatileRef<'a, T, A>
where A: Access,

Turns the given pointer into a VolatileRef instance with the given access.

§Safety
  • The pointer must be properly aligned.
  • It must be “dereferenceable” in the sense defined in the core::ptr documentation.
  • The pointer must point to an initialized instance of T.
  • You must enforce Rust’s aliasing rules, since the returned lifetime ’a is arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. In particular, while this VolatileRef exists, the memory the pointer points to must not get mutated. If the given access parameter allows write access, the pointer must not get read either while this VolatileRef exists.
Source

pub fn from_ref(reference: &'a T) -> VolatileRef<'a, T, ReadOnly>
where T: 'a,

Creates a VolatileRef from the given shared reference.

Note: This function is only intended for testing, not for accessing real volatile data. The reason is that the &mut T argument is considered dereferenceable by Rust, so the compiler is allowed to insert non-volatile reads. This might lead to undesired (or even undefined?) behavior when accessing volatile data. So to be safe, only create raw pointers to volatile data and use the Self::new constructor instead.

Source

pub fn from_mut_ref(reference: &'a mut T) -> Self
where T: 'a,

Creates a VolatileRef from the given mutable reference.

Note: This function is only intended for testing, not for accessing real volatile data. The reason is that the &mut T argument is considered dereferenceable by Rust, so the compiler is allowed to insert non-volatile reads. This might lead to undesired (or even undefined?) behavior when accessing volatile data. So to be safe, only create raw pointers to volatile data and use the Self::new constructor instead.

Source§

impl<'a, T, A> VolatileRef<'a, T, A>
where T: ?Sized,

Source

pub fn borrow(&self) -> VolatileRef<'_, T, A::Restricted>

Immutably borrows from this VolatileRef.

This method creates a VolatileRef tied to the lifetime of the &VolatileRef it is created from. This is useful for providing a volatile reference without moving the original VolatileRef. In comparison with creating a &VolatileRef<'a, T>, this avoids the additional indirection and lifetime.

Source

pub fn borrow_mut(&mut self) -> VolatileRef<'_, T, A>
where A: Access,

Mutably borrows from this VolatileRef.

This method creates a VolatileRef tied to the lifetime of the &mut VolatileRef it is created from. This is useful for providing a volatile reference without moving the original VolatileRef. In comparison with creating a &mut VolatileRef<'a, T>, this avoids the additional indirection and lifetime.

Source

pub fn as_ptr(&self) -> VolatilePtr<'_, T, A::Restricted>

Borrows this VolatileRef as a read-only VolatilePtr.

Use this method to do (partial) volatile reads of the referenced data.

Source

pub fn as_mut_ptr(&mut self) -> VolatilePtr<'_, T, A>
where A: Access,

Borrows this VolatileRef as a mutable VolatilePtr.

Use this method to do (partial) volatile reads or writes of the referenced data.

Source

pub fn into_ptr(self) -> VolatilePtr<'a, T, A>
where A: Access,

Converts this VolatileRef into a VolatilePtr with full access without shortening the lifetime.

Use this method when you need a VolatilePtr instance that lives for the full lifetime 'a.

This method consumes the VolatileRef.

Source§

impl<'a, T, A> VolatileRef<'a, T, A>
where T: ?Sized,

Methods for restricting access.

Source

pub fn restrict<To>(self) -> VolatileRef<'a, T, A::Restricted>
where A: RestrictAccess<To>,

Restricts access permissions to A.

§Example
use volatile::access::{ReadOnly, WriteOnly};
use volatile::VolatileRef;

let mut value: i16 = -4;
let volatile = VolatileRef::from_mut_ref(&mut value);

let read_only = volatile.restrict::<ReadOnly>();
assert_eq!(read_only.as_ptr().read(), -4);
// read_only.as_ptr().write(10); // compile-time error

let no_access = read_only.restrict::<WriteOnly>();
// no_access.read(); // compile-time error
// no_access.write(10); // compile-time error
Source§

impl<'a, T> VolatileRef<'a, T, ReadWrite>
where T: ?Sized,

Methods for restricting access.

Source

pub fn read_only(self) -> VolatileRef<'a, T, ReadOnly>

Restricts access permissions to read-only.

§Example
use volatile::VolatileRef;

let mut value: i16 = -4;
let volatile = VolatileRef::from_mut_ref(&mut value);

let read_only = volatile.read_only();
assert_eq!(read_only.as_ptr().read(), -4);
// read_only.as_ptr().write(10); // compile-time error
Source

pub fn write_only(self) -> VolatileRef<'a, T, WriteOnly>

Restricts access permissions to write-only.

§Example

Creating a write-only reference to a struct field:

use volatile::{VolatileRef};

#[derive(Clone, Copy)]
struct Example { field_1: u32, field_2: u8, }
let mut value = Example { field_1: 15, field_2: 255 };
let volatile = VolatileRef::from_mut_ref(&mut value);

let write_only = volatile.write_only();
// write_only.as_ptr().read(); // compile-time error

Trait Implementations§

Source§

impl<'a, T, A> Clone for VolatileRef<'a, T, A>
where T: ?Sized, A: Access + Copyable,

Source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T, A> Debug for VolatileRef<'_, T, A>
where T: ?Sized,

Source§

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

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

impl<T, A> Hash for VolatileRef<'_, T, A>
where T: ?Sized,

Source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<T, A> Ord for VolatileRef<'_, T, A>
where T: ?Sized,

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) -> Self
where Self: Sized,

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

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

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

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

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

impl<T, A> PartialEq for VolatileRef<'_, T, A>
where T: ?Sized,

Source§

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

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

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

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T, A> PartialOrd for VolatileRef<'_, T, A>
where T: ?Sized,

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

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

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

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

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<T, A> Pointer for VolatileRef<'_, T, A>
where T: ?Sized,

Source§

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

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

impl<'a, T, A> Copy for VolatileRef<'a, T, A>
where T: ?Sized, A: Access + Copyable,

Source§

impl<T, A> Eq for VolatileRef<'_, T, A>
where T: ?Sized,

Source§

impl<T, A> Send for VolatileRef<'_, T, A>
where T: Sync + ?Sized,

Source§

impl<T, A> Sync for VolatileRef<'_, T, A>
where T: Sync + ?Sized,

Auto Trait Implementations§

§

impl<'a, T, A> Freeze for VolatileRef<'a, T, A>
where T: ?Sized,

§

impl<'a, T, A> RefUnwindSafe for VolatileRef<'a, T, A>

§

impl<'a, T, A> Unpin for VolatileRef<'a, T, A>
where A: Unpin, T: ?Sized,

§

impl<'a, T, A> UnwindSafe for VolatileRef<'a, T, A>
where T: RefUnwindSafe + ?Sized, A: UnwindSafe,

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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 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.

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