Merge branch 'better_fmap' into 'master'
Better fmap See merge request redox-os/ipcd!5
This commit is contained in:
Generated
+4
-5
@@ -18,15 +18,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.139"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
version = "0.3.5"
|
||||
source = "git+https://gitlab.redox-os.org/4lDO2/syscall.git?branch=better_fmap#f0976e1d6020e6854ca30ed1f6d61b10dfc4fa58"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@
|
||||
edition = "2018"
|
||||
name = "ipcd"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
redox_syscall = "0.2"
|
||||
redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git" }
|
||||
|
||||
+5
-1
@@ -1,3 +1,5 @@
|
||||
#![feature(int_roundings)]
|
||||
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
fs::File,
|
||||
@@ -112,7 +114,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
match shm.socket.read(&mut packet) {
|
||||
Ok(0) => break true,
|
||||
Ok(_) => {
|
||||
shm.handle(&mut packet);
|
||||
unsafe {
|
||||
shm.handle(&mut packet);
|
||||
}
|
||||
shm.socket.write(&packet)?;
|
||||
},
|
||||
Err(err) => if err.kind() == io::ErrorKind::WouldBlock {
|
||||
|
||||
+48
-18
@@ -6,11 +6,11 @@ use std::{
|
||||
os::unix::fs::OpenOptionsExt,
|
||||
rc::Rc,
|
||||
};
|
||||
use syscall::{error::*, flag::O_NONBLOCK, Error, Map, SchemeMut, Result};
|
||||
use syscall::{error::*, flag::O_NONBLOCK, Error, Map, SchemeMut, Result, Packet, KSMSG_MMAP_PREP, MapFlags, KSMSG_MMAP, PAGE_SIZE, MAP_PRIVATE};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ShmHandle {
|
||||
buffer: Option<Box<[u8]>>,
|
||||
buffer: Option<MmapGuard>,
|
||||
refs: usize
|
||||
}
|
||||
pub struct ShmScheme {
|
||||
@@ -46,22 +46,6 @@ impl SchemeMut for ShmScheme {
|
||||
self.next_id += 1;
|
||||
Ok(id)
|
||||
}
|
||||
fn fmap(&mut self, id: usize, map: &Map) -> Result<usize> {
|
||||
let path = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
let total_size = map.offset + map.size;
|
||||
match self.maps.get_mut(path).expect("handle pointing to nothing").buffer {
|
||||
Some(ref mut buf) => {
|
||||
if total_size != buf.len() {
|
||||
return Err(Error::new(ERANGE));
|
||||
}
|
||||
Ok(buf[map.offset..].as_mut_ptr() as usize)
|
||||
},
|
||||
ref mut buf @ None => {
|
||||
*buf = Some(vec![0; total_size].into_boxed_slice());
|
||||
Ok(buf.as_mut().unwrap()[map.offset..].as_mut_ptr() as usize)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
// Write scheme name
|
||||
const PREFIX: &[u8] = b"shm:";
|
||||
@@ -91,4 +75,50 @@ impl SchemeMut for ShmScheme {
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
fn mmap_prep(&mut self, id: usize, offset: u64, size: usize, flags: MapFlags) -> Result<usize> {
|
||||
let path = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
let total_size = offset as usize + size;
|
||||
match self.maps.get_mut(path).expect("handle pointing to nothing").buffer {
|
||||
Some(ref mut buf) => {
|
||||
if total_size > buf.len() {
|
||||
return Err(Error::new(ERANGE));
|
||||
}
|
||||
Ok(buf.as_ptr() + offset as usize)
|
||||
},
|
||||
ref mut buf @ None => {
|
||||
*buf = Some(MmapGuard::alloc(size.div_ceil(PAGE_SIZE))?);
|
||||
Ok(buf.as_mut().unwrap().as_ptr() + offset as usize)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MmapGuard {
|
||||
base: usize,
|
||||
size: usize,
|
||||
}
|
||||
impl MmapGuard {
|
||||
pub fn alloc(page_count: usize) -> Result<Self> {
|
||||
let size = page_count * PAGE_SIZE;
|
||||
let base = unsafe { syscall::fmap(!0, &Map { offset: 0, size, flags: MAP_PRIVATE, address: 0 }) }?;
|
||||
|
||||
Ok(Self {
|
||||
base,
|
||||
size,
|
||||
})
|
||||
}
|
||||
pub fn len(&self) -> usize {
|
||||
self.size
|
||||
}
|
||||
pub fn as_ptr(&self) -> usize {
|
||||
self.base
|
||||
}
|
||||
}
|
||||
impl Drop for MmapGuard {
|
||||
fn drop(&mut self) {
|
||||
if self.size == 0 {
|
||||
return;
|
||||
}
|
||||
let _ = unsafe { syscall::funmap(self.base, self.size) };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user