12
12
use access:: { ReadOnly , ReadWrite , Readable , Writable , WriteOnly } ;
13
13
use core:: {
14
14
marker:: PhantomData ,
15
- ops:: { Index , IndexMut } ,
15
+ ops:: Deref ,
16
+ ops:: { DerefMut , Index , IndexMut } ,
16
17
ptr,
17
18
slice:: SliceIndex ,
18
19
} ;
@@ -35,6 +36,7 @@ pub struct Volatile<R, A = ReadWrite> {
35
36
access : PhantomData < A > ,
36
37
}
37
38
39
+ /// Construction functions
38
40
impl < R > Volatile < R > {
39
41
/// Construct a new volatile instance wrapping the given reference.
40
42
///
@@ -70,8 +72,10 @@ impl<R> Volatile<R> {
70
72
}
71
73
}
72
74
73
- impl < T , A > Volatile < & T , A >
75
+ /// Methods for references to `Copy` types
76
+ impl < R , T , A > Volatile < R , A >
74
77
where
78
+ R : Deref < Target = T > ,
75
79
T : Copy ,
76
80
{
77
81
/// Performs a volatile read of the contained value.
@@ -80,48 +84,25 @@ where
80
84
/// away by the compiler, but by themselves do not have atomic ordering
81
85
/// guarantees. To also get atomicity, consider looking at the `Atomic` wrapper type.
82
86
///
83
- /// ## Example
87
+ /// ## Examples
84
88
///
85
89
/// ```rust
86
90
/// use volatile::Volatile;
87
91
///
88
92
/// let value = 42;
89
- /// let volatile = Volatile::new(&value);
93
+ /// let shared_reference = Volatile::new(&value);
94
+ /// assert_eq!(shared_reference.read(), 42);
90
95
///
91
- /// assert_eq!(volatile.read(), 42);
96
+ /// let mut value = 50;
97
+ /// let mut_reference = Volatile::new(&mut value);
98
+ /// assert_eq!(mut_reference.read(), 50);
92
99
/// ```
93
100
pub fn read ( & self ) -> T
94
101
where
95
102
A : Readable ,
96
103
{
97
104
// UNSAFE: Safe, as we know that our internal value exists.
98
- unsafe { ptr:: read_volatile ( self . reference ) }
99
- }
100
- }
101
-
102
- impl < T : Copy , A > Volatile < & mut T , A > {
103
- /// Performs a volatile read of the contained value.
104
- ///
105
- /// Returns a copy of the read value. Volatile reads are guaranteed not to be optimized
106
- /// away by the compiler, but by themselves do not have atomic ordering
107
- /// guarantees. To also get atomicity, consider looking at the `Atomic` wrapper type.
108
- ///
109
- /// ## Example
110
- ///
111
- /// ```rust
112
- /// use volatile::Volatile;
113
- ///
114
- /// let mut value = 10;
115
- /// let volatile = Volatile::new(&mut value);
116
- ///
117
- /// assert_eq!(volatile.read(), 10);
118
- /// ```
119
- pub fn read ( & self ) -> T
120
- where
121
- A : Readable ,
122
- {
123
- // UNSAFE: Safe, as we know that our internal value exists.
124
- unsafe { ptr:: read_volatile ( self . reference ) }
105
+ unsafe { ptr:: read_volatile ( & * self . reference ) }
125
106
}
126
107
127
108
/// Performs a volatile write, setting the contained value to the given `value`.
@@ -144,9 +125,10 @@ impl<T: Copy, A> Volatile<&mut T, A> {
144
125
pub fn write ( & mut self , value : T )
145
126
where
146
127
A : Writable ,
128
+ R : DerefMut ,
147
129
{
148
130
// UNSAFE: Safe, as we know that our internal value exists.
149
- unsafe { ptr:: write_volatile ( self . reference , value) } ;
131
+ unsafe { ptr:: write_volatile ( & mut * self . reference , value) } ;
150
132
}
151
133
152
134
/// Updates the contained value using the given closure and volatile instructions.
@@ -166,8 +148,9 @@ impl<T: Copy, A> Volatile<&mut T, A> {
166
148
/// ```
167
149
pub fn update < F > ( & mut self , f : F )
168
150
where
169
- F : FnOnce ( & mut T ) ,
170
151
A : Readable + Writable ,
152
+ R : DerefMut ,
153
+ F : FnOnce ( & mut T ) ,
171
154
{
172
155
let mut value = self . read ( ) ;
173
156
f ( & mut value) ;
0 commit comments