mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-22 11:13:22 +00:00
实现SystemV共享内存 (#690)
* 实现SystemV共享内存 * 测试shm * 添加测试程序 * 完善细节 * 修正shm的时间数据错误的问题 * fix: devfs的metadata权限为0x777的错误 --------- Co-authored-by: longjin <longjin@DragonOS.org>
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user