Skip to content

Commit 2dc770c

Browse files
bonzinialxiord
authored andcommitted
provide access to Bytes<> methods for all ByteValued types
Add a method to go from ByteValued to VolatileSlice, allowing usage of Bytes methods to read and write ByteValued types. The as_bytes() method requires a mutable reference, so there cannot be other owners that are unaware of concurrent volatile accesses. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent eed6033 commit 2dc770c

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

src/bytes.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
//! Define the ByteValued trait to mark that it is safe to instantiate the struct with random data.
1212
13+
use crate::VolatileSlice;
1314
use std::io::{Read, Write};
1415
use std::mem::size_of;
1516
use std::result::Result;
@@ -100,6 +101,22 @@ pub unsafe trait ByteValued: Copy + Default + Send + Sync {
100101
// borrowing the given mutable reference.
101102
unsafe { from_raw_parts_mut(self as *mut Self as *mut u8, size_of::<Self>()) }
102103
}
104+
105+
/// Converts a mutable reference to `self` into a VolatileSlice. This is
106+
/// useful because `VolatileSlice` provides a `Bytes<usize>` implementation.
107+
///
108+
/// # Safety
109+
///
110+
/// Unlike most VolatileMemory implementation, this method requires an exclusive
111+
/// reference to `self`; this trivially fulfills `VolatileSlice::new`'s requirement
112+
/// that all accesses to `self` use volatile accesses (because there can
113+
/// be no other accesses).
114+
fn as_bytes(&mut self) -> VolatileSlice {
115+
unsafe {
116+
// This is safe because the lifetime is the same as self
117+
VolatileSlice::new(self as *mut Self as usize as *mut _, size_of::<Self>())
118+
}
119+
}
103120
}
104121

105122
// All intrinsic types and arrays of intrinsic types are ByteValued. They are just numbers.
@@ -405,4 +422,22 @@ mod tests {
405422
.is_err());
406423
assert!(bytes.read_obj::<u64>(MOCK_BYTES_CONTAINER_SIZE).is_err());
407424
}
425+
426+
#[repr(C)]
427+
#[derive(Copy, Clone, Default)]
428+
struct S {
429+
a: u32,
430+
b: u32,
431+
}
432+
433+
unsafe impl ByteValued for S {}
434+
435+
#[test]
436+
fn byte_valued_slice() {
437+
let a: [u8; 8] = [0, 0, 0, 0, 1, 1, 1, 1];
438+
let mut s: S = Default::default();
439+
s.as_bytes().copy_from(&a);
440+
assert_eq!(s.a, 0);
441+
assert_eq!(s.b, 0x1010101);
442+
}
408443
}

0 commit comments

Comments
 (0)