forked from rust-osdev/volatile
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmod.rs
103 lines (90 loc) · 2.49 KB
/
mod.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use core::{cmp::Ordering, fmt, hash, marker::PhantomData, ptr::NonNull};
use crate::access::ReadWrite;
mod macros;
mod operations;
#[cfg(test)]
mod tests;
#[cfg(feature = "unstable")]
mod unstable;
#[cfg(feature = "very_unstable")]
mod very_unstable;
/// Wraps a pointer to make accesses to the referenced value volatile.
///
/// Allows volatile reads and writes on the referenced value. The referenced value needs to
/// be `Copy` for reading and writing, as volatile reads and writes take and return copies
/// of the value.
///
/// 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.
#[repr(transparent)]
pub struct VolatilePtr<'a, T, A = ReadWrite>
where
T: ?Sized,
{
pointer: NonNull<T>,
reference: PhantomData<&'a T>,
access: PhantomData<A>,
}
impl<'a, T, A> Copy for VolatilePtr<'a, T, A> where T: ?Sized {}
impl<T, A> Clone for VolatilePtr<'_, T, A>
where
T: ?Sized,
{
fn clone(&self) -> Self {
*self
}
}
impl<T, A> fmt::Debug for VolatilePtr<'_, T, A>
where
T: ?Sized,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Pointer::fmt(&self.pointer.as_ptr(), f)
}
}
impl<T, A> fmt::Pointer for VolatilePtr<'_, T, A>
where
T: ?Sized,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Pointer::fmt(&self.pointer.as_ptr(), f)
}
}
impl<T, A> PartialEq for VolatilePtr<'_, T, A>
where
T: ?Sized,
{
fn eq(&self, other: &Self) -> bool {
core::ptr::eq(self.pointer.as_ptr(), other.pointer.as_ptr())
}
}
impl<T, A> Eq for VolatilePtr<'_, T, A> where T: ?Sized {}
impl<T, A> PartialOrd for VolatilePtr<'_, T, A>
where
T: ?Sized,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T, A> Ord for VolatilePtr<'_, T, A>
where
T: ?Sized,
{
fn cmp(&self, other: &Self) -> Ordering {
#[allow(ambiguous_wide_pointer_comparisons)]
Ord::cmp(&self.pointer.as_ptr(), &other.pointer.as_ptr())
}
}
impl<T, A> hash::Hash for VolatilePtr<'_, T, A>
where
T: ?Sized,
{
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.pointer.as_ptr().hash(state);
}
}