Struct voladdress::VolAddress

source ·
pub struct VolAddress<T, R, W> { /* private fields */ }
Expand description

A volatile address.

This type stores a memory address and provides ergonomic volatile access to said memory address.

Note that this type has several methods for accessing the data at the address specified, and a particular instance of this type can use them unsafely, use them safely, or not use them at all based on the generic values of R and W (explained below).

  • read
  • write
  • apply (reads, runs a function, then writes)

§Generic Parameters

  • T: The type of the value stored at the address.
    • The target type type must impl Copy for reading and writing to be allowed.
  • R: If the address is readable.
    • If R=Safe then you can safely read from the address.
    • If R=Unsafe then you can unsafely read from the address.
    • Otherwise you cannot read from the address.
  • W: If the address is writable.
    • If W=Safe then you can safely write to the address.
    • If W=Unsafe then you can unsafely write to the address.
    • Otherwise you cannot write to the address.

The VolAddress type is intended to represent a single value of a T type that is the size of a single machine register (or less).

  • If there’s an array of contiguous T values you want to model, consider using VolBlock instead.
  • If there’s a series of strided T values you want to model, consider using VolSeries instead.
  • If the T type is larger than a single machine register it’s probably not a good fit for the VolAddress abstraction.

§Safety

This type’s safety follows the “unsafe creation, then safe use” strategy.

  • Validity Invariant: The address of a VolAddress must always be non-zero, or you will instantly trigger UB.
  • Safety Invariant: The address of a VolAddress must be an aligned and legal address for a T type value (with correct R and W permissions) within the device’s memory space, otherwise the read and write methods will trigger UB when called.
  • Synchronization Invariant: Volatile access has no cross-thread synchronization behavior within the LLVM memory model. The results of all volatile access is target-dependent, including cross-thread access. Volatile access has no automatic synchronization of its own, and so if your target requires some sort of synchronization for volatile accesses of the address in question you must provide the appropriate synchronization in some way external to this type.

Implementations§

source§

impl<T, R, W> VolAddress<T, R, W>

source

pub const unsafe fn new(address: usize) -> Self

Constructs the value.

§Safety
  • As per the type docs.
source

pub const unsafe fn cast<Z>(self) -> VolAddress<Z, R, W>

Changes the target type from T to Z.

§Safety
  • As per the type docs
source

pub const unsafe fn change_permissions<NewRead, NewWrite>( self ) -> VolAddress<T, NewRead, NewWrite>

Changes the permissions of the address to the new read and write permissions specified.

§Safety
  • As per the type docs
source

pub const fn as_usize(self) -> usize

Converts the VolAddress back into a normal usize value.

source

pub const fn as_ptr(self) -> *const T

Converts the VolAddress into const pointer form.

This should usually only be used when you need to call a foreign function that expects a pointer.

source

pub const fn as_mut_ptr(self) -> *mut T

Converts the VolAddress into mut pointer form.

This should usually only be used when you need to call a foreign function that expects a pointer.

source

pub const unsafe fn add(self, count: usize) -> Self

Advances the pointer by the given number of positions (usize).

Shorthand for addr.offset(count as isize)

This is intended to basically work like <*mut T>::wrapping_add.

§Safety
  • As per the type docs
source

pub const unsafe fn sub(self, count: usize) -> Self

Reverses the pointer by the given number of positions (usize).

Shorthand for addr.offset((count as isize).wrapping_neg())

This is intended to basically work like <*mut T>::wrapping_sub.

§Safety
  • As per the type docs
source

pub const unsafe fn offset(self, count: isize) -> Self

Offsets the address by the given number of positions (isize).

This is intended to basically work like <*mut T>::wrapping_offset.

§Safety
  • As per the type docs
source§

impl<T, R, W, const C: usize> VolAddress<[T; C], R, W>

source

pub const unsafe fn as_volblock(self) -> VolBlock<T, R, W, C>

Converts an address for an array to a block for each element of the array.

