Make the MMappedMemory generic

This commit is contained in:
guillaume didier 2020-04-07 14:25:13 +02:00
parent ac4889372d
commit 5c025fb495
4 changed files with 49 additions and 35 deletions

View File

@ -2,7 +2,7 @@ use cache_utils::flush;
use cache_utils::mmap::MMappedMemory; use cache_utils::mmap::MMappedMemory;
pub fn main() { pub fn main() {
let m = unsafe { MMappedMemory::new(2 << 20) }; let m = MMappedMemory::new(2 << 20);
let array = m.slice(); let array = m.slice();
loop { loop {
unsafe { unsafe {

View File

@ -1,4 +1,5 @@
#![cfg_attr(feature = "no_std", no_std)] #![cfg_attr(feature = "no_std", no_std)]
#![feature(ptr_internals)]
use static_assertions::assert_cfg; use static_assertions::assert_cfg;

View File

@ -34,7 +34,7 @@ struct Page {
} }
*/ */
pub fn main() { pub fn main() {
let m = unsafe { MMappedMemory::new(SIZE) }; let m = MMappedMemory::new(SIZE);
let array = m.slice(); let array = m.slice();
let old = sched_getaffinity(Pid::from_raw(0)).unwrap(); let old = sched_getaffinity(Pid::from_raw(0)).unwrap();

View File

@ -2,9 +2,12 @@
use core::borrow::{Borrow, BorrowMut}; use core::borrow::{Borrow, BorrowMut};
use core::ffi::c_void; use core::ffi::c_void;
use core::mem::size_of;
use core::ops::{Deref, DerefMut}; use core::ops::{Deref, DerefMut};
use core::ptr::null_mut; use core::ptr::null_mut;
use core::ptr::Unique;
use core::slice::{from_raw_parts, from_raw_parts_mut}; use core::slice::{from_raw_parts, from_raw_parts_mut};
use nix::errno::Errno::EINVAL;
use nix::sys::mman; use nix::sys::mman;
/* from linux kernel headers. /* from linux kernel headers.
@ -17,78 +20,88 @@ use nix::sys::mman;
#define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT) #define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT)
*/ */
pub struct MMappedMemory { pub struct MMappedMemory<T> {
pointer: *mut u8, pointer: Unique<T>,
size: usize, size: usize,
} }
impl MMappedMemory { impl<T> MMappedMemory<T> {
pub unsafe fn new(size: usize) -> MMappedMemory { pub fn try_new(size: usize) -> Result<MMappedMemory<T>, nix::Error> {
let p: *mut u8 = mman::mmap( assert_ne!(size_of::<T>(), 0);
if let Some(p) = unsafe {
let p = mman::mmap(
null_mut(), null_mut(),
size, size * size_of::<T>(),
mman::ProtFlags::PROT_READ | mman::ProtFlags::PROT_WRITE, mman::ProtFlags::PROT_READ | mman::ProtFlags::PROT_WRITE,
mman::MapFlags::MAP_PRIVATE mman::MapFlags::MAP_PRIVATE
| mman::MapFlags::MAP_ANONYMOUS | mman::MapFlags::MAP_ANONYMOUS
| mman::MapFlags::MAP_HUGETLB, | mman::MapFlags::MAP_HUGETLB,
-1, -1,
0, 0,
) )?;
.unwrap() as *mut u8; Unique::new(p as *mut T)
MMappedMemory { pointer: p, size } } {
Ok(MMappedMemory { pointer: p, size })
} else {
Err(nix::Error::Sys(EINVAL))
}
} }
pub fn slice(&self) -> &[u8] { pub fn new(size: usize) -> MMappedMemory<T> {
unsafe { from_raw_parts(self.pointer, self.size) } Self::try_new(size).unwrap()
} }
pub fn slice_mut(&mut self) -> &mut [u8] { pub fn slice(&self) -> &[T] {
unsafe { from_raw_parts_mut(self.pointer, self.size) } unsafe { from_raw_parts(self.pointer.as_ptr(), self.size) }
}
pub fn slice_mut(&mut self) -> &mut [T] {
unsafe { from_raw_parts_mut(self.pointer.as_ptr(), self.size) }
} }
} }
impl Drop for MMappedMemory { impl<T> Drop for MMappedMemory<T> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
mman::munmap(self.pointer as *mut c_void, self.size).unwrap(); mman::munmap(self.pointer.as_ptr() as *mut c_void, self.size).unwrap();
} }
} }
} }
impl Deref for MMappedMemory { impl<T> Deref for MMappedMemory<T> {
type Target = [u8]; type Target = [T];
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
self.slice() self.slice()
} }
} }
impl DerefMut for MMappedMemory { impl<T> DerefMut for MMappedMemory<T> {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
self.slice_mut() self.slice_mut()
} }
} }
impl AsRef<[u8]> for MMappedMemory { impl<T> AsRef<[T]> for MMappedMemory<T> {
fn as_ref(&self) -> &[u8] { fn as_ref(&self) -> &[T] {
unimplemented!() unimplemented!()
} }
} }
impl AsMut<[u8]> for MMappedMemory { impl<T> AsMut<[T]> for MMappedMemory<T> {
fn as_mut(&mut self) -> &mut [u8] { fn as_mut(&mut self) -> &mut [T] {
self.slice_mut() self.slice_mut()
} }
} }
impl Borrow<[u8]> for MMappedMemory { impl<T> Borrow<[T]> for MMappedMemory<T> {
fn borrow(&self) -> &[u8] { fn borrow(&self) -> &[T] {
self.slice() self.slice()
} }
} }
impl BorrowMut<[u8]> for MMappedMemory { impl<T> BorrowMut<[T]> for MMappedMemory<T> {
fn borrow_mut(&mut self) -> &mut [u8] { fn borrow_mut(&mut self) -> &mut [T] {
self.slice_mut() self.slice_mut()
} }
} }