mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-25 17:33:28 +04:00
Implement memory_set splitting for munmap, add sys_sysinfo
This commit is contained in:
parent
dc55238989
commit
1645451749
@ -269,7 +269,7 @@ impl<T: InactivePageTable> MemorySet<T> {
|
||||
}
|
||||
|
||||
/*
|
||||
** @brief remove the memory area to the memory set
|
||||
** @brief remove the memory area from the memory set
|
||||
** @param area: MemoryArea the memory area to remove
|
||||
** @retval none
|
||||
*/
|
||||
@ -285,6 +285,41 @@ impl<T: InactivePageTable> MemorySet<T> {
|
||||
panic!("no memory area found");
|
||||
}
|
||||
|
||||
/*
|
||||
** @brief remove the memory area from the memory set and split existed ones when necessary
|
||||
** @param area: MemoryArea the memory area to remove
|
||||
** @retval none
|
||||
*/
|
||||
pub fn pop_with_split(&mut self, start_addr: VirtAddr, end_addr: VirtAddr) {
|
||||
assert!(start_addr <= end_addr, "invalid memory area");
|
||||
for i in 0..self.areas.len() {
|
||||
if self.areas[i].is_overlap_with(start_addr, end_addr) {
|
||||
if self.areas[i].start_addr >= start_addr && self.areas[i].end_addr <= end_addr {
|
||||
// subset
|
||||
let area = self.areas.remove(i);
|
||||
self.page_table.edit(|pt| area.unmap(pt));
|
||||
} else if self.areas[i].start_addr >= start_addr && self.areas[i].start_addr < end_addr {
|
||||
// prefix
|
||||
let area = self.areas.remove(i);
|
||||
let dead_area = MemoryArea { start_addr: area.start_addr, end_addr, attr: area.attr, handler: area.handler.box_clone(), name: area.name };
|
||||
self.page_table.edit(|pt| dead_area.unmap(pt));
|
||||
let new_area = MemoryArea { start_addr: end_addr, end_addr: area.end_addr, attr: area.attr, handler: area.handler, name: area.name };
|
||||
self.areas.insert(i, new_area);
|
||||
} else if self.areas[i].end_addr <= end_addr && self.areas[i].end_addr > start_addr {
|
||||
// postfix
|
||||
let area = self.areas.remove(i);
|
||||
let dead_area = MemoryArea { start_addr: start_addr, end_addr: area.end_addr, attr: area.attr, handler: area.handler.box_clone(), name: area.name };
|
||||
self.page_table.edit(|pt| dead_area.unmap(pt));
|
||||
let new_area = MemoryArea { start_addr: area.start_addr, end_addr: start_addr, attr: area.attr, handler: area.handler, name: area.name };
|
||||
self.areas.insert(i, new_area);
|
||||
} else {
|
||||
unimplemented!("");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** @brief get iterator of the memory area
|
||||
** @retval impl Iterator<Item=&MemoryArea>
|
||||
|
@ -23,7 +23,7 @@ pub fn sys_mmap(mut addr: usize, mut len: usize, prot: usize, flags: usize, fd:
|
||||
|
||||
if flags.contains(MmapFlags::FIXED) {
|
||||
// we have to map it to addr, so remove the old mapping first
|
||||
proc.memory_set.pop(addr, addr + len);
|
||||
proc.memory_set.pop_with_split(addr, addr + len);
|
||||
} else {
|
||||
addr = proc.memory_set.find_free_area(addr, len);
|
||||
}
|
||||
@ -63,7 +63,7 @@ pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult {
|
||||
pub fn sys_munmap(addr: usize, len: usize) -> SysResult {
|
||||
info!("munmap addr={:#x}, size={:#x}", addr, len);
|
||||
let mut proc = process();
|
||||
proc.memory_set.pop(addr, addr + len);
|
||||
proc.memory_set.pop_with_split(addr, addr + len);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
|
@ -34,3 +34,31 @@ pub fn sys_sched_getaffinity(pid: usize, size: usize, mask: *mut u32) -> SysResu
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn sys_sysinfo(sys_info: *mut SysInfo) -> SysResult {
|
||||
let proc = process();
|
||||
proc.memory_set.check_mut_ptr(sys_info)?;
|
||||
|
||||
let sysinfo = SysInfo::default();
|
||||
unsafe {
|
||||
*sys_info = sysinfo
|
||||
};
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct SysInfo {
|
||||
uptime: u64,
|
||||
loads: [u64; 3],
|
||||
totalram: u64,
|
||||
freeram: u64,
|
||||
sharedram: u64,
|
||||
bufferram: u64,
|
||||
totalswap: u64,
|
||||
freeswap: u64,
|
||||
procs: u16,
|
||||
totalhigh: u64,
|
||||
freehigh: u64,
|
||||
mem_unit: u32
|
||||
}
|
@ -99,6 +99,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
||||
096 => sys_gettimeofday(args[0] as *mut TimeVal, args[1] as *const u8),
|
||||
// 097 => sys_getrlimit(),
|
||||
// 098 => sys_getrusage(),
|
||||
099 => sys_sysinfo(args[0] as *mut SysInfo),
|
||||
110 => sys_getppid(),
|
||||
// 133 => sys_mknod(),
|
||||
141 => sys_set_priority(args[0]),
|
||||
@ -131,6 +132,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
||||
warn!("sys_ioctl is unimplemented");
|
||||
Ok(0)
|
||||
}
|
||||
028 => {
|
||||
warn!("sys_madvise is unimplemented");
|
||||
Ok(0)
|
||||
}
|
||||
037 => {
|
||||
warn!("sys_alarm is unimplemented");
|
||||
Ok(0)
|
||||
@ -139,6 +144,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
||||
warn!("sys_fcntl is unimplemented");
|
||||
Ok(0)
|
||||
}
|
||||
089 => {
|
||||
warn!("sys_readlink is unimplemented");
|
||||
Err(SysError::ENOENT)
|
||||
}
|
||||
092 => {
|
||||
warn!("sys_chown is unimplemented");
|
||||
Ok(0)
|
||||
@ -171,6 +180,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
||||
warn!("sys_sigaltstack is unimplemented");
|
||||
Ok(0)
|
||||
}
|
||||
213 => {
|
||||
warn!("sys_epoll_create is unimplemented");
|
||||
Err(SysError::ENOSYS)
|
||||
}
|
||||
218 => {
|
||||
warn!("sys_set_tid_address is unimplemented");
|
||||
Ok(thread::current().id())
|
||||
@ -185,7 +198,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
||||
}
|
||||
291 => {
|
||||
warn!("sys_epoll_create1 is unimplemented");
|
||||
Err(SysError::EINVAL)
|
||||
Err(SysError::ENOSYS)
|
||||
}
|
||||
302 => {
|
||||
warn!("sys_prlimit64 is unimplemented");
|
||||
|
Loading…
Reference in New Issue
Block a user