§Safety
  • As per the VolBlock construction rules.
  • It is highly likely that on any device this is safe, but because of possible strangeness with volatile side effects this is marked as an unsafe method.
source§

impl<T, W> VolAddress<T, Safe, W>
where T: Copy,

source

pub fn read(self) -> T

Volatile reads the current value of A.

source§

impl<T, W> VolAddress<T, Unsafe, W>
where T: Copy,

source

pub unsafe fn read(self) -> T

Volatile reads the current value of A.

§Safety
  • The safety rules of reading this address depend on the device. Consult your hardware manual.
source§

impl<T, R> VolAddress<T, R, Safe>
where T: Copy,

source

pub fn write(self, t: T)

Volatile writes a new value to A.

source§

impl<T, R> VolAddress<T, R, Unsafe>
where T: Copy,

source

pub unsafe fn write(self, t: T)

Volatile writes a new value to A.

§Safety
  • The safety rules of writing this address depend on the device. Consult your hardware manual.
source§

impl<T> VolAddress<T, Safe, Safe>
where T: Copy,

source

pub fn apply<F: FnOnce(&mut T)>(self, op: F)

Reads the address, applies the operation, and writes back the new value.

source§

impl<T> VolAddress<T, Unsafe, Safe>
where T: Copy,

source

pub unsafe fn apply<F: FnOnce(&mut T)>(self, op: F)

Reads the address, applies the operation, and writes back the new value.

§Safety
  • The safety rules of reading/writing this address depend on the device. Consult your hardware manual.
source§

impl<T> VolAddress<T, Safe, Unsafe>
where T: Copy,

source

pub unsafe fn apply<F: FnOnce(&mut T)>(self, op: F)

Reads the address, applies the operation, and writes back the new value.

§Safety
  • The safety rules of reading/writing this address depend on the device. Consult your hardware manual.
source§

impl<T> VolAddress<T, Unsafe, Unsafe>
where T: Copy,

source

pub unsafe fn apply<F: FnOnce(&mut T)>(self, op: F)

Reads the address, applies the operation, and writes back the new value.

§Safety
  • The safety rules of reading/writing this address depend on the device. Consult your hardware manual.

Trait Implementations§

source§

impl<T, R, W> Clone for VolAddress<T, R, W>

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, R, W> Debug for VolAddress<T, R, W>

source§

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

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

impl<T: Hash, R: Hash, W: Hash> Hash for VolAddress<T, R, W>

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: Ord, R: Ord, W: Ord> Ord for VolAddress<T, R, W>

source§

fn cmp(&self, other: &VolAddress<T, R, W>) -> 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 + PartialOrd,

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

impl<T: PartialEq, R: PartialEq, W: PartialEq> PartialEq for VolAddress<T, R, W>

source§

fn eq(&self, other: &VolAddress<T, R, W>) -> 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<T: PartialOrd, R: PartialOrd, W: PartialOrd> PartialOrd for VolAddress<T, R, W>

source§

fn partial_cmp(&self, other: &VolAddress<T, R, W>) -> 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<T, R, W> Pointer for VolAddress<T, R, W>

source§

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

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

impl<T, R, W> Copy for VolAddress<T, R, W>

source§

impl<T: Eq, R: Eq, W: Eq> Eq for VolAddress<T, R, W>

source§

impl<T, R, W> StructuralPartialEq for VolAddress<T, R, W>

Auto Trait Implementations§

§

impl<T, R, W> Freeze for VolAddress<T, R, W>

§

impl<T, R, W> RefUnwindSafe for VolAddress<T, R, W>

§

impl<T, R, W> Send for VolAddress<T, R, W>
where T: Send, R: Send, W: Send,

§

impl<T, R, W> Sync for VolAddress<T, R, W>
where T: Sync, R: Sync, W: Sync,

§

impl<T, R, W> Unpin for VolAddress<T, R, W>
where T: Unpin, R: Unpin, W: Unpin,

§

impl<T, R, W> UnwindSafe for VolAddress<T, R, W>
where T: UnwindSafe, R: UnwindSafe, W: 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> 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>,

§

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

§

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.