16fc066acSJomo use crate::{
26fc066acSJomo arch::mm::LockedFrameAllocator,
36fc066acSJomo filesystem::vfs::syscall::ModeType,
46fc066acSJomo libs::{
56fc066acSJomo align::page_align_up,
66fc066acSJomo spinlock::{SpinLock, SpinLockGuard},
76fc066acSJomo },
86fc066acSJomo mm::{
96fc066acSJomo allocator::page_frame::{FrameAllocator, PageFrameCount, PhysPageFrame},
106fc066acSJomo page::{page_manager_lock_irqsave, Page},
116fc066acSJomo PhysAddr,
126fc066acSJomo },
136fc066acSJomo process::{Pid, ProcessManager},
146fc066acSJomo syscall::user_access::{UserBufferReader, UserBufferWriter},
156fc066acSJomo time::PosixTimeSpec,
166fc066acSJomo };
17*cf7f801eSMemoryShore use alloc::{sync::Arc, vec::Vec};
186fc066acSJomo use core::sync::atomic::{compiler_fence, Ordering};
196fc066acSJomo use hashbrown::{HashMap, HashSet};
206fc066acSJomo use ida::IdAllocator;
212eab6dd7S曾俊 use log::info;
226fc066acSJomo use num::ToPrimitive;
236fc066acSJomo use system_error::SystemError;
246fc066acSJomo
256fc066acSJomo pub static mut SHM_MANAGER: Option<SpinLock<ShmManager>> = None;
266fc066acSJomo
276fc066acSJomo /// 用于创建新的私有IPC对象
286fc066acSJomo pub const IPC_PRIVATE: ShmKey = ShmKey::new(0);
296fc066acSJomo
306fc066acSJomo /// 初始化SHM_MANAGER
shm_manager_init()316fc066acSJomo pub fn shm_manager_init() {
322eab6dd7S曾俊 info!("shm_manager_init");
336fc066acSJomo let shm_manager = SpinLock::new(ShmManager::new());
346fc066acSJomo
356fc066acSJomo compiler_fence(Ordering::SeqCst);
366fc066acSJomo unsafe { SHM_MANAGER = Some(shm_manager) };
376fc066acSJomo compiler_fence(Ordering::SeqCst);
386fc066acSJomo
392eab6dd7S曾俊 info!("shm_manager_init done");
406fc066acSJomo }
416fc066acSJomo
shm_manager_lock() -> SpinLockGuard<'static, ShmManager>426fc066acSJomo pub fn shm_manager_lock() -> SpinLockGuard<'static, ShmManager> {
436fc066acSJomo unsafe { SHM_MANAGER.as_ref().unwrap().lock() }
446fc066acSJomo }
456fc066acSJomo
466fc066acSJomo int_like!(ShmId, usize);
476fc066acSJomo int_like!(ShmKey, usize);
486fc066acSJomo
496fc066acSJomo bitflags! {
506fc066acSJomo pub struct ShmFlags:u32{
516fc066acSJomo const SHM_RDONLY = 0o10000;
526fc066acSJomo const SHM_RND = 0o20000;
536fc066acSJomo const SHM_REMAP = 0o40000;
546fc066acSJomo const SHM_EXEC = 0o100000;
556fc066acSJomo const SHM_HUGETLB = 0o4000;
566fc066acSJomo
576fc066acSJomo const IPC_CREAT = 0o1000;
586fc066acSJomo const IPC_EXCL = 0o2000;
596fc066acSJomo
606fc066acSJomo const SHM_DEST = 0o1000;
616fc066acSJomo const SHM_LOCKED = 0o2000;
626fc066acSJomo }
636fc066acSJomo }
646fc066acSJomo
656fc066acSJomo /// 管理共享内存段信息的操作码
666fc066acSJomo #[derive(Eq, Clone, Copy)]
676fc066acSJomo pub enum ShmCtlCmd {
686fc066acSJomo /// 删除共享内存段
696fc066acSJomo IpcRmid = 0,
706fc066acSJomo /// 设置KernIpcPerm选项
716fc066acSJomo IpcSet = 1,
726fc066acSJomo /// 获取ShmIdDs
736fc066acSJomo IpcStat = 2,
746fc066acSJomo /// 查看ShmMetaData
756fc066acSJomo IpcInfo = 3,
766fc066acSJomo
776fc066acSJomo /// 不允许共享内存段被置换出物理内存
786fc066acSJomo ShmLock = 11,
796fc066acSJomo /// 允许共享内存段被置换出物理内存
806fc066acSJomo ShmUnlock = 12,
816fc066acSJomo /// 查看ShmMetaData
826fc066acSJomo ShmStat = 13,
836fc066acSJomo /// 查看ShmInfo
846fc066acSJomo ShmInfo = 14,
856fc066acSJomo /// 查看ShmMetaData
866fc066acSJomo ShmtStatAny = 15,
876fc066acSJomo
886fc066acSJomo Default,
896fc066acSJomo }
906fc066acSJomo
916fc066acSJomo impl From<usize> for ShmCtlCmd {
from(cmd: usize) -> ShmCtlCmd926fc066acSJomo fn from(cmd: usize) -> ShmCtlCmd {
936fc066acSJomo match cmd {
946fc066acSJomo 0 => Self::IpcRmid,
956fc066acSJomo 1 => Self::IpcSet,
966fc066acSJomo 2 => Self::IpcStat,
976fc066acSJomo 3 => Self::IpcInfo,
986fc066acSJomo 11 => Self::ShmLock,
996fc066acSJomo 12 => Self::ShmUnlock,
1006fc066acSJomo 13 => Self::ShmStat,
1016fc066acSJomo 14 => Self::ShmInfo,
1026fc066acSJomo 15 => Self::ShmtStatAny,
1036fc066acSJomo _ => Self::Default,
1046fc066acSJomo }
1056fc066acSJomo }
1066fc066acSJomo }
1076fc066acSJomo
1086fc066acSJomo impl PartialEq for ShmCtlCmd {
eq(&self, other: &ShmCtlCmd) -> bool1096fc066acSJomo fn eq(&self, other: &ShmCtlCmd) -> bool {
1106fc066acSJomo *self as usize == *other as usize
1116fc066acSJomo }
1126fc066acSJomo }
1136fc066acSJomo
1146fc066acSJomo /// 共享内存管理器
1156fc066acSJomo #[derive(Debug)]
1166fc066acSJomo pub struct ShmManager {
1176fc066acSJomo /// ShmId分配器
1186fc066acSJomo id_allocator: IdAllocator,
1196fc066acSJomo /// ShmId映射共享内存信息表
1206fc066acSJomo id2shm: HashMap<ShmId, KernelShm>,
1216fc066acSJomo /// ShmKey映射ShmId表
1226fc066acSJomo key2id: HashMap<ShmKey, ShmId>,
1236fc066acSJomo }
1246fc066acSJomo
1256fc066acSJomo impl ShmManager {
new() -> Self1266fc066acSJomo pub fn new() -> Self {
1276fc066acSJomo ShmManager {
1286fc066acSJomo id_allocator: IdAllocator::new(0, usize::MAX - 1),
1296fc066acSJomo id2shm: HashMap::new(),
1306fc066acSJomo key2id: HashMap::new(),
1316fc066acSJomo }
1326fc066acSJomo }
1336fc066acSJomo
1346fc066acSJomo /// # 添加共享内存段
1356fc066acSJomo ///
1366fc066acSJomo /// ## 参数
1376fc066acSJomo ///
1386fc066acSJomo /// - `key`: 共享内存键值
1396fc066acSJomo /// - `size`: 共享内存大小
1406fc066acSJomo /// - `shmflg`: 共享内存标志
1416fc066acSJomo ///
1426fc066acSJomo /// ## 返回值
1436fc066acSJomo ///
1446fc066acSJomo /// 成功:共享内存id
1456fc066acSJomo /// 失败:对应错误码
add( &mut self, key: ShmKey, size: usize, shmflg: ShmFlags, ) -> Result<usize, SystemError>1466fc066acSJomo pub fn add(
1476fc066acSJomo &mut self,
1486fc066acSJomo key: ShmKey,
1496fc066acSJomo size: usize,
1506fc066acSJomo shmflg: ShmFlags,
1516fc066acSJomo ) -> Result<usize, SystemError> {
1526fc066acSJomo // 判断共享内存大小是否过小或溢出
1536fc066acSJomo if !(PosixShmMetaInfo::SHMMIN..=PosixShmMetaInfo::SHMMAX).contains(&size) {
1546fc066acSJomo return Err(SystemError::EINVAL);
1556fc066acSJomo }
1566fc066acSJomo
1576fc066acSJomo let id = self.id_allocator.alloc().expect("No more id to allocate.");
1586fc066acSJomo let shm_id = ShmId::new(id);
1596fc066acSJomo
1606fc066acSJomo // 分配共享内存页面
1616fc066acSJomo let page_count = PageFrameCount::from_bytes(page_align_up(size)).unwrap();
1626fc066acSJomo let phys_page =
1636fc066acSJomo unsafe { LockedFrameAllocator.allocate(page_count) }.ok_or(SystemError::EINVAL)?;
1646fc066acSJomo // 创建共享内存page,并添加到PAGE_MANAGER中
1656fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave();
1666fc066acSJomo let mut cur_phys = PhysPageFrame::new(phys_page.0);
1676fc066acSJomo for _ in 0..page_count.data() {
168*cf7f801eSMemoryShore let page = Arc::new(Page::new(true, cur_phys.phys_address()));
169*cf7f801eSMemoryShore page.write_irqsave().set_shm_id(shm_id);
1706fc066acSJomo let paddr = cur_phys.phys_address();
171*cf7f801eSMemoryShore page_manager_guard.insert(paddr, &page);
1726fc066acSJomo cur_phys = cur_phys.next();
1736fc066acSJomo }
1746fc066acSJomo
1756fc066acSJomo // 创建共享内存信息结构体
1766fc066acSJomo let paddr = phys_page.0;
1776fc066acSJomo let kern_ipc_perm = KernIpcPerm {
1786fc066acSJomo id: shm_id,
1796fc066acSJomo key,
1806fc066acSJomo uid: 0,
1816fc066acSJomo gid: 0,
1826fc066acSJomo _cuid: 0,
1836fc066acSJomo _cgid: 0,
1846fc066acSJomo mode: shmflg & ShmFlags::from_bits_truncate(ModeType::S_IRWXUGO.bits()),
1856fc066acSJomo _seq: 0,
1866fc066acSJomo };
1876fc066acSJomo let shm_kernel = KernelShm::new(kern_ipc_perm, paddr, size);
1886fc066acSJomo
1896fc066acSJomo // 将key、id及其对应KernelShm添加到表中
1906fc066acSJomo self.id2shm.insert(shm_id, shm_kernel);
1916fc066acSJomo self.key2id.insert(key, shm_id);
1926fc066acSJomo
1936fc066acSJomo return Ok(shm_id.data());
1946fc066acSJomo }
1956fc066acSJomo
contains_key(&self, key: &ShmKey) -> Option<&ShmId>1966fc066acSJomo pub fn contains_key(&self, key: &ShmKey) -> Option<&ShmId> {
1976fc066acSJomo self.key2id.get(key)
1986fc066acSJomo }
1996fc066acSJomo
get_mut(&mut self, id: &ShmId) -> Option<&mut KernelShm>2006fc066acSJomo pub fn get_mut(&mut self, id: &ShmId) -> Option<&mut KernelShm> {
2016fc066acSJomo self.id2shm.get_mut(id)
2026fc066acSJomo }
2036fc066acSJomo
free_key(&mut self, key: &ShmKey)2046fc066acSJomo pub fn free_key(&mut self, key: &ShmKey) {
2056fc066acSJomo self.key2id.remove(key);
2066fc066acSJomo }
2076fc066acSJomo
free_id(&mut self, id: &ShmId)2086fc066acSJomo pub fn free_id(&mut self, id: &ShmId) {
2096fc066acSJomo self.id2shm.remove(id);
2106fc066acSJomo self.id_allocator.free(id.0);
2116fc066acSJomo }
2126fc066acSJomo
ipc_info(&self, user_buf: *const u8, from_user: bool) -> Result<usize, SystemError>2136fc066acSJomo pub fn ipc_info(&self, user_buf: *const u8, from_user: bool) -> Result<usize, SystemError> {
2146fc066acSJomo let mut user_buffer_writer = UserBufferWriter::new(
2156fc066acSJomo user_buf as *mut u8,
2166fc066acSJomo core::mem::size_of::<PosixShmMetaInfo>(),
2176fc066acSJomo from_user,
2186fc066acSJomo )?;
2196fc066acSJomo
2206fc066acSJomo let shm_meta_info = PosixShmMetaInfo::new();
2216fc066acSJomo user_buffer_writer.copy_one_to_user(&shm_meta_info, 0)?;
2226fc066acSJomo
2236fc066acSJomo return Ok(0);
2246fc066acSJomo }
2256fc066acSJomo
shm_info(&self, user_buf: *const u8, from_user: bool) -> Result<usize, SystemError>2266fc066acSJomo pub fn shm_info(&self, user_buf: *const u8, from_user: bool) -> Result<usize, SystemError> {
2276fc066acSJomo // 已使用id数量
2286fc066acSJomo let used_ids = self.id2shm.len().to_i32().unwrap();
2296fc066acSJomo // 共享内存总和
2306fc066acSJomo let shm_tot = self.id2shm.iter().fold(0, |acc, (_, kernel_shm)| {
2316fc066acSJomo acc + PageFrameCount::from_bytes(page_align_up(kernel_shm.shm_size))
2326fc066acSJomo .unwrap()
2336fc066acSJomo .data()
2346fc066acSJomo });
2356fc066acSJomo let shm_info = PosixShmInfo::new(used_ids, shm_tot, 0, 0, 0, 0);
2366fc066acSJomo
2376fc066acSJomo let mut user_buffer_writer = UserBufferWriter::new(
2386fc066acSJomo user_buf as *mut u8,
2396fc066acSJomo core::mem::size_of::<PosixShmInfo>(),
2406fc066acSJomo from_user,
2416fc066acSJomo )?;
2426fc066acSJomo user_buffer_writer.copy_one_to_user(&shm_info, 0)?;
2436fc066acSJomo
2446fc066acSJomo return Ok(0);
2456fc066acSJomo }
2466fc066acSJomo
shm_stat( &self, id: ShmId, cmd: ShmCtlCmd, user_buf: *const u8, from_user: bool, ) -> Result<usize, SystemError>2476fc066acSJomo pub fn shm_stat(
2486fc066acSJomo &self,
2496fc066acSJomo id: ShmId,
2506fc066acSJomo cmd: ShmCtlCmd,
2516fc066acSJomo user_buf: *const u8,
2526fc066acSJomo from_user: bool,
2536fc066acSJomo ) -> Result<usize, SystemError> {
2546fc066acSJomo let kernel_shm = self.id2shm.get(&id).ok_or(SystemError::EINVAL)?;
2556fc066acSJomo let key = kernel_shm.kern_ipc_perm.key.data().to_i32().unwrap();
2566fc066acSJomo let mode = kernel_shm.kern_ipc_perm.mode.bits();
2576fc066acSJomo
2586fc066acSJomo let shm_perm = PosixIpcPerm::new(key, 0, 0, 0, 0, mode);
2596fc066acSJomo let shm_segsz = kernel_shm.shm_size;
2606fc066acSJomo let shm_atime = kernel_shm.shm_atim.total_nanos();
2616fc066acSJomo let shm_dtime = kernel_shm.shm_dtim.total_nanos();
2626fc066acSJomo let shm_ctime = kernel_shm.shm_ctim.total_nanos();
2636fc066acSJomo let shm_cpid = kernel_shm.shm_cprid.data().to_u32().unwrap();
2646fc066acSJomo let shm_lpid = kernel_shm.shm_lprid.data().to_u32().unwrap();
2656fc066acSJomo let shm_map_count = kernel_shm.map_count();
2666fc066acSJomo let shm_id_ds = PosixShmIdDs {
2676fc066acSJomo shm_perm,
2686fc066acSJomo shm_segsz,
2696fc066acSJomo shm_atime,
2706fc066acSJomo shm_dtime,
2716fc066acSJomo shm_ctime,
2726fc066acSJomo shm_cpid,
2736fc066acSJomo shm_lpid,
2746fc066acSJomo shm_map_count,
2756fc066acSJomo _unused1: 0,
2766fc066acSJomo _unused2: 0,
2776fc066acSJomo };
2786fc066acSJomo
2796fc066acSJomo let mut user_buffer_writer = UserBufferWriter::new(
2806fc066acSJomo user_buf as *mut u8,
2816fc066acSJomo core::mem::size_of::<PosixShmIdDs>(),
2826fc066acSJomo from_user,
2836fc066acSJomo )?;
2846fc066acSJomo user_buffer_writer.copy_one_to_user(&shm_id_ds, 0)?;
2856fc066acSJomo
2866fc066acSJomo let r: usize = if cmd == ShmCtlCmd::IpcStat {
2876fc066acSJomo 0
2886fc066acSJomo } else {
2896fc066acSJomo id.data()
2906fc066acSJomo };
2916fc066acSJomo
2926fc066acSJomo return Ok(r);
2936fc066acSJomo }
2946fc066acSJomo
ipc_set( &mut self, id: ShmId, user_buf: *const u8, from_user: bool, ) -> Result<usize, SystemError>2956fc066acSJomo pub fn ipc_set(
2966fc066acSJomo &mut self,
2976fc066acSJomo id: ShmId,
2986fc066acSJomo user_buf: *const u8,
2996fc066acSJomo from_user: bool,
3006fc066acSJomo ) -> Result<usize, SystemError> {
3016fc066acSJomo let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
3026fc066acSJomo
3036fc066acSJomo let user_buffer_reader =
3046fc066acSJomo UserBufferReader::new(user_buf, core::mem::size_of::<PosixShmIdDs>(), from_user)?;
3056fc066acSJomo let mut shm_id_ds = PosixShmIdDs::default();
3066fc066acSJomo user_buffer_reader.copy_one_from_user(&mut shm_id_ds, 0)?;
3076fc066acSJomo
3086fc066acSJomo kernel_shm.copy_from(shm_id_ds);
3096fc066acSJomo
3106fc066acSJomo return Ok(0);
3116fc066acSJomo }
3126fc066acSJomo
ipc_rmid(&mut self, id: ShmId) -> Result<usize, SystemError>3136fc066acSJomo pub fn ipc_rmid(&mut self, id: ShmId) -> Result<usize, SystemError> {
3146fc066acSJomo let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
3156fc066acSJomo kernel_shm.set_mode(ShmFlags::SHM_DEST, true);
3166fc066acSJomo
3176fc066acSJomo let mut cur_phys = PhysPageFrame::new(kernel_shm.shm_start_paddr);
3186fc066acSJomo let count = PageFrameCount::from_bytes(page_align_up(kernel_shm.shm_size)).unwrap();
3196fc066acSJomo let key = kernel_shm.kern_ipc_perm.key;
3206fc066acSJomo let id = kernel_shm.kern_ipc_perm.id;
3216fc066acSJomo let map_count = kernel_shm.map_count();
3226fc066acSJomo
3236fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave();
3246fc066acSJomo if map_count > 0 {
3256fc066acSJomo // 设置共享内存物理页当映射计数等于0时可被回收
3266fc066acSJomo for _ in 0..count.data() {
327*cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&cur_phys.phys_address());
328*cf7f801eSMemoryShore page.write_irqsave().set_dealloc_when_zero(true);
3296fc066acSJomo
3306fc066acSJomo cur_phys = cur_phys.next();
3316fc066acSJomo }
3326fc066acSJomo
3336fc066acSJomo // 释放key,不让后续进程连接
3346fc066acSJomo self.free_key(&key);
3356fc066acSJomo } else {
3366fc066acSJomo // 释放共享内存物理页
3376fc066acSJomo for _ in 0..count.data() {
3386fc066acSJomo let paddr = cur_phys.phys_address();
3396fc066acSJomo unsafe {
3406fc066acSJomo LockedFrameAllocator.free(paddr, PageFrameCount::new(1));
3416fc066acSJomo }
3426fc066acSJomo // 将已回收的物理页面对应的Page从PAGE_MANAGER中删去
3436fc066acSJomo page_manager_guard.remove_page(&paddr);
3446fc066acSJomo cur_phys = cur_phys.next();
3456fc066acSJomo }
3466fc066acSJomo
3476fc066acSJomo // 释放key和id
3486fc066acSJomo self.free_id(&id);
3496fc066acSJomo self.free_key(&key)
3506fc066acSJomo }
3516fc066acSJomo
3526fc066acSJomo return Ok(0);
3536fc066acSJomo }
3546fc066acSJomo
shm_lock(&mut self, id: ShmId) -> Result<usize, SystemError>3556fc066acSJomo pub fn shm_lock(&mut self, id: ShmId) -> Result<usize, SystemError> {
3566fc066acSJomo let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
3576fc066acSJomo kernel_shm.set_mode(ShmFlags::SHM_LOCKED, true);
3586fc066acSJomo
3596fc066acSJomo return Ok(0);
3606fc066acSJomo }
3616fc066acSJomo
shm_unlock(&mut self, id: ShmId) -> Result<usize, SystemError>3626fc066acSJomo pub fn shm_unlock(&mut self, id: ShmId) -> Result<usize, SystemError> {
3636fc066acSJomo let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
3646fc066acSJomo kernel_shm.set_mode(ShmFlags::SHM_LOCKED, false);
3656fc066acSJomo
3666fc066acSJomo return Ok(0);
3676fc066acSJomo }
3686fc066acSJomo }
3696fc066acSJomo /// 共享内存信息
3706fc066acSJomo #[derive(Debug)]
3716fc066acSJomo pub struct KernelShm {
3726fc066acSJomo /// 权限信息
3736fc066acSJomo kern_ipc_perm: KernIpcPerm,
3746fc066acSJomo /// 共享内存起始物理地址
3756fc066acSJomo shm_start_paddr: PhysAddr,
3766fc066acSJomo /// 共享内存大小(bytes),注意是用户指定的大小(未经过页面对齐)
3776fc066acSJomo shm_size: usize,
3786fc066acSJomo /// 最后一次连接的时间
3796fc066acSJomo shm_atim: PosixTimeSpec,
3806fc066acSJomo /// 最后一次断开连接的时间
3816fc066acSJomo shm_dtim: PosixTimeSpec,
3826fc066acSJomo /// 最后一次更改信息的时间
3836fc066acSJomo shm_ctim: PosixTimeSpec,
3846fc066acSJomo /// 创建者进程id
3856fc066acSJomo shm_cprid: Pid,
3866fc066acSJomo /// 最后操作者进程id
3876fc066acSJomo shm_lprid: Pid,
3886fc066acSJomo }
3896fc066acSJomo
3906fc066acSJomo impl KernelShm {
new(kern_ipc_perm: KernIpcPerm, shm_start_paddr: PhysAddr, shm_size: usize) -> Self3916fc066acSJomo pub fn new(kern_ipc_perm: KernIpcPerm, shm_start_paddr: PhysAddr, shm_size: usize) -> Self {
3926fc066acSJomo let shm_cprid = ProcessManager::current_pid();
3936fc066acSJomo KernelShm {
3946fc066acSJomo kern_ipc_perm,
3956fc066acSJomo shm_start_paddr,
3966fc066acSJomo shm_size,
3976fc066acSJomo shm_atim: PosixTimeSpec::new(0, 0),
3986fc066acSJomo shm_dtim: PosixTimeSpec::new(0, 0),
3996fc066acSJomo shm_ctim: PosixTimeSpec::now(),
4006fc066acSJomo shm_cprid,
4016fc066acSJomo shm_lprid: shm_cprid,
4026fc066acSJomo }
4036fc066acSJomo }
4046fc066acSJomo
start_paddr(&self) -> PhysAddr4056fc066acSJomo pub fn start_paddr(&self) -> PhysAddr {
4066fc066acSJomo self.shm_start_paddr
4076fc066acSJomo }
4086fc066acSJomo
size(&self) -> usize4096fc066acSJomo pub fn size(&self) -> usize {
4106fc066acSJomo self.shm_size
4116fc066acSJomo }
4126fc066acSJomo
4136fc066acSJomo /// 更新最后连接时间
update_atim(&mut self)4146fc066acSJomo pub fn update_atim(&mut self) {
4156fc066acSJomo // 更新最后一次连接时间
4166fc066acSJomo self.shm_atim = PosixTimeSpec::now();
4176fc066acSJomo
4186fc066acSJomo // 更新最后操作当前共享内存的进程ID
4196fc066acSJomo self.shm_lprid = ProcessManager::current_pid();
4206fc066acSJomo }
4216fc066acSJomo
4226fc066acSJomo /// 更新最后断开连接时间
update_dtim(&mut self)4236fc066acSJomo pub fn update_dtim(&mut self) {
4246fc066acSJomo // 更新最后一次断开连接时间
4256fc066acSJomo self.shm_dtim = PosixTimeSpec::now();
4266fc066acSJomo
4276fc066acSJomo // 更新最后操作当前共享内存的进程ID
4286fc066acSJomo self.shm_lprid = ProcessManager::current_pid();
4296fc066acSJomo }
4306fc066acSJomo
4316fc066acSJomo /// 更新最后一次修改信息的时间
update_ctim(&mut self)4326fc066acSJomo pub fn update_ctim(&mut self) {
4336fc066acSJomo // 更新最后一次修改信息的时间
4346fc066acSJomo self.shm_ctim = PosixTimeSpec::now();
4356fc066acSJomo }
4366fc066acSJomo
4376fc066acSJomo /// 共享内存段的映射计数(有多少个不同的VMA映射)
map_count(&self) -> usize4386fc066acSJomo pub fn map_count(&self) -> usize {
439*cf7f801eSMemoryShore let mut page_manager_guard = page_manager_lock_irqsave();
4406fc066acSJomo let mut id_set: HashSet<usize> = HashSet::new();
4416fc066acSJomo let mut cur_phys = PhysPageFrame::new(self.shm_start_paddr);
4426fc066acSJomo let page_count = PageFrameCount::from_bytes(page_align_up(self.shm_size)).unwrap();
4436fc066acSJomo
4446fc066acSJomo for _ in 0..page_count.data() {
4456fc066acSJomo let page = page_manager_guard.get(&cur_phys.phys_address()).unwrap();
4466fc066acSJomo id_set.extend(
447*cf7f801eSMemoryShore page.read_irqsave()
448*cf7f801eSMemoryShore .anon_vma()
4496fc066acSJomo .iter()
4506fc066acSJomo .map(|vma| vma.id())
4516fc066acSJomo .collect::<Vec<_>>(),
4526fc066acSJomo );
4536fc066acSJomo
4546fc066acSJomo cur_phys = cur_phys.next();
4556fc066acSJomo }
4566fc066acSJomo
4576fc066acSJomo // 由于LockedVMA的id是独一无二的,因此有多少个不同的id,就代表着有多少个不同的VMA映射到共享内存段
4586fc066acSJomo return id_set.len();
4596fc066acSJomo }
4606fc066acSJomo
copy_from(&mut self, shm_id_ds: PosixShmIdDs)4616fc066acSJomo pub fn copy_from(&mut self, shm_id_ds: PosixShmIdDs) {
4626fc066acSJomo self.kern_ipc_perm.uid = shm_id_ds.uid() as usize;
4636fc066acSJomo self.kern_ipc_perm.gid = shm_id_ds.gid() as usize;
4646fc066acSJomo self.kern_ipc_perm.mode = ShmFlags::from_bits_truncate(shm_id_ds.mode());
4656fc066acSJomo self.update_ctim();
4666fc066acSJomo }
4676fc066acSJomo
set_mode(&mut self, shmflg: ShmFlags, set: bool)4686fc066acSJomo pub fn set_mode(&mut self, shmflg: ShmFlags, set: bool) {
4696fc066acSJomo if set {
4706fc066acSJomo self.kern_ipc_perm.mode.insert(shmflg);
4716fc066acSJomo } else {
4726fc066acSJomo self.kern_ipc_perm.mode.remove(shmflg);
4736fc066acSJomo }
4746fc066acSJomo
4756fc066acSJomo self.update_ctim();
4766fc066acSJomo }
4776fc066acSJomo }
4786fc066acSJomo
4796fc066acSJomo /// 共享内存权限信息
4806fc066acSJomo #[derive(Debug)]
4816fc066acSJomo pub struct KernIpcPerm {
4826fc066acSJomo /// 共享内存id
4836fc066acSJomo id: ShmId,
4846fc066acSJomo /// 共享内存键值,由创建共享内存用户指定
4856fc066acSJomo key: ShmKey,
4866fc066acSJomo /// 共享内存拥有者用户id
4876fc066acSJomo uid: usize,
4886fc066acSJomo /// 共享内存拥有者所在组id
4896fc066acSJomo gid: usize,
4906fc066acSJomo /// 共享内存创建者用户id
4916fc066acSJomo _cuid: usize,
4926fc066acSJomo /// 共享内存创建者所在组id
4936fc066acSJomo _cgid: usize,
4946fc066acSJomo /// 共享内存区权限模式
4956fc066acSJomo mode: ShmFlags,
4966fc066acSJomo _seq: usize,
4976fc066acSJomo }
4986fc066acSJomo
4996fc066acSJomo /// 共享内存元信息,符合POSIX标准
5006fc066acSJomo #[repr(C)]
5016fc066acSJomo #[derive(Debug, Clone, Copy)]
5026fc066acSJomo pub struct PosixShmMetaInfo {
5036fc066acSJomo /// 最大共享内存段的大小(bytes)
5046fc066acSJomo shmmax: usize,
5056fc066acSJomo /// 最小共享内存段的大小(bytes)
5066fc066acSJomo shmmin: usize,
5076fc066acSJomo /// 最大共享内存标识符数量
5086fc066acSJomo shmmni: usize,
5096fc066acSJomo /// 单个进程可以拥有的最大共享内存段的数量,和最大共享内存标识符数量相同
5106fc066acSJomo shmseg: usize,
5116fc066acSJomo /// 所有共享内存段总共可以使用的最大内存量(pages)
5126fc066acSJomo shmall: usize,
5136fc066acSJomo _unused1: usize,
5146fc066acSJomo _unused2: usize,
5156fc066acSJomo _unused3: usize,
5166fc066acSJomo _unused4: usize,
5176fc066acSJomo }
5186fc066acSJomo
5196fc066acSJomo impl PosixShmMetaInfo {
5206fc066acSJomo /// 最小共享内存段的大小(bytes)
5216fc066acSJomo pub const SHMMIN: usize = 1;
5226fc066acSJomo /// 最大共享内存标识符数量
5236fc066acSJomo pub const SHMMNI: usize = 4096;
5246fc066acSJomo /// 最大共享内存段的大小(bytes)
5256fc066acSJomo pub const SHMMAX: usize = usize::MAX - (1 << 24);
5266fc066acSJomo /// 所有共享内存段总共可以使用的最大内存量(pages)
5276fc066acSJomo pub const SHMALL: usize = usize::MAX - (1 << 24);
5286fc066acSJomo /// 单个进程可以拥有的最大共享内存段的数量,和最大共享内存标识符数量相同
5296fc066acSJomo pub const SHMSEG: usize = 4096;
5306fc066acSJomo
new() -> Self5316fc066acSJomo pub fn new() -> Self {
5326fc066acSJomo PosixShmMetaInfo {
5336fc066acSJomo shmmax: Self::SHMMAX,
5346fc066acSJomo shmmin: Self::SHMMIN,
5356fc066acSJomo shmmni: Self::SHMMNI,
5366fc066acSJomo shmseg: Self::SHMSEG,
5376fc066acSJomo shmall: Self::SHMALL,
5386fc066acSJomo _unused1: 0,
5396fc066acSJomo _unused2: 0,
5406fc066acSJomo _unused3: 0,
5416fc066acSJomo _unused4: 0,
5426fc066acSJomo }
5436fc066acSJomo }
5446fc066acSJomo }
5456fc066acSJomo
5466fc066acSJomo /// 共享内存信息,符合POSIX标准
5476fc066acSJomo #[repr(C)]
5486fc066acSJomo #[derive(Clone, Copy)]
5496fc066acSJomo pub struct PosixShmInfo {
5506fc066acSJomo /// 已使用id数
5516fc066acSJomo used_ids: i32,
5526fc066acSJomo /// 共享内存总量(pages)
5536fc066acSJomo shm_tot: usize,
5546fc066acSJomo /// 保留在内存中的共享内存大小
5556fc066acSJomo shm_rss: usize,
5566fc066acSJomo /// 被置换出的共享内存大小
5576fc066acSJomo shm_swp: usize,
5586fc066acSJomo /// 尝试置换次数
5596fc066acSJomo swap_attempts: usize,
5606fc066acSJomo /// 成功置换次数
5616fc066acSJomo swap_successes: usize,
5626fc066acSJomo }
5636fc066acSJomo
5646fc066acSJomo impl PosixShmInfo {
new( used_ids: i32, shm_tot: usize, shm_rss: usize, shm_swp: usize, swap_attempts: usize, swap_successes: usize, ) -> Self5656fc066acSJomo pub fn new(
5666fc066acSJomo used_ids: i32,
5676fc066acSJomo shm_tot: usize,
5686fc066acSJomo shm_rss: usize,
5696fc066acSJomo shm_swp: usize,
5706fc066acSJomo swap_attempts: usize,
5716fc066acSJomo swap_successes: usize,
5726fc066acSJomo ) -> Self {
5736fc066acSJomo PosixShmInfo {
5746fc066acSJomo used_ids,
5756fc066acSJomo shm_tot,
5766fc066acSJomo shm_rss,
5776fc066acSJomo shm_swp,
5786fc066acSJomo swap_attempts,
5796fc066acSJomo swap_successes,
5806fc066acSJomo }
5816fc066acSJomo }
5826fc066acSJomo }
5836fc066acSJomo
5846fc066acSJomo /// 共享内存段属性信息,符合POSIX标准
5856fc066acSJomo #[repr(C)]
5866fc066acSJomo #[derive(Debug, Clone, Copy, Default)]
5876fc066acSJomo pub struct PosixShmIdDs {
5886fc066acSJomo /// 共享内存段权限
5896fc066acSJomo shm_perm: PosixIpcPerm,
5906fc066acSJomo /// 共享内存大小(bytes)
5916fc066acSJomo shm_segsz: usize,
5926fc066acSJomo /// 最后一次连接的时间
5936fc066acSJomo shm_atime: i64,
5946fc066acSJomo /// 最后一次断开连接的时间
5956fc066acSJomo shm_dtime: i64,
5966fc066acSJomo /// 最后一次更改信息的时间
5976fc066acSJomo shm_ctime: i64,
5986fc066acSJomo /// 创建者进程id
5996fc066acSJomo shm_cpid: u32,
6006fc066acSJomo /// 最后操作者进程id
6016fc066acSJomo shm_lpid: u32,
6026fc066acSJomo /// 链接数
6036fc066acSJomo shm_map_count: usize,
6046fc066acSJomo _unused1: usize,
6056fc066acSJomo _unused2: usize,
6066fc066acSJomo }
6076fc066acSJomo
6086fc066acSJomo impl PosixShmIdDs {
uid(&self) -> u326096fc066acSJomo pub fn uid(&self) -> u32 {
6106fc066acSJomo self.shm_perm.uid
6116fc066acSJomo }
6126fc066acSJomo
gid(&self) -> u326136fc066acSJomo pub fn gid(&self) -> u32 {
6146fc066acSJomo self.shm_perm.gid
6156fc066acSJomo }
6166fc066acSJomo
mode(&self) -> u326176fc066acSJomo pub fn mode(&self) -> u32 {
6186fc066acSJomo self.shm_perm.mode
6196fc066acSJomo }
6206fc066acSJomo }
6216fc066acSJomo
6226fc066acSJomo /// 共享内存段权限,符合POSIX标准
6236fc066acSJomo #[repr(C)]
6246fc066acSJomo #[derive(Debug, Clone, Copy, Default)]
6256fc066acSJomo pub struct PosixIpcPerm {
6266fc066acSJomo /// IPC对象键值
6276fc066acSJomo key: i32,
6286fc066acSJomo /// 当前用户id
6296fc066acSJomo uid: u32,
6306fc066acSJomo /// 当前用户组id
6316fc066acSJomo gid: u32,
6326fc066acSJomo /// 创建者用户id
6336fc066acSJomo cuid: u32,
6346fc066acSJomo /// 创建者组id
6356fc066acSJomo cgid: u32,
6366fc066acSJomo /// 权限
6376fc066acSJomo mode: u32,
6386fc066acSJomo /// 序列号
6396fc066acSJomo seq: i32,
6406fc066acSJomo _pad1: i32,
6416fc066acSJomo _unused1: usize,
6426fc066acSJomo _unused2: usize,
6436fc066acSJomo }
6446fc066acSJomo
6456fc066acSJomo impl PosixIpcPerm {
new(key: i32, uid: u32, gid: u32, cuid: u32, cgid: u32, mode: u32) -> Self6466fc066acSJomo pub fn new(key: i32, uid: u32, gid: u32, cuid: u32, cgid: u32, mode: u32) -> Self {
6476fc066acSJomo PosixIpcPerm {
6486fc066acSJomo key,
6496fc066acSJomo uid,
6506fc066acSJomo gid,
6516fc066acSJomo cuid,
6526fc066acSJomo cgid,
6536fc066acSJomo mode,
6546fc066acSJomo seq: 0,
6556fc066acSJomo _pad1: 0,
6566fc066acSJomo _unused1: 0,
6576fc066acSJomo _unused2: 0,
6586fc066acSJomo }
6596fc066acSJomo }
6606fc066acSJomo }
661