实现SystemV共享内存 (#690)

* 实现SystemV共享内存

* 测试shm

* 添加测试程序

* 完善细节

* 修正shm的时间数据错误的问题

* fix: devfs的metadata权限为0x777的错误

---------

Co-authored-by: longjin <longjin@DragonOS.org>
This commit is contained in:
Jomo
2024-04-07 14:04:19 +08:00
committed by GitHub
parent eb49bb993a
commit 6fc066ac11
49 changed files with 1567 additions and 202 deletions

View File

@ -12,6 +12,7 @@ use hashbrown::{HashMap, HashSet};
use crate::{
arch::{interrupt::ipi::send_ipi, MMArch},
exception::ipi::{IpiKind, IpiTarget},
ipc::shm::ShmId,
kerror, kwarn,
libs::spinlock::{SpinLock, SpinLockGuard},
};
@ -41,7 +42,7 @@ pub fn page_manager_init() {
kinfo!("page_manager_init done");
}
pub fn page_manager_lock_irasave() -> SpinLockGuard<'static, PageManager> {
pub fn page_manager_lock_irqsave() -> SpinLockGuard<'static, PageManager> {
unsafe { PAGE_MANAGER.as_ref().unwrap().lock_irqsave() }
}
@ -57,6 +58,14 @@ impl PageManager {
}
}
pub fn contains(&self, paddr: &PhysAddr) -> bool {
self.phys2page.contains_key(paddr)
}
pub fn get(&self, paddr: &PhysAddr) -> Option<&Page> {
self.phys2page.get(paddr)
}
pub fn get_mut(&mut self, paddr: &PhysAddr) -> &mut Page {
self.phys2page.get_mut(paddr).unwrap()
}
@ -76,15 +85,22 @@ pub struct Page {
map_count: usize,
/// 是否为共享页
shared: bool,
/// 映射计数为0时是否可回收
free_when_zero: bool,
/// 共享页id如果是共享页
shm_id: Option<ShmId>,
/// 映射到当前page的VMA
anon_vma: HashSet<Arc<LockedVMA>>,
}
impl Page {
pub fn new(shared: bool) -> Self {
let dealloc_when_zero = !shared;
Self {
map_count: 0,
shared,
free_when_zero: dealloc_when_zero,
shm_id: None,
anon_vma: HashSet::new(),
}
}
@ -103,7 +119,27 @@ impl Page {
/// 判断当前物理页是否能被回
pub fn can_deallocate(&self) -> bool {
self.map_count == 0 && !self.shared
self.map_count == 0 && self.free_when_zero
}
pub fn shared(&self) -> bool {
self.shared
}
pub fn shm_id(&self) -> Option<ShmId> {
self.shm_id
}
pub fn set_shm_id(&mut self, shm_id: ShmId) {
self.shm_id = Some(shm_id);
}
pub fn set_dealloc_when_zero(&mut self, dealloc_when_zero: bool) {
self.free_when_zero = dealloc_when_zero;
}
pub fn anon_vma(&self) -> &HashSet<Arc<LockedVMA>> {
&self.anon_vma
}
}
@ -682,7 +718,12 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
let phys: PhysAddr = self.frame_allocator.allocate_one()?;
compiler_fence(Ordering::SeqCst);
page_manager_lock_irasave().insert(phys, Page::new(false));
let mut page_manager_guard: SpinLockGuard<'static, PageManager> =
page_manager_lock_irqsave();
if !page_manager_guard.contains(&phys) {
page_manager_guard.insert(phys, Page::new(false))
}
return self.map_phys(virt, phys, flags);
}