Skip to content

Instantly share code, notes, and snippets.

@JinShil
Last active December 15, 2016 01:10
Show Gist options
  • Save JinShil/b4ce8d6dd054a6ea6f255b414c374031 to your computer and use it in GitHub Desktop.
Save JinShil/b4ce8d6dd054a6ea6f255b414c374031 to your computer and use it in GitHub Desktop.
Volatile and Non-volatile implementation of the same type (special thanks to @mbrubeck)
use std::ptr;
use std::marker::PhantomData;
trait ReadWrite {
unsafe fn read<T>(src: *const T) -> T;
unsafe fn write<T>(dst: *mut T, src: T);
}
enum Volatile {}
enum NonVolatile {}
impl ReadWrite for Volatile {
#[inline]
unsafe fn read<T>(src: *const T) -> T {
ptr::read_volatile(src)
}
#[inline]
unsafe fn write<T>(dst: *mut T, src: T) {
ptr::write_volatile(dst, src)
}
}
impl ReadWrite for NonVolatile {
#[inline]
unsafe fn read<T>(src: *const T) -> T {
ptr::read(src)
}
#[inline]
unsafe fn write<T>(dst: *mut T, src: T) {
ptr::write(dst, src)
}
}
struct MyStruct<RW>{
x: u8,
_data: PhantomData<RW>,
}
impl<RW: ReadWrite> MyStruct<RW> {
fn new() -> Self {
MyStruct { x: 0, _data: PhantomData }
}
fn do_stuff(&mut self) {
unsafe {
let x = RW::read(&self.x);
RW::write(&mut self.x, x + 1);
}
}
}
fn main() {
let mut a = MyStruct::<Volatile>::new();
a.do_stuff();
let mut b = MyStruct::<NonVolatile>::new();
b.do_stuff();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment