8000 Rewrite crate to operate on reference values by phil-opp · Pull Request #13 · rust-osdev/volatile · GitHub
[go: up one dir, main page]

Skip to content

Rewrite crate to operate on reference values #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Sep 21, 2020
Merged
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
277b25b
Different rewrite approaches
phil-opp Jul 29, 2020
93fb1e1
Decide for foo.rs approach
phil-opp Jul 29, 2020
8be4430
Update documentation
phil-opp Jul 29, 2020
401a86b
Remove const_fn cargo feature
phil-opp Jul 29, 2020
59dd91d
Reorganize access module and make it public
phil-opp Jul 29, 2020
53fd257
Add constructor methods for read/write-only types
phil-opp Jul 29, 2020
b469f42
Make methods generic using `Deref` trait
phil-opp Jul 29, 2020
d0bcea2
Add methods for working with volatile slices
phil-opp Jul 29, 2020
1b4931d
Document `copy_into_slice` method
phil-opp Jul 29, 2020
4766a43
Add `as_slice`/`as_mut_slice` methods for volatile array references
phil-opp Jul 30, 2020
cfbd66e
Rename the 'nightly' feature to 'unstable'
phil-opp Jul 31, 2020
bf8031c
Document constructor functions
phil-opp Jul 31, 2020
93e7150
Provide a custom fmt::Debug implementation to prevent reading of writ…
phil-opp Jul 31, 2020
8682a86
Improve documentation of `Volatile::new`
phil-opp Jul 31, 2020
46a7603
Warn on missing documentation
phil-opp Jul 31, 2020
7dffe2c
Improve documentation
phil-opp Aug 19, 2020
dfbaa68
Run cargo fmt
phil-opp Aug 19, 2020
76e7657
Don't derive Default
phil-opp Aug 19, 2020
4ba88d3
Add `map`/`map_mut`/`extract_inner` methods
phil-opp Aug 19, 2020
fb7e6a5
Use map/map_mut for index/index_mut implementation
phil-opp Aug 19, 2020
a78fd04
Use map/map_mut for array to slice conversion methods
phil-opp Aug 19, 2020
eabda2e
Add documentation for slice index methods
phil-opp Aug 19, 2020
2e272d6
Fix typo in docs
phil-opp Aug 19, 2020
d120638
Change order of impl blocks to show `read`/`write` methods first in docs
phil-opp Aug 19, 2020
966bea9
Enable `unstable` feature when building docs on docs.rs
phil-opp Aug 19, 2020
408a5f1
Create a CI workflow
phil-opp Aug 19, 2020
9bc9f95
Fix as_slice/as_mut_slice
phil-opp Aug 19, 2020
267ef61
Add `fill` and `copy_within` methods for slices
phil-opp Sep 9, 2020
401c5ba
Derive `Debug` and `Clone` for access types
phil-opp Sep 21, 2020
a4ccd3d
Document new slice methods
phil-opp Sep 21, 2020
2eaa1d6
Update check_range call for latest nightly
phil-opp Sep 21, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Change order of impl blocks to show read/write methods first in docs
  • Loading branch information
phil-opp committed Aug 19, 2020
commit d12063861e38d1f555bf1169eba9b853013d5945
174 changes: 87 additions & 87 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,93 @@ impl<R> Volatile<R> {
}
}

/// Methods for references to `Copy` types
impl<R, T, A> Volatile<R, A>
where
R: Deref<Target = T>,
T: Copy,
{
/// Performs a volatile read of the contained value.
///
/// Returns a copy of the read value. Volatile reads are guaranteed not to be optimized
/// away by the compiler, but by themselves do not have atomic ordering
/// guarantees. To also get atomicity, consider looking at the `Atomic` wrapper types of
/// the standard/`core` library.
///
/// ## Examples
///
/// ```rust
/// use volatile::Volatile;
///
/// let value = 42;
/// let shared_reference = Volatile::new(&value);
/// assert_eq!(shared_reference.read(), 42);
///
/// let mut value = 50;
/// let mut_reference = Volatile::new(&mut value);
/// assert_eq!(mut_reference.read(), 50);
/// ```
pub fn read(&self) -> T
where
A: Readable,
{
// UNSAFE: Safe, as we know that our internal value exists.
unsafe { ptr::read_volatile(&*self.reference) }
}

/// Performs a volatile write, setting the contained value to the given `value`.
///
/// Volatile writes are guaranteed to not be optimized away by the compiler, but by
/// themselves do not have atomic ordering guarantees. To also get atomicity, consider
/// looking at the `Atomic` wrapper types of the standard/`core` library.
///
/// ## Example
///
/// ```rust
/// use volatile::Volatile;
///
/// let mut value = 42;
/// let mut volatile = Volatile::new(&mut value);
/// volatile.write(50);
///
/// assert_eq!(volatile.read(), 50);
/// ```
pub fn write(&mut self, value: T)
where
A: Writable,
R: DerefMut,
{
// UNSAFE: Safe, as we know that our internal value exists.
unsafe { ptr::write_volatile(&mut *self.reference, value) };
}

/// Updates the contained value using the given closure and volatile instructions.
///
/// Performs a volatile read of the contained value, passes a mutable reference to it to the
/// function `f`, and then performs a volatile write of the (potentially updated) value back to
/// the contained value.
///
/// ```rust
/// use volatile::Volatile;
///
/// let mut value = 42;
/// let mut volatile = Volatile::new(&mut value);
/// volatile.update(|val| *val += 1);
///
/// assert_eq!(volatile.read(), 43);
/// ```
pub fn update<F>(&mut self, f: F)
where
A: Readable + Writable,
R: DerefMut,
F: FnOnce(&mut T),
{
let mut value = self.read();
f(&mut value);
self.write(value);
}
}

/// Method for extracting the wrapped value.
impl<R, A> Volatile<R, A> {
/// Extracts the inner value stored in the wrapper type.
Expand Down Expand Up @@ -299,93 +386,6 @@ where
}
}

/// Methods for references to `Copy` types
impl<R, T, A> Volatile<R, A>
where
R: Deref<Target = T>,
T: Copy,
{
/// Performs a volatile read of the contained value.
///
/// Returns a copy of the read value. Volatile reads are guaranteed not to be optimized
/// away by the compiler, but by themselves do not have atomic ordering
/// guarantees. To also get atomicity, consider looking at the `Atomic` wrapper types of
/// the standard/`core` library.
///
/// ## Examples
///
/// ```rust
/// use volatile::Volatile;
///
/// let value = 42;
/// let shared_reference = Volatile::new(&value);
/// assert_eq!(shared_reference.read(), 42);
///
/// let mut value = 50;
/// let mut_reference = Volatile::new(&mut value);
/// assert_eq!(mut_reference.read(), 50);
/// ```
pub fn read(&self) -> T
where
A: Readable,
{
// UNSAFE: Safe, as we know that our internal value exists.
unsafe { ptr::read_volatile(&*self.reference) }
}

/// Performs a volatile write, setting the contained value to the given `value`.
///
/// Volatile writes are guaranteed to not be optimized away by the compiler, but by
/// themselves do not have atomic ordering guarantees. To also get atomicity, consider
/// looking at the `Atomic` wrapper types of the standard/`core` library.
///
/// ## Example
///
/// ```rust
/// use volatile::Volatile;
///
/// let mut value = 42;
/// let mut volatile = Volatile::new(&mut value);
/// volatile.write(50);
///
/// assert_eq!(volatile.read(), 50);
/// ```
pub fn write(&mut self, value: T)
where
A: Writable,
R: DerefMut,
{
// UNSAFE: Safe, as we know that our internal value exists.
unsafe { ptr::write_volatile(&mut *self.reference, value) };
}

/// Updates the contained value using the given closure and volatile instructions.
///
/// Performs a volatile read of the contained value, passes a mutable reference to it to the
/// function `f`, and then performs a volatile write of the (potentially updated) value back to
/// the contained value.
///
/// ```rust
/// use volatile::Volatile;
///
/// let mut value = 42;
/// let mut volatile = Volatile::new(&mut value);
/// volatile.update(|val| *val += 1);
///
/// assert_eq!(volatile.read(), 43);
/// ```
pub fn update<F>(&mut self, f: F)
where
A: Readable + Writable,
R: DerefMut,
F: FnOnce(&mut T),
{
let mut value = self.read();
f(&mut value);
self.write(value);
}
}

/// Methods for volatile slices
impl<T, R, A> Volatile<R, A>
where
Expand Down
0