mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
实现SystemV共享内存 (#690)
* 实现SystemV共享内存 * 测试shm * 添加测试程序 * 完善细节 * 修正shm的时间数据错误的问题 * fix: devfs的metadata权限为0x777的错误 --------- Co-authored-by: longjin <longjin@DragonOS.org>
This commit is contained in:
parent
eb49bb993a
commit
6fc066ac11
@ -602,7 +602,8 @@ pub fn test_buddy() {
|
||||
pub struct LockedFrameAllocator;
|
||||
|
||||
impl FrameAllocator for LockedFrameAllocator {
|
||||
unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
|
||||
unsafe fn allocate(&mut self, mut count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
|
||||
count = count.next_power_of_two();
|
||||
if let Some(ref mut allocator) = *INNER_ALLOCATOR.lock_irqsave() {
|
||||
return allocator.allocate(count);
|
||||
} else {
|
||||
|
@ -7,7 +7,7 @@ use crate::filesystem::vfs::{
|
||||
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
|
||||
};
|
||||
use crate::libs::spinlock::SpinLockGuard;
|
||||
use crate::{libs::spinlock::SpinLock, time::TimeSpec};
|
||||
use crate::{libs::spinlock::SpinLock, time::PosixTimeSpec};
|
||||
use alloc::{
|
||||
string::String,
|
||||
sync::{Arc, Weak},
|
||||
@ -47,9 +47,9 @@ impl LockedAhciInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::BlockDevice, // 文件夹,block设备,char设备
|
||||
mode: ModeType::from_bits_truncate(0o666),
|
||||
nlinks: 1,
|
||||
|
@ -38,7 +38,7 @@ use crate::{
|
||||
rwlock::{RwLockReadGuard, RwLockWriteGuard},
|
||||
spinlock::{SpinLock, SpinLockGuard},
|
||||
},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
static mut PS2_MOUSE_DEVICE: Option<Arc<Ps2MouseDevice>> = None;
|
||||
@ -199,9 +199,9 @@ impl Ps2MouseDevice {
|
||||
size: 4096,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
||||
mode: ModeType::from_bits_truncate(0o644),
|
||||
nlinks: 1,
|
||||
|
@ -32,7 +32,7 @@ use crate::{
|
||||
rwlock::RwLock,
|
||||
spinlock::{SpinLock, SpinLockGuard},
|
||||
},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
use system_error::SystemError;
|
||||
|
||||
@ -83,9 +83,9 @@ impl LockedPS2KeyBoardInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
||||
mode: ModeType::from_bits_truncate(0o666),
|
||||
nlinks: 1,
|
||||
|
@ -3,7 +3,7 @@ use crate::arch::mm::kernel_page_flags;
|
||||
use crate::arch::MMArch;
|
||||
|
||||
use crate::mm::kernel_mapper::KernelMapper;
|
||||
use crate::mm::page::{page_manager_lock_irasave, PageFlags};
|
||||
use crate::mm::page::{page_manager_lock_irqsave, PageFlags};
|
||||
use crate::mm::{
|
||||
allocator::page_frame::{
|
||||
allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame,
|
||||
@ -60,7 +60,7 @@ pub unsafe fn dma_dealloc(paddr: usize, vaddr: NonNull<u8>, pages: usize) -> i32
|
||||
deallocate_page_frames(
|
||||
PhysPageFrame::new(PhysAddr::new(paddr)),
|
||||
page_count,
|
||||
&mut page_manager_lock_irasave(),
|
||||
&mut page_manager_lock_irqsave(),
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
subsys::SubSysPrivate,
|
||||
},
|
||||
init::initcall::INITCALL_SUBSYS,
|
||||
time::{timekeeping::do_settimeofday64, TimeSpec},
|
||||
time::{timekeeping::do_settimeofday64, PosixTimeSpec},
|
||||
};
|
||||
|
||||
use super::{interface::rtc_read_time, register_default_rtc, sysfs::RtcGeneralDevice};
|
||||
@ -96,7 +96,7 @@ fn rtc_hctosys(dev: &Arc<RtcGeneralDevice>) {
|
||||
}
|
||||
|
||||
let time = r.unwrap();
|
||||
let timespec64: TimeSpec = time.into();
|
||||
let timespec64: PosixTimeSpec = time.into();
|
||||
let r = do_settimeofday64(timespec64);
|
||||
dev.set_hc2sys_result(r);
|
||||
|
||||
|
@ -5,7 +5,7 @@ use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
libs::rwlock::RwLock,
|
||||
time::{Instant, TimeSpec, NSEC_PER_SEC},
|
||||
time::{Instant, PosixTimeSpec, NSEC_PER_SEC},
|
||||
};
|
||||
|
||||
use self::sysfs::RtcGeneralDevice;
|
||||
@ -137,7 +137,7 @@ impl RtcTime {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RtcTime> for TimeSpec {
|
||||
impl From<RtcTime> for PosixTimeSpec {
|
||||
fn from(val: RtcTime) -> Self {
|
||||
let instant = Instant::mktime64(
|
||||
val.year_real() as u32,
|
||||
@ -155,7 +155,7 @@ impl From<RtcTime> for TimeSpec {
|
||||
* 存储最接近的值会减慢同步 API 的速度。因此,这里我们存储截断的值
|
||||
* 并在后面加上 0.5s 的最佳猜测。
|
||||
*/
|
||||
TimeSpec::new(instant.secs(), (NSEC_PER_SEC >> 1).into())
|
||||
PosixTimeSpec::new(instant.secs(), (NSEC_PER_SEC >> 1).into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ use crate::arch::mm::kernel_page_flags;
|
||||
use crate::arch::MMArch;
|
||||
|
||||
use crate::mm::kernel_mapper::KernelMapper;
|
||||
use crate::mm::page::{page_manager_lock_irasave, PageFlags};
|
||||
use crate::mm::page::{page_manager_lock_irqsave, PageFlags};
|
||||
use crate::mm::{
|
||||
allocator::page_frame::{
|
||||
allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame,
|
||||
@ -71,7 +71,7 @@ unsafe impl Hal for HalImpl {
|
||||
deallocate_page_frames(
|
||||
PhysPageFrame::new(PhysAddr::new(paddr)),
|
||||
page_count,
|
||||
&mut page_manager_lock_irasave(),
|
||||
&mut page_manager_lock_irqsave(),
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
once::Once,
|
||||
spinlock::{SpinLock, SpinLockGuard},
|
||||
},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
use alloc::{
|
||||
collections::BTreeMap,
|
||||
@ -273,9 +273,9 @@ impl DevFSInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: dev_type_, // 文件夹
|
||||
mode,
|
||||
nlinks: 1,
|
||||
@ -363,9 +363,9 @@ impl LockedDevFSInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type,
|
||||
mode,
|
||||
nlinks: 1,
|
||||
|
@ -5,7 +5,7 @@ use crate::filesystem::vfs::{
|
||||
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
|
||||
};
|
||||
use crate::libs::spinlock::SpinLockGuard;
|
||||
use crate::{libs::spinlock::SpinLock, time::TimeSpec};
|
||||
use crate::{libs::spinlock::SpinLock, time::PosixTimeSpec};
|
||||
use alloc::{
|
||||
string::String,
|
||||
sync::{Arc, Weak},
|
||||
@ -42,9 +42,9 @@ impl LockedNullInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
||||
mode: ModeType::from_bits_truncate(0o666),
|
||||
nlinks: 1,
|
||||
|
@ -5,7 +5,7 @@ use crate::filesystem::vfs::{
|
||||
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
|
||||
};
|
||||
use crate::libs::spinlock::SpinLockGuard;
|
||||
use crate::{libs::spinlock::SpinLock, time::TimeSpec};
|
||||
use crate::{libs::spinlock::SpinLock, time::PosixTimeSpec};
|
||||
use alloc::{
|
||||
string::String,
|
||||
sync::{Arc, Weak},
|
||||
@ -42,9 +42,9 @@ impl LockedZeroInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::CharDevice, // 文件夹,block设备,char设备
|
||||
mode: ModeType::from_bits_truncate(0o666),
|
||||
nlinks: 1,
|
||||
|
@ -24,7 +24,7 @@ use crate::{
|
||||
filesystem::vfs::{syscall::ModeType, FileType, ROOT_INODE},
|
||||
init::initcall::INITCALL_FS,
|
||||
libs::spinlock::{SpinLock, SpinLockGuard},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
use super::vfs::{
|
||||
@ -105,11 +105,11 @@ impl LockedDevPtsFSInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::Dir,
|
||||
mode: ModeType::from_bits_truncate(0x777),
|
||||
mode: ModeType::from_bits_truncate(0o777),
|
||||
nlinks: 1,
|
||||
uid: 0,
|
||||
gid: 0,
|
||||
|
@ -26,7 +26,7 @@ use crate::{
|
||||
spinlock::{SpinLock, SpinLockGuard},
|
||||
vec_cursor::VecCursor,
|
||||
},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
use super::entry::FATFile;
|
||||
@ -195,9 +195,9 @@ impl LockedFATInode {
|
||||
} else {
|
||||
fs.bpb.total_sectors_16 as usize
|
||||
},
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type,
|
||||
mode: ModeType::from_bits_truncate(0o777),
|
||||
nlinks: 1,
|
||||
@ -327,9 +327,9 @@ impl FATFileSystem {
|
||||
} else {
|
||||
bpb.total_sectors_16 as usize
|
||||
},
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::Dir,
|
||||
mode: ModeType::from_bits_truncate(0o777),
|
||||
nlinks: 1,
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
rwlock::RwLock,
|
||||
spinlock::{SpinLock, SpinLockGuard},
|
||||
},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
use self::callback::{KernCallbackData, KernFSCallback, KernInodePrivateData};
|
||||
@ -90,9 +90,9 @@ impl KernFS {
|
||||
gid: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::new(0, 0),
|
||||
mtime: TimeSpec::new(0, 0),
|
||||
ctime: TimeSpec::new(0, 0),
|
||||
atime: PosixTimeSpec::new(0, 0),
|
||||
mtime: PosixTimeSpec::new(0, 0),
|
||||
ctime: PosixTimeSpec::new(0, 0),
|
||||
dev_id: 0,
|
||||
inode_id: generate_inode_id(),
|
||||
file_type: FileType::Dir,
|
||||
@ -526,9 +526,9 @@ impl KernFSInode {
|
||||
gid: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::new(0, 0),
|
||||
mtime: TimeSpec::new(0, 0),
|
||||
ctime: TimeSpec::new(0, 0),
|
||||
atime: PosixTimeSpec::new(0, 0),
|
||||
mtime: PosixTimeSpec::new(0, 0),
|
||||
ctime: PosixTimeSpec::new(0, 0),
|
||||
dev_id: 0,
|
||||
inode_id: generate_inode_id(),
|
||||
file_type: file_type.into(),
|
||||
|
@ -2,7 +2,7 @@ use core::fmt::{Display, Formatter, Result};
|
||||
|
||||
use alloc::string::String;
|
||||
|
||||
use crate::time::TimeSpec;
|
||||
use crate::time::PosixTimeSpec;
|
||||
|
||||
// /// 日志类型
|
||||
// #[derive(Default, Clone, Debug)]
|
||||
@ -58,7 +58,7 @@ impl From<usize> for LogLevel {
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct LogMessage {
|
||||
/// 时间戳
|
||||
timestamp: TimeSpec,
|
||||
timestamp: PosixTimeSpec,
|
||||
/// 日志级别
|
||||
level: LogLevel,
|
||||
// /// 日志类型
|
||||
@ -68,7 +68,7 @@ pub struct LogMessage {
|
||||
}
|
||||
|
||||
impl LogMessage {
|
||||
pub fn new(timestamp: TimeSpec, level: LogLevel, message: String) -> Self {
|
||||
pub fn new(timestamp: PosixTimeSpec, level: LogLevel, message: String) -> Self {
|
||||
LogMessage {
|
||||
timestamp,
|
||||
level,
|
||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||
},
|
||||
mm::allocator::page_frame::FrameAllocator,
|
||||
process::{Pid, ProcessManager},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
use super::vfs::{
|
||||
@ -314,9 +314,9 @@ impl ProcFS {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::Dir,
|
||||
mode: ModeType::from_bits_truncate(0o555),
|
||||
nlinks: 1,
|
||||
@ -600,9 +600,9 @@ impl IndexNode for LockedProcFSInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type,
|
||||
mode,
|
||||
nlinks: 1,
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
ipc::pipe::LockedPipeInode,
|
||||
libs::casting::DowncastArc,
|
||||
libs::spinlock::{SpinLock, SpinLockGuard},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
use alloc::{
|
||||
@ -110,9 +110,9 @@ impl RamFS {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::Dir,
|
||||
mode: ModeType::from_bits_truncate(0o777),
|
||||
nlinks: 1,
|
||||
@ -310,9 +310,9 @@ impl IndexNode for LockedRamFSInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type,
|
||||
mode,
|
||||
nlinks: 1,
|
||||
@ -545,9 +545,9 @@ impl IndexNode for LockedRamFSInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::Pipe,
|
||||
mode,
|
||||
nlinks: 1,
|
||||
|
@ -20,7 +20,7 @@ use crate::{
|
||||
casting::DowncastArc,
|
||||
spinlock::{SpinLock, SpinLockGuard},
|
||||
},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
use self::{core::generate_inode_id, file::FileMode, syscall::ModeType};
|
||||
@ -549,13 +549,13 @@ pub struct Metadata {
|
||||
pub blocks: usize,
|
||||
|
||||
/// inode最后一次被访问的时间
|
||||
pub atime: TimeSpec,
|
||||
pub atime: PosixTimeSpec,
|
||||
|
||||
/// inode最后一次修改的时间
|
||||
pub mtime: TimeSpec,
|
||||
pub mtime: PosixTimeSpec,
|
||||
|
||||
/// inode的创建时间
|
||||
pub ctime: TimeSpec,
|
||||
pub ctime: PosixTimeSpec,
|
||||
|
||||
/// 文件类型
|
||||
pub file_type: FileType,
|
||||
@ -584,9 +584,9 @@ impl Default for Metadata {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::File,
|
||||
mode: ModeType::empty(),
|
||||
nlinks: 1,
|
||||
@ -701,9 +701,9 @@ impl Metadata {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type,
|
||||
mode,
|
||||
nlinks: 1,
|
||||
|
@ -17,7 +17,7 @@ use crate::{
|
||||
user_access::{self, check_and_clone_cstr, UserBufferWriter},
|
||||
Syscall,
|
||||
},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
use super::SuperBlock;
|
||||
@ -110,11 +110,11 @@ pub struct PosixKstat {
|
||||
/// 分配的512B块数
|
||||
blocks: u64,
|
||||
/// 最后访问时间
|
||||
atime: TimeSpec,
|
||||
atime: PosixTimeSpec,
|
||||
/// 最后修改时间
|
||||
mtime: TimeSpec,
|
||||
mtime: PosixTimeSpec,
|
||||
/// 最后状态变化时间
|
||||
ctime: TimeSpec,
|
||||
ctime: PosixTimeSpec,
|
||||
/// 用于填充结构体大小的空白数据
|
||||
pub _pad: [i8; 24],
|
||||
}
|
||||
@ -129,15 +129,15 @@ impl PosixKstat {
|
||||
gid: 0,
|
||||
rdev: 0,
|
||||
size: 0,
|
||||
atime: TimeSpec {
|
||||
atime: PosixTimeSpec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
},
|
||||
mtime: TimeSpec {
|
||||
mtime: PosixTimeSpec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
},
|
||||
ctime: TimeSpec {
|
||||
ctime: PosixTimeSpec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
},
|
||||
@ -180,13 +180,13 @@ pub struct PosixStatx {
|
||||
|
||||
/* 0x40 */
|
||||
/// 最后访问时间
|
||||
stx_atime: TimeSpec,
|
||||
stx_atime: PosixTimeSpec,
|
||||
/// 文件创建时间
|
||||
stx_btime: TimeSpec,
|
||||
stx_btime: PosixTimeSpec,
|
||||
/// 最后状态变化时间
|
||||
stx_ctime: TimeSpec,
|
||||
stx_ctime: PosixTimeSpec,
|
||||
/// 最后修改时间
|
||||
stx_mtime: TimeSpec,
|
||||
stx_mtime: PosixTimeSpec,
|
||||
|
||||
/* 0x80 */
|
||||
/// 主设备ID
|
||||
@ -217,19 +217,19 @@ impl PosixStatx {
|
||||
stx_size: 0,
|
||||
stx_blocks: 0,
|
||||
stx_attributes_mask: StxAttributes::STATX_ATTR_APPEND,
|
||||
stx_atime: TimeSpec {
|
||||
stx_atime: PosixTimeSpec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
},
|
||||
stx_btime: TimeSpec {
|
||||
stx_btime: PosixTimeSpec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
},
|
||||
stx_ctime: TimeSpec {
|
||||
stx_ctime: PosixTimeSpec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
},
|
||||
stx_mtime: TimeSpec {
|
||||
stx_mtime: PosixTimeSpec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
},
|
||||
|
@ -1,4 +1,5 @@
|
||||
pub mod pipe;
|
||||
pub mod shm;
|
||||
pub mod signal;
|
||||
pub mod signal_types;
|
||||
pub mod syscall;
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
net::event_poll::{EPollEventType, EPollItem, EventPoll},
|
||||
process::ProcessState,
|
||||
sched::{schedule, SchedMode},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
use alloc::{
|
||||
@ -121,9 +121,9 @@ impl LockedPipeInode {
|
||||
size: PIPE_BUFF_SIZE as i64,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::Pipe,
|
||||
mode: ModeType::from_bits_truncate(0o666),
|
||||
nlinks: 1,
|
||||
|
658
kernel/src/ipc/shm.rs
Normal file
658
kernel/src/ipc/shm.rs
Normal file
@ -0,0 +1,658 @@
|
||||
use crate::{
|
||||
arch::mm::LockedFrameAllocator,
|
||||
filesystem::vfs::syscall::ModeType,
|
||||
libs::{
|
||||
align::page_align_up,
|
||||
spinlock::{SpinLock, SpinLockGuard},
|
||||
},
|
||||
mm::{
|
||||
allocator::page_frame::{FrameAllocator, PageFrameCount, PhysPageFrame},
|
||||
page::{page_manager_lock_irqsave, Page},
|
||||
PhysAddr,
|
||||
},
|
||||
process::{Pid, ProcessManager},
|
||||
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use ida::IdAllocator;
|
||||
use num::ToPrimitive;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub static mut SHM_MANAGER: Option<SpinLock<ShmManager>> = None;
|
||||
|
||||
/// 用于创建新的私有IPC对象
|
||||
pub const IPC_PRIVATE: ShmKey = ShmKey::new(0);
|
||||
|
||||
/// 初始化SHM_MANAGER
|
||||
pub fn shm_manager_init() {
|
||||
kinfo!("shm_manager_init");
|
||||
let shm_manager = SpinLock::new(ShmManager::new());
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
unsafe { SHM_MANAGER = Some(shm_manager) };
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
kinfo!("shm_manager_init done");
|
||||
}
|
||||
|
||||
pub fn shm_manager_lock() -> SpinLockGuard<'static, ShmManager> {
|
||||
unsafe { SHM_MANAGER.as_ref().unwrap().lock() }
|
||||
}
|
||||
|
||||
int_like!(ShmId, usize);
|
||||
int_like!(ShmKey, usize);
|
||||
|
||||
bitflags! {
|
||||
pub struct ShmFlags:u32{
|
||||
const SHM_RDONLY = 0o10000;
|
||||
const SHM_RND = 0o20000;
|
||||
const SHM_REMAP = 0o40000;
|
||||
const SHM_EXEC = 0o100000;
|
||||
const SHM_HUGETLB = 0o4000;
|
||||
|
||||
const IPC_CREAT = 0o1000;
|
||||
const IPC_EXCL = 0o2000;
|
||||
|
||||
const SHM_DEST = 0o1000;
|
||||
const SHM_LOCKED = 0o2000;
|
||||
}
|
||||
}
|
||||
|
||||
/// 管理共享内存段信息的操作码
|
||||
#[derive(Eq, Clone, Copy)]
|
||||
pub enum ShmCtlCmd {
|
||||
/// 删除共享内存段
|
||||
IpcRmid = 0,
|
||||
/// 设置KernIpcPerm选项
|
||||
IpcSet = 1,
|
||||
/// 获取ShmIdDs
|
||||
IpcStat = 2,
|
||||
/// 查看ShmMetaData
|
||||
IpcInfo = 3,
|
||||
|
||||
/// 不允许共享内存段被置换出物理内存
|
||||
ShmLock = 11,
|
||||
/// 允许共享内存段被置换出物理内存
|
||||
ShmUnlock = 12,
|
||||
/// 查看ShmMetaData
|
||||
ShmStat = 13,
|
||||
/// 查看ShmInfo
|
||||
ShmInfo = 14,
|
||||
/// 查看ShmMetaData
|
||||
ShmtStatAny = 15,
|
||||
|
||||
Default,
|
||||
}
|
||||
|
||||
impl From<usize> for ShmCtlCmd {
|
||||
fn from(cmd: usize) -> ShmCtlCmd {
|
||||
match cmd {
|
||||
0 => Self::IpcRmid,
|
||||
1 => Self::IpcSet,
|
||||
2 => Self::IpcStat,
|
||||
3 => Self::IpcInfo,
|
||||
11 => Self::ShmLock,
|
||||
12 => Self::ShmUnlock,
|
||||
13 => Self::ShmStat,
|
||||
14 => Self::ShmInfo,
|
||||
15 => Self::ShmtStatAny,
|
||||
_ => Self::Default,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for ShmCtlCmd {
|
||||
fn eq(&self, other: &ShmCtlCmd) -> bool {
|
||||
*self as usize == *other as usize
|
||||
}
|
||||
}
|
||||
|
||||
/// 共享内存管理器
|
||||
#[derive(Debug)]
|
||||
pub struct ShmManager {
|
||||
/// ShmId分配器
|
||||
id_allocator: IdAllocator,
|
||||
/// ShmId映射共享内存信息表
|
||||
id2shm: HashMap<ShmId, KernelShm>,
|
||||
/// ShmKey映射ShmId表
|
||||
key2id: HashMap<ShmKey, ShmId>,
|
||||
}
|
||||
|
||||
impl ShmManager {
|
||||
pub fn new() -> Self {
|
||||
ShmManager {
|
||||
id_allocator: IdAllocator::new(0, usize::MAX - 1),
|
||||
id2shm: HashMap::new(),
|
||||
key2id: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// # 添加共享内存段
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `key`: 共享内存键值
|
||||
/// - `size`: 共享内存大小
|
||||
/// - `shmflg`: 共享内存标志
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:共享内存id
|
||||
/// 失败:对应错误码
|
||||
pub fn add(
|
||||
&mut self,
|
||||
key: ShmKey,
|
||||
size: usize,
|
||||
shmflg: ShmFlags,
|
||||
) -> Result<usize, SystemError> {
|
||||
// 判断共享内存大小是否过小或溢出
|
||||
if !(PosixShmMetaInfo::SHMMIN..=PosixShmMetaInfo::SHMMAX).contains(&size) {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let id = self.id_allocator.alloc().expect("No more id to allocate.");
|
||||
let shm_id = ShmId::new(id);
|
||||
|
||||
// 分配共享内存页面
|
||||
let page_count = PageFrameCount::from_bytes(page_align_up(size)).unwrap();
|
||||
let phys_page =
|
||||
unsafe { LockedFrameAllocator.allocate(page_count) }.ok_or(SystemError::EINVAL)?;
|
||||
// 创建共享内存page,并添加到PAGE_MANAGER中
|
||||
let mut page_manager_guard = page_manager_lock_irqsave();
|
||||
let mut cur_phys = PhysPageFrame::new(phys_page.0);
|
||||
for _ in 0..page_count.data() {
|
||||
let mut page = Page::new(true);
|
||||
page.set_shm_id(shm_id);
|
||||
let paddr = cur_phys.phys_address();
|
||||
page_manager_guard.insert(paddr, page);
|
||||
cur_phys = cur_phys.next();
|
||||
}
|
||||
|
||||
// 创建共享内存信息结构体
|
||||
let paddr = phys_page.0;
|
||||
let kern_ipc_perm = KernIpcPerm {
|
||||
id: shm_id,
|
||||
key,
|
||||
uid: 0,
|
||||
gid: 0,
|
||||
_cuid: 0,
|
||||
_cgid: 0,
|
||||
mode: shmflg & ShmFlags::from_bits_truncate(ModeType::S_IRWXUGO.bits()),
|
||||
_seq: 0,
|
||||
};
|
||||
let shm_kernel = KernelShm::new(kern_ipc_perm, paddr, size);
|
||||
|
||||
// 将key、id及其对应KernelShm添加到表中
|
||||
self.id2shm.insert(shm_id, shm_kernel);
|
||||
self.key2id.insert(key, shm_id);
|
||||
|
||||
return Ok(shm_id.data());
|
||||
}
|
||||
|
||||
pub fn contains_key(&self, key: &ShmKey) -> Option<&ShmId> {
|
||||
self.key2id.get(key)
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, id: &ShmId) -> Option<&mut KernelShm> {
|
||||
self.id2shm.get_mut(id)
|
||||
}
|
||||
|
||||
pub fn free_key(&mut self, key: &ShmKey) {
|
||||
self.key2id.remove(key);
|
||||
}
|
||||
|
||||
pub fn free_id(&mut self, id: &ShmId) {
|
||||
self.id2shm.remove(id);
|
||||
self.id_allocator.free(id.0);
|
||||
}
|
||||
|
||||
pub fn ipc_info(&self, user_buf: *const u8, from_user: bool) -> Result<usize, SystemError> {
|
||||
let mut user_buffer_writer = UserBufferWriter::new(
|
||||
user_buf as *mut u8,
|
||||
core::mem::size_of::<PosixShmMetaInfo>(),
|
||||
from_user,
|
||||
)?;
|
||||
|
||||
let shm_meta_info = PosixShmMetaInfo::new();
|
||||
user_buffer_writer.copy_one_to_user(&shm_meta_info, 0)?;
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn shm_info(&self, user_buf: *const u8, from_user: bool) -> Result<usize, SystemError> {
|
||||
// 已使用id数量
|
||||
let used_ids = self.id2shm.len().to_i32().unwrap();
|
||||
// 共享内存总和
|
||||
let shm_tot = self.id2shm.iter().fold(0, |acc, (_, kernel_shm)| {
|
||||
acc + PageFrameCount::from_bytes(page_align_up(kernel_shm.shm_size))
|
||||
.unwrap()
|
||||
.data()
|
||||
});
|
||||
let shm_info = PosixShmInfo::new(used_ids, shm_tot, 0, 0, 0, 0);
|
||||
|
||||
let mut user_buffer_writer = UserBufferWriter::new(
|
||||
user_buf as *mut u8,
|
||||
core::mem::size_of::<PosixShmInfo>(),
|
||||
from_user,
|
||||
)?;
|
||||
user_buffer_writer.copy_one_to_user(&shm_info, 0)?;
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn shm_stat(
|
||||
&self,
|
||||
id: ShmId,
|
||||
cmd: ShmCtlCmd,
|
||||
user_buf: *const u8,
|
||||
from_user: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
let kernel_shm = self.id2shm.get(&id).ok_or(SystemError::EINVAL)?;
|
||||
let key = kernel_shm.kern_ipc_perm.key.data().to_i32().unwrap();
|
||||
let mode = kernel_shm.kern_ipc_perm.mode.bits();
|
||||
|
||||
let shm_perm = PosixIpcPerm::new(key, 0, 0, 0, 0, mode);
|
||||
let shm_segsz = kernel_shm.shm_size;
|
||||
let shm_atime = kernel_shm.shm_atim.total_nanos();
|
||||
let shm_dtime = kernel_shm.shm_dtim.total_nanos();
|
||||
let shm_ctime = kernel_shm.shm_ctim.total_nanos();
|
||||
let shm_cpid = kernel_shm.shm_cprid.data().to_u32().unwrap();
|
||||
let shm_lpid = kernel_shm.shm_lprid.data().to_u32().unwrap();
|
||||
let shm_map_count = kernel_shm.map_count();
|
||||
let shm_id_ds = PosixShmIdDs {
|
||||
shm_perm,
|
||||
shm_segsz,
|
||||
shm_atime,
|
||||
shm_dtime,
|
||||
shm_ctime,
|
||||
shm_cpid,
|
||||
shm_lpid,
|
||||
shm_map_count,
|
||||
_unused1: 0,
|
||||
_unused2: 0,
|
||||
};
|
||||
|
||||
let mut user_buffer_writer = UserBufferWriter::new(
|
||||
user_buf as *mut u8,
|
||||
core::mem::size_of::<PosixShmIdDs>(),
|
||||
from_user,
|
||||
)?;
|
||||
user_buffer_writer.copy_one_to_user(&shm_id_ds, 0)?;
|
||||
|
||||
let r: usize = if cmd == ShmCtlCmd::IpcStat {
|
||||
0
|
||||
} else {
|
||||
id.data()
|
||||
};
|
||||
|
||||
return Ok(r);
|
||||
}
|
||||
|
||||
pub fn ipc_set(
|
||||
&mut self,
|
||||
id: ShmId,
|
||||
user_buf: *const u8,
|
||||
from_user: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
|
||||
|
||||
let user_buffer_reader =
|
||||
UserBufferReader::new(user_buf, core::mem::size_of::<PosixShmIdDs>(), from_user)?;
|
||||
let mut shm_id_ds = PosixShmIdDs::default();
|
||||
user_buffer_reader.copy_one_from_user(&mut shm_id_ds, 0)?;
|
||||
|
||||
kernel_shm.copy_from(shm_id_ds);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn ipc_rmid(&mut self, id: ShmId) -> Result<usize, SystemError> {
|
||||
let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
|
||||
kernel_shm.set_mode(ShmFlags::SHM_DEST, true);
|
||||
|
||||
let mut cur_phys = PhysPageFrame::new(kernel_shm.shm_start_paddr);
|
||||
let count = PageFrameCount::from_bytes(page_align_up(kernel_shm.shm_size)).unwrap();
|
||||
let key = kernel_shm.kern_ipc_perm.key;
|
||||
let id = kernel_shm.kern_ipc_perm.id;
|
||||
let map_count = kernel_shm.map_count();
|
||||
|
||||
let mut page_manager_guard = page_manager_lock_irqsave();
|
||||
if map_count > 0 {
|
||||
// 设置共享内存物理页当映射计数等于0时可被回收
|
||||
for _ in 0..count.data() {
|
||||
let page = page_manager_guard.get_mut(&cur_phys.phys_address());
|
||||
page.set_dealloc_when_zero(true);
|
||||
|
||||
cur_phys = cur_phys.next();
|
||||
}
|
||||
|
||||
// 释放key,不让后续进程连接
|
||||
self.free_key(&key);
|
||||
} else {
|
||||
// 释放共享内存物理页
|
||||
for _ in 0..count.data() {
|
||||
let paddr = cur_phys.phys_address();
|
||||
unsafe {
|
||||
LockedFrameAllocator.free(paddr, PageFrameCount::new(1));
|
||||
}
|
||||
// 将已回收的物理页面对应的Page从PAGE_MANAGER中删去
|
||||
page_manager_guard.remove_page(&paddr);
|
||||
cur_phys = cur_phys.next();
|
||||
}
|
||||
|
||||
// 释放key和id
|
||||
self.free_id(&id);
|
||||
self.free_key(&key)
|
||||
}
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn shm_lock(&mut self, id: ShmId) -> Result<usize, SystemError> {
|
||||
let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
|
||||
kernel_shm.set_mode(ShmFlags::SHM_LOCKED, true);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn shm_unlock(&mut self, id: ShmId) -> Result<usize, SystemError> {
|
||||
let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?;
|
||||
kernel_shm.set_mode(ShmFlags::SHM_LOCKED, false);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
||||
/// 共享内存信息
|
||||
#[derive(Debug)]
|
||||
pub struct KernelShm {
|
||||
/// 权限信息
|
||||
kern_ipc_perm: KernIpcPerm,
|
||||
/// 共享内存起始物理地址
|
||||
shm_start_paddr: PhysAddr,
|
||||
/// 共享内存大小(bytes),注意是用户指定的大小(未经过页面对齐)
|
||||
shm_size: usize,
|
||||
/// 最后一次连接的时间
|
||||
shm_atim: PosixTimeSpec,
|
||||
/// 最后一次断开连接的时间
|
||||
shm_dtim: PosixTimeSpec,
|
||||
/// 最后一次更改信息的时间
|
||||
shm_ctim: PosixTimeSpec,
|
||||
/// 创建者进程id
|
||||
shm_cprid: Pid,
|
||||
/// 最后操作者进程id
|
||||
shm_lprid: Pid,
|
||||
}
|
||||
|
||||
impl KernelShm {
|
||||
pub fn new(kern_ipc_perm: KernIpcPerm, shm_start_paddr: PhysAddr, shm_size: usize) -> Self {
|
||||
let shm_cprid = ProcessManager::current_pid();
|
||||
KernelShm {
|
||||
kern_ipc_perm,
|
||||
shm_start_paddr,
|
||||
shm_size,
|
||||
shm_atim: PosixTimeSpec::new(0, 0),
|
||||
shm_dtim: PosixTimeSpec::new(0, 0),
|
||||
shm_ctim: PosixTimeSpec::now(),
|
||||
shm_cprid,
|
||||
shm_lprid: shm_cprid,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_paddr(&self) -> PhysAddr {
|
||||
self.shm_start_paddr
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
self.shm_size
|
||||
}
|
||||
|
||||
/// 更新最后连接时间
|
||||
pub fn update_atim(&mut self) {
|
||||
// 更新最后一次连接时间
|
||||
self.shm_atim = PosixTimeSpec::now();
|
||||
|
||||
// 更新最后操作当前共享内存的进程ID
|
||||
self.shm_lprid = ProcessManager::current_pid();
|
||||
}
|
||||
|
||||
/// 更新最后断开连接时间
|
||||
pub fn update_dtim(&mut self) {
|
||||
// 更新最后一次断开连接时间
|
||||
self.shm_dtim = PosixTimeSpec::now();
|
||||
|
||||
// 更新最后操作当前共享内存的进程ID
|
||||
self.shm_lprid = ProcessManager::current_pid();
|
||||
}
|
||||
|
||||
/// 更新最后一次修改信息的时间
|
||||
pub fn update_ctim(&mut self) {
|
||||
// 更新最后一次修改信息的时间
|
||||
self.shm_ctim = PosixTimeSpec::now();
|
||||
}
|
||||
|
||||
/// 共享内存段的映射计数(有多少个不同的VMA映射)
|
||||
pub fn map_count(&self) -> usize {
|
||||
let page_manager_guard = page_manager_lock_irqsave();
|
||||
let mut id_set: HashSet<usize> = HashSet::new();
|
||||
let mut cur_phys = PhysPageFrame::new(self.shm_start_paddr);
|
||||
let page_count = PageFrameCount::from_bytes(page_align_up(self.shm_size)).unwrap();
|
||||
|
||||
for _ in 0..page_count.data() {
|
||||
let page = page_manager_guard.get(&cur_phys.phys_address()).unwrap();
|
||||
id_set.extend(
|
||||
page.anon_vma()
|
||||
.iter()
|
||||
.map(|vma| vma.id())
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
cur_phys = cur_phys.next();
|
||||
}
|
||||
|
||||
// 由于LockedVMA的id是独一无二的,因此有多少个不同的id,就代表着有多少个不同的VMA映射到共享内存段
|
||||
return id_set.len();
|
||||
}
|
||||
|
||||
pub fn copy_from(&mut self, shm_id_ds: PosixShmIdDs) {
|
||||
self.kern_ipc_perm.uid = shm_id_ds.uid() as usize;
|
||||
self.kern_ipc_perm.gid = shm_id_ds.gid() as usize;
|
||||
self.kern_ipc_perm.mode = ShmFlags::from_bits_truncate(shm_id_ds.mode());
|
||||
self.update_ctim();
|
||||
}
|
||||
|
||||
pub fn set_mode(&mut self, shmflg: ShmFlags, set: bool) {
|
||||
if set {
|
||||
self.kern_ipc_perm.mode.insert(shmflg);
|
||||
} else {
|
||||
self.kern_ipc_perm.mode.remove(shmflg);
|
||||
}
|
||||
|
||||
self.update_ctim();
|
||||
}
|
||||
}
|
||||
|
||||
/// 共享内存权限信息
|
||||
#[derive(Debug)]
|
||||
pub struct KernIpcPerm {
|
||||
/// 共享内存id
|
||||
id: ShmId,
|
||||
/// 共享内存键值,由创建共享内存用户指定
|
||||
key: ShmKey,
|
||||
/// 共享内存拥有者用户id
|
||||
uid: usize,
|
||||
/// 共享内存拥有者所在组id
|
||||
gid: usize,
|
||||
/// 共享内存创建者用户id
|
||||
_cuid: usize,
|
||||
/// 共享内存创建者所在组id
|
||||
_cgid: usize,
|
||||
/// 共享内存区权限模式
|
||||
mode: ShmFlags,
|
||||
_seq: usize,
|
||||
}
|
||||
|
||||
/// 共享内存元信息,符合POSIX标准
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct PosixShmMetaInfo {
|
||||
/// 最大共享内存段的大小(bytes)
|
||||
shmmax: usize,
|
||||
/// 最小共享内存段的大小(bytes)
|
||||
shmmin: usize,
|
||||
/// 最大共享内存标识符数量
|
||||
shmmni: usize,
|
||||
/// 单个进程可以拥有的最大共享内存段的数量,和最大共享内存标识符数量相同
|
||||
shmseg: usize,
|
||||
/// 所有共享内存段总共可以使用的最大内存量(pages)
|
||||
shmall: usize,
|
||||
_unused1: usize,
|
||||
_unused2: usize,
|
||||
_unused3: usize,
|
||||
_unused4: usize,
|
||||
}
|
||||
|
||||
impl PosixShmMetaInfo {
|
||||
/// 最小共享内存段的大小(bytes)
|
||||
pub const SHMMIN: usize = 1;
|
||||
/// 最大共享内存标识符数量
|
||||
pub const SHMMNI: usize = 4096;
|
||||
/// 最大共享内存段的大小(bytes)
|
||||
pub const SHMMAX: usize = usize::MAX - (1 << 24);
|
||||
/// 所有共享内存段总共可以使用的最大内存量(pages)
|
||||
pub const SHMALL: usize = usize::MAX - (1 << 24);
|
||||
/// 单个进程可以拥有的最大共享内存段的数量,和最大共享内存标识符数量相同
|
||||
pub const SHMSEG: usize = 4096;
|
||||
|
||||
pub fn new() -> Self {
|
||||
PosixShmMetaInfo {
|
||||
shmmax: Self::SHMMAX,
|
||||
shmmin: Self::SHMMIN,
|
||||
shmmni: Self::SHMMNI,
|
||||
shmseg: Self::SHMSEG,
|
||||
shmall: Self::SHMALL,
|
||||
_unused1: 0,
|
||||
_unused2: 0,
|
||||
_unused3: 0,
|
||||
_unused4: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 共享内存信息,符合POSIX标准
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct PosixShmInfo {
|
||||
/// 已使用id数
|
||||
used_ids: i32,
|
||||
/// 共享内存总量(pages)
|
||||
shm_tot: usize,
|
||||
/// 保留在内存中的共享内存大小
|
||||
shm_rss: usize,
|
||||
/// 被置换出的共享内存大小
|
||||
shm_swp: usize,
|
||||
/// 尝试置换次数
|
||||
swap_attempts: usize,
|
||||
/// 成功置换次数
|
||||
swap_successes: usize,
|
||||
}
|
||||
|
||||
impl PosixShmInfo {
|
||||
pub fn new(
|
||||
used_ids: i32,
|
||||
shm_tot: usize,
|
||||
shm_rss: usize,
|
||||
shm_swp: usize,
|
||||
swap_attempts: usize,
|
||||
swap_successes: usize,
|
||||
) -> Self {
|
||||
PosixShmInfo {
|
||||
used_ids,
|
||||
shm_tot,
|
||||
shm_rss,
|
||||
shm_swp,
|
||||
swap_attempts,
|
||||
swap_successes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 共享内存段属性信息,符合POSIX标准
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct PosixShmIdDs {
|
||||
/// 共享内存段权限
|
||||
shm_perm: PosixIpcPerm,
|
||||
/// 共享内存大小(bytes)
|
||||
shm_segsz: usize,
|
||||
/// 最后一次连接的时间
|
||||
shm_atime: i64,
|
||||
/// 最后一次断开连接的时间
|
||||
shm_dtime: i64,
|
||||
/// 最后一次更改信息的时间
|
||||
shm_ctime: i64,
|
||||
/// 创建者进程id
|
||||
shm_cpid: u32,
|
||||
/// 最后操作者进程id
|
||||
shm_lpid: u32,
|
||||
/// 链接数
|
||||
shm_map_count: usize,
|
||||
_unused1: usize,
|
||||
_unused2: usize,
|
||||
}
|
||||
|
||||
impl PosixShmIdDs {
|
||||
pub fn uid(&self) -> u32 {
|
||||
self.shm_perm.uid
|
||||
}
|
||||
|
||||
pub fn gid(&self) -> u32 {
|
||||
self.shm_perm.gid
|
||||
}
|
||||
|
||||
pub fn mode(&self) -> u32 {
|
||||
self.shm_perm.mode
|
||||
}
|
||||
}
|
||||
|
||||
/// 共享内存段权限,符合POSIX标准
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct PosixIpcPerm {
|
||||
/// IPC对象键值
|
||||
key: i32,
|
||||
/// 当前用户id
|
||||
uid: u32,
|
||||
/// 当前用户组id
|
||||
gid: u32,
|
||||
/// 创建者用户id
|
||||
cuid: u32,
|
||||
/// 创建者组id
|
||||
cgid: u32,
|
||||
/// 权限
|
||||
mode: u32,
|
||||
/// 序列号
|
||||
seq: i32,
|
||||
_pad1: i32,
|
||||
_unused1: usize,
|
||||
_unused2: usize,
|
||||
}
|
||||
|
||||
impl PosixIpcPerm {
|
||||
pub fn new(key: i32, uid: u32, gid: u32, cuid: u32, cgid: u32, mode: u32) -> Self {
|
||||
PosixIpcPerm {
|
||||
key,
|
||||
uid,
|
||||
gid,
|
||||
cuid,
|
||||
cgid,
|
||||
mode,
|
||||
seq: 0,
|
||||
_pad1: 0,
|
||||
_unused1: 0,
|
||||
_unused2: 0,
|
||||
}
|
||||
}
|
||||
}
|
@ -6,20 +6,35 @@ use core::{
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::ipc::signal::{SigCode, SigFlags, SigSet, Signal},
|
||||
arch::{
|
||||
ipc::signal::{SigCode, SigFlags, SigSet, Signal},
|
||||
MMArch,
|
||||
},
|
||||
filesystem::vfs::{
|
||||
file::{File, FileMode},
|
||||
FilePrivateData,
|
||||
},
|
||||
ipc::shm::{shm_manager_lock, IPC_PRIVATE},
|
||||
kerror, kwarn,
|
||||
libs::align::page_align_up,
|
||||
libs::spinlock::SpinLock,
|
||||
mm::VirtAddr,
|
||||
mm::{
|
||||
allocator::page_frame::{PageFrameCount, PhysPageFrame, VirtPageFrame},
|
||||
page::{page_manager_lock_irqsave, PageFlags, PageFlushAll},
|
||||
syscall::ProtFlags,
|
||||
ucontext::{AddressSpace, VMA},
|
||||
VirtAddr, VmFlags,
|
||||
},
|
||||
process::{Pid, ProcessManager},
|
||||
syscall::{user_access::UserBufferWriter, Syscall},
|
||||
syscall::{
|
||||
user_access::{UserBufferReader, UserBufferWriter},
|
||||
Syscall,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{
|
||||
pipe::{LockedPipeInode, PipeFsPrivateData},
|
||||
shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
|
||||
signal_types::{
|
||||
SaHandlerType, SigInfo, SigType, Sigaction, SigactionType, UserSigaction, USER_SIG_DFL,
|
||||
USER_SIG_ERR, USER_SIG_IGN,
|
||||
@ -230,4 +245,262 @@ impl Syscall {
|
||||
}
|
||||
return retval.map(|_| 0);
|
||||
}
|
||||
|
||||
/// # SYS_SHMGET系统调用函数,用于获取共享内存
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `key`: 共享内存键值
|
||||
/// - `size`: 共享内存大小(bytes)
|
||||
/// - `shmflg`: 共享内存标志
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:共享内存id
|
||||
/// 失败:错误码
|
||||
pub fn shmget(key: ShmKey, size: usize, shmflg: ShmFlags) -> Result<usize, SystemError> {
|
||||
// 暂不支持巨页
|
||||
if shmflg.contains(ShmFlags::SHM_HUGETLB) {
|
||||
kerror!("shmget: not support huge page");
|
||||
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
|
||||
}
|
||||
|
||||
let mut shm_manager_guard = shm_manager_lock();
|
||||
match key {
|
||||
// 创建共享内存段
|
||||
IPC_PRIVATE => shm_manager_guard.add(key, size, shmflg),
|
||||
_ => {
|
||||
// 查找key对应的共享内存段是否存在
|
||||
let id = shm_manager_guard.contains_key(&key);
|
||||
if let Some(id) = id {
|
||||
// 不能重复创建
|
||||
if shmflg.contains(ShmFlags::IPC_CREAT | ShmFlags::IPC_EXCL) {
|
||||
return Err(SystemError::EEXIST);
|
||||
}
|
||||
|
||||
// key值存在,说明有对应共享内存,返回该共享内存id
|
||||
return Ok(id.data());
|
||||
} else {
|
||||
// key不存在且shm_flags不包含IPC_CREAT创建IPC对象标志,则返回错误码
|
||||
if !shmflg.contains(ShmFlags::IPC_CREAT) {
|
||||
return Err(SystemError::ENOENT);
|
||||
}
|
||||
|
||||
// 存在创建IPC对象标志
|
||||
return shm_manager_guard.add(key, size, shmflg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// # SYS_SHMAT系统调用函数,用于连接共享内存段
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `id`: 共享内存id
|
||||
/// - `vaddr`: 连接共享内存的进程虚拟内存区域起始地址
|
||||
/// - `shmflg`: 共享内存标志
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:映射到共享内存的虚拟内存区域起始地址
|
||||
/// 失败:错误码
|
||||
pub fn shmat(id: ShmId, vaddr: VirtAddr, shmflg: ShmFlags) -> Result<usize, SystemError> {
|
||||
let mut shm_manager_guard = shm_manager_lock();
|
||||
let current_address_space = AddressSpace::current()?;
|
||||
let mut address_write_guard = current_address_space.write();
|
||||
|
||||
let kernel_shm = shm_manager_guard.get_mut(&id).ok_or(SystemError::EINVAL)?;
|
||||
let size = page_align_up(kernel_shm.size());
|
||||
let mut phys = PhysPageFrame::new(kernel_shm.start_paddr());
|
||||
let count = PageFrameCount::from_bytes(size).unwrap();
|
||||
let r = match vaddr.data() {
|
||||
// 找到空闲区域并映射到共享内存
|
||||
0 => {
|
||||
// 找到空闲区域
|
||||
let region = address_write_guard
|
||||
.mappings
|
||||
.find_free(vaddr, size)
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
let vm_flags = VmFlags::from(shmflg);
|
||||
let destination = VirtPageFrame::new(region.start());
|
||||
let page_flags: PageFlags<MMArch> =
|
||||
PageFlags::from_prot_flags(ProtFlags::from(vm_flags), true);
|
||||
let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
|
||||
|
||||
// 将共享内存映射到对应虚拟区域
|
||||
let vma = VMA::physmap(
|
||||
phys,
|
||||
destination,
|
||||
count,
|
||||
vm_flags,
|
||||
page_flags,
|
||||
&mut address_write_guard.user_mapper.utable,
|
||||
flusher,
|
||||
)?;
|
||||
|
||||
// 将VMA加入到当前进程的VMA列表中
|
||||
address_write_guard.mappings.insert_vma(vma);
|
||||
|
||||
region.start().data()
|
||||
}
|
||||
// 指定虚拟地址
|
||||
_ => {
|
||||
// 获取对应vma
|
||||
let vma = address_write_guard
|
||||
.mappings
|
||||
.contains(vaddr)
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
if vma.lock().region().start() != vaddr {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
// 验证用户虚拟内存区域是否有效
|
||||
let _ = UserBufferReader::new(vaddr.data() as *const u8, size, true)?;
|
||||
|
||||
// 必须在取消映射前获取到PageFlags
|
||||
let page_flags = address_write_guard
|
||||
.user_mapper
|
||||
.utable
|
||||
.translate(vaddr)
|
||||
.ok_or(SystemError::EINVAL)?
|
||||
.1;
|
||||
|
||||
// 取消原映射
|
||||
let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
|
||||
vma.unmap(&mut address_write_guard.user_mapper.utable, flusher);
|
||||
|
||||
// 将该虚拟内存区域映射到共享内存区域
|
||||
let mut page_manager_guard = page_manager_lock_irqsave();
|
||||
let mut virt = VirtPageFrame::new(vaddr);
|
||||
for _ in 0..count.data() {
|
||||
let r = unsafe {
|
||||
address_write_guard.user_mapper.utable.map_phys(
|
||||
virt.virt_address(),
|
||||
phys.phys_address(),
|
||||
page_flags,
|
||||
)
|
||||
}
|
||||
.expect("Failed to map zero, may be OOM error");
|
||||
r.flush();
|
||||
|
||||
// 将vma加入到对应Page的anon_vma
|
||||
page_manager_guard
|
||||
.get_mut(&phys.phys_address())
|
||||
.insert_vma(vma.clone());
|
||||
|
||||
phys = phys.next();
|
||||
virt = virt.next();
|
||||
}
|
||||
|
||||
// 更新vma的映射状态
|
||||
vma.lock().set_mapped(true);
|
||||
|
||||
vaddr.data()
|
||||
}
|
||||
};
|
||||
|
||||
// 更新最后一次连接时间
|
||||
kernel_shm.update_atim();
|
||||
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
/// # SYS_SHMDT系统调用函数,用于取消对共享内存的连接
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `vaddr`: 需要取消映射的虚拟内存区域起始地址
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:0
|
||||
/// 失败:错误码
|
||||
pub fn shmdt(vaddr: VirtAddr) -> Result<usize, SystemError> {
|
||||
let current_address_space = AddressSpace::current()?;
|
||||
let mut address_write_guard = current_address_space.write();
|
||||
|
||||
// 获取vma
|
||||
let vma = address_write_guard
|
||||
.mappings
|
||||
.contains(vaddr)
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
|
||||
// 判断vaddr是否为起始地址
|
||||
if vma.lock().region().start() != vaddr {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
// 获取映射的物理地址
|
||||
let paddr = address_write_guard
|
||||
.user_mapper
|
||||
.utable
|
||||
.translate(vaddr)
|
||||
.ok_or(SystemError::EINVAL)?
|
||||
.0;
|
||||
|
||||
// 如果物理页的shm_id为None,代表不是共享页
|
||||
let page_manager_guard = page_manager_lock_irqsave();
|
||||
let page = page_manager_guard.get(&paddr).ok_or(SystemError::EINVAL)?;
|
||||
let shm_id = page.shm_id().ok_or(SystemError::EINVAL)?;
|
||||
drop(page_manager_guard);
|
||||
|
||||
// 获取对应共享页管理信息
|
||||
let mut shm_manager_guard = shm_manager_lock();
|
||||
let kernel_shm = shm_manager_guard
|
||||
.get_mut(&shm_id)
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
// 更新最后一次断开连接时间
|
||||
kernel_shm.update_dtim();
|
||||
drop(shm_manager_guard);
|
||||
|
||||
// 取消映射
|
||||
let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
|
||||
vma.unmap(&mut address_write_guard.user_mapper.utable, flusher);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
/// # SYS_SHMCTL系统调用函数,用于管理共享内存段
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `id`: 共享内存id
|
||||
/// - `cmd`: 操作码
|
||||
/// - `user_buf`: 用户缓冲区
|
||||
/// - `from_user`: buf_vaddr是否来自用户地址空间
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:0
|
||||
/// 失败:错误码
|
||||
pub fn shmctl(
|
||||
id: ShmId,
|
||||
cmd: ShmCtlCmd,
|
||||
user_buf: *const u8,
|
||||
from_user: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
let mut shm_manager_guard = shm_manager_lock();
|
||||
|
||||
match cmd {
|
||||
// 查看共享内存元信息
|
||||
ShmCtlCmd::IpcInfo => shm_manager_guard.ipc_info(user_buf, from_user),
|
||||
// 查看共享内存使用信息
|
||||
ShmCtlCmd::ShmInfo => shm_manager_guard.shm_info(user_buf, from_user),
|
||||
// 查看id对应的共享内存信息
|
||||
ShmCtlCmd::ShmStat | ShmCtlCmd::ShmtStatAny | ShmCtlCmd::IpcStat => {
|
||||
shm_manager_guard.shm_stat(id, cmd, user_buf, from_user)
|
||||
}
|
||||
// 设置KernIpcPerm
|
||||
ShmCtlCmd::IpcSet => shm_manager_guard.ipc_set(id, user_buf, from_user),
|
||||
// 将共享内存段设置为可回收状态
|
||||
ShmCtlCmd::IpcRmid => shm_manager_guard.ipc_rmid(id),
|
||||
// 锁住共享内存段,不允许内存置换
|
||||
ShmCtlCmd::ShmLock => shm_manager_guard.shm_lock(id),
|
||||
// 解锁共享内存段,允许内存置换
|
||||
ShmCtlCmd::ShmUnlock => shm_manager_guard.shm_unlock(id),
|
||||
// 无效操作码
|
||||
ShmCtlCmd::Default => Err(SystemError::EINVAL),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ use crate::{
|
||||
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
||||
time::{
|
||||
timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper},
|
||||
TimeSpec,
|
||||
PosixTimeSpec,
|
||||
},
|
||||
};
|
||||
|
||||
@ -220,7 +220,7 @@ impl Futex {
|
||||
uaddr: VirtAddr,
|
||||
flags: FutexFlag,
|
||||
val: u32,
|
||||
abs_time: Option<TimeSpec>,
|
||||
abs_time: Option<PosixTimeSpec>,
|
||||
bitset: u32,
|
||||
) -> Result<usize, SystemError> {
|
||||
if bitset == 0 {
|
||||
|
@ -3,7 +3,7 @@ use system_error::SystemError;
|
||||
use crate::{
|
||||
mm::{verify_area, VirtAddr},
|
||||
syscall::Syscall,
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@ -16,7 +16,7 @@ impl Syscall {
|
||||
uaddr: VirtAddr,
|
||||
operation: FutexFlag,
|
||||
val: u32,
|
||||
timeout: Option<TimeSpec>,
|
||||
timeout: Option<PosixTimeSpec>,
|
||||
uaddr2: VirtAddr,
|
||||
val2: u32,
|
||||
val3: u32,
|
||||
|
@ -16,7 +16,7 @@ use crate::{
|
||||
kmsg::KMSG,
|
||||
log::{LogLevel, LogMessage},
|
||||
},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
#[macro_export]
|
||||
@ -120,7 +120,7 @@ pub struct Logger;
|
||||
impl Logger {
|
||||
pub fn log(&self, log_level: usize, message: fmt::Arguments) {
|
||||
if unsafe { KMSG.is_some() } {
|
||||
let timestamp: TimeSpec = TimeSpec::now();
|
||||
let timestamp: PosixTimeSpec = PosixTimeSpec::now_cpu_time();
|
||||
let log_level = LogLevel::from(log_level);
|
||||
|
||||
let log_message = LogMessage::new(timestamp, log_level, message.to_string());
|
||||
|
@ -5,6 +5,7 @@ use core::{
|
||||
|
||||
use crate::{
|
||||
arch::{mm::LockedFrameAllocator, MMArch},
|
||||
ipc::shm::shm_manager_lock,
|
||||
libs::spinlock::SpinLockGuard,
|
||||
mm::{MemoryManagementArch, PhysAddr, VirtAddr},
|
||||
};
|
||||
@ -196,6 +197,11 @@ impl PageFrameCount {
|
||||
return Some(Self(bytes / MMArch::PAGE_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn next_power_of_two(&self) -> Self {
|
||||
Self::new(self.0.next_power_of_two())
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for PageFrameCount {
|
||||
@ -352,17 +358,26 @@ pub unsafe fn allocate_page_frames(count: PageFrameCount) -> Option<(PhysAddr, P
|
||||
pub unsafe fn deallocate_page_frames(
|
||||
frame: PhysPageFrame,
|
||||
count: PageFrameCount,
|
||||
page_manager: &mut SpinLockGuard<'_, crate::mm::page::PageManager>,
|
||||
page_manager_guard: &mut SpinLockGuard<'_, crate::mm::page::PageManager>,
|
||||
) {
|
||||
unsafe {
|
||||
LockedFrameAllocator.free(frame.phys_address(), count);
|
||||
}
|
||||
|
||||
// 将已回收的物理页面对应的Page从PAGE_MANAGER中删去
|
||||
let mut frame = frame;
|
||||
for _ in 0..count.data() {
|
||||
let paddr = frame.phys_address();
|
||||
page_manager.remove_page(&paddr);
|
||||
let page = page_manager_guard.get(&paddr);
|
||||
|
||||
if let Some(page) = page {
|
||||
// 如果page是共享页,将其共享页信息从SHM_MANAGER中删去
|
||||
if page.shared() {
|
||||
shm_manager_lock().free_id(&page.shm_id().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
// 将已回收的物理页面对应的Page从PAGE_MANAGER中删去
|
||||
page_manager_guard.remove_page(&paddr);
|
||||
frame = frame.next();
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ use crate::{
|
||||
arch::MMArch,
|
||||
driver::serial::serial8250::send_to_default_serial8250_port,
|
||||
filesystem::procfs::kmsg::kmsg_init,
|
||||
ipc::shm::shm_manager_init,
|
||||
libs::printk::PrintkWriter,
|
||||
mm::{mmio_buddy::mmio_init, page::page_manager_init},
|
||||
};
|
||||
@ -49,6 +50,8 @@ pub unsafe fn mm_init() {
|
||||
kmsg_init();
|
||||
// enable PAGE_MANAGER
|
||||
page_manager_init();
|
||||
// enable SHM_MANAGER
|
||||
shm_manager_init();
|
||||
|
||||
MM_INIT
|
||||
.compare_exchange(
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::MMArch,
|
||||
ipc::shm::ShmFlags,
|
||||
kerror,
|
||||
libs::align::{check_aligned, page_align_up},
|
||||
mm::MemoryManagementArch,
|
||||
@ -113,6 +114,28 @@ impl From<ProtFlags> for VmFlags {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ShmFlags> for VmFlags {
|
||||
fn from(shm_flags: ShmFlags) -> Self {
|
||||
let mut vm_flags = VmFlags::VM_NONE;
|
||||
|
||||
if shm_flags.contains(ShmFlags::SHM_RDONLY) {
|
||||
vm_flags |= VmFlags::VM_READ;
|
||||
} else {
|
||||
vm_flags |= VmFlags::VM_READ | VmFlags::VM_WRITE;
|
||||
}
|
||||
|
||||
if shm_flags.contains(ShmFlags::SHM_EXEC) {
|
||||
vm_flags |= VmFlags::VM_EXEC;
|
||||
}
|
||||
|
||||
if shm_flags.contains(ShmFlags::SHM_HUGETLB) {
|
||||
vm_flags |= VmFlags::VM_HUGETLB;
|
||||
}
|
||||
|
||||
vm_flags
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VmFlags> for MapFlags {
|
||||
fn from(value: VmFlags) -> Self {
|
||||
let mut map_flags = MapFlags::MAP_NONE;
|
||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||
rwlock::{RwLock, RwLockWriteGuard},
|
||||
spinlock::{SpinLock, SpinLockGuard},
|
||||
},
|
||||
mm::page::page_manager_lock_irasave,
|
||||
mm::page::page_manager_lock_irqsave,
|
||||
process::ProcessManager,
|
||||
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
||||
};
|
||||
@ -577,7 +577,9 @@ impl InnerAddressSpace {
|
||||
pub unsafe fn unmap_all(&mut self) {
|
||||
let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new();
|
||||
for vma in self.mappings.iter_vmas() {
|
||||
vma.unmap(&mut self.user_mapper.utable, &mut flusher);
|
||||
if vma.mapped() {
|
||||
vma.unmap(&mut self.user_mapper.utable, &mut flusher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -670,7 +672,7 @@ impl Drop for UserMapper {
|
||||
deallocate_page_frames(
|
||||
PhysPageFrame::new(self.utable.table().phys()),
|
||||
PageFrameCount::new(1),
|
||||
&mut page_manager_lock_irasave(),
|
||||
&mut page_manager_lock_irqsave(),
|
||||
)
|
||||
};
|
||||
}
|
||||
@ -909,6 +911,10 @@ impl LockedVMA {
|
||||
return r;
|
||||
}
|
||||
|
||||
pub fn id(&self) -> usize {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn lock(&self) -> SpinLockGuard<VMA> {
|
||||
return self.vma.lock();
|
||||
}
|
||||
@ -950,14 +956,14 @@ impl LockedVMA {
|
||||
assert!(guard.mapped);
|
||||
|
||||
// 获取物理页的anon_vma的守卫
|
||||
let mut anon_vma_guard: SpinLockGuard<'_, crate::mm::page::PageManager> =
|
||||
page_manager_lock_irasave();
|
||||
let mut page_manager_guard: SpinLockGuard<'_, crate::mm::page::PageManager> =
|
||||
page_manager_lock_irqsave();
|
||||
for page in guard.region.pages() {
|
||||
let (paddr, _, flush) = unsafe { mapper.unmap_phys(page.virt_address(), true) }
|
||||
.expect("Failed to unmap, beacuse of some page is not mapped");
|
||||
|
||||
// 从anon_vma中删除当前VMA
|
||||
let page = anon_vma_guard.get_mut(&paddr);
|
||||
let page = page_manager_guard.get_mut(&paddr);
|
||||
page.remove_vma(self);
|
||||
|
||||
// 如果物理页的anon_vma链表长度为0并且不是共享页,则释放物理页.
|
||||
@ -966,7 +972,7 @@ impl LockedVMA {
|
||||
deallocate_page_frames(
|
||||
PhysPageFrame::new(paddr),
|
||||
PageFrameCount::new(1),
|
||||
&mut anon_vma_guard,
|
||||
&mut page_manager_guard,
|
||||
)
|
||||
};
|
||||
}
|
||||
@ -1030,12 +1036,12 @@ impl LockedVMA {
|
||||
});
|
||||
|
||||
// 重新设置before、after这两个VMA里面的物理页的anon_vma
|
||||
let mut anon_vma_guard = page_manager_lock_irasave();
|
||||
let mut page_manager_guard = page_manager_lock_irqsave();
|
||||
if let Some(before) = before.clone() {
|
||||
let virt_iter = before.lock().region.iter_pages();
|
||||
for frame in virt_iter {
|
||||
let paddr = utable.translate(frame.virt_address()).unwrap().0;
|
||||
let page = anon_vma_guard.get_mut(&paddr);
|
||||
let page = page_manager_guard.get_mut(&paddr);
|
||||
page.insert_vma(before.clone());
|
||||
page.remove_vma(self);
|
||||
}
|
||||
@ -1045,7 +1051,7 @@ impl LockedVMA {
|
||||
let virt_iter = after.lock().region.iter_pages();
|
||||
for frame in virt_iter {
|
||||
let paddr = utable.translate(frame.virt_address()).unwrap().0;
|
||||
let page = anon_vma_guard.get_mut(&paddr);
|
||||
let page = page_manager_guard.get_mut(&paddr);
|
||||
page.insert_vma(after.clone());
|
||||
page.remove_vma(self);
|
||||
}
|
||||
@ -1155,6 +1161,10 @@ impl VMA {
|
||||
self.region.set_size(new_region_size);
|
||||
}
|
||||
|
||||
pub fn set_mapped(&mut self, mapped: bool) {
|
||||
self.mapped = mapped;
|
||||
}
|
||||
|
||||
/// # 拷贝当前VMA的内容
|
||||
///
|
||||
/// ### 安全性
|
||||
@ -1273,11 +1283,11 @@ impl VMA {
|
||||
});
|
||||
|
||||
// 将VMA加入到anon_vma中
|
||||
let mut anon_vma_guard = page_manager_lock_irasave();
|
||||
let mut page_manager_guard = page_manager_lock_irqsave();
|
||||
cur_phy = phys;
|
||||
for _ in 0..count.data() {
|
||||
let paddr = cur_phy.phys_address();
|
||||
let page = anon_vma_guard.get_mut(&paddr);
|
||||
let page = page_manager_guard.get_mut(&paddr);
|
||||
page.insert_vma(r.clone());
|
||||
cur_phy = cur_phy.next();
|
||||
}
|
||||
@ -1336,14 +1346,14 @@ impl VMA {
|
||||
// kdebug!("VMA::zeroed: flusher dropped");
|
||||
|
||||
// 清空这些内存并将VMA加入到anon_vma中
|
||||
let mut anon_vma_guard = page_manager_lock_irasave();
|
||||
let mut page_manager_guard = page_manager_lock_irqsave();
|
||||
let virt_iter: VirtPageFrameIter =
|
||||
VirtPageFrameIter::new(destination, destination.add(page_count));
|
||||
for frame in virt_iter {
|
||||
let paddr = mapper.translate(frame.virt_address()).unwrap().0;
|
||||
|
||||
// 将VMA加入到anon_vma
|
||||
let page = anon_vma_guard.get_mut(&paddr);
|
||||
let page = page_manager_guard.get_mut(&paddr);
|
||||
page.insert_vma(r.clone());
|
||||
|
||||
// 清空内存
|
||||
|
@ -26,7 +26,7 @@ use crate::{
|
||||
sched::{schedule, SchedMode},
|
||||
time::{
|
||||
timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper},
|
||||
TimeSpec,
|
||||
PosixTimeSpec,
|
||||
},
|
||||
};
|
||||
|
||||
@ -394,7 +394,7 @@ impl EventPoll {
|
||||
epfd: i32,
|
||||
epoll_event: &mut [EPollEvent],
|
||||
max_events: i32,
|
||||
timespec: Option<TimeSpec>,
|
||||
timespec: Option<PosixTimeSpec>,
|
||||
) -> Result<usize, SystemError> {
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
let fd_table = current_pcb.fd_table();
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
user_access::{UserBufferReader, UserBufferWriter},
|
||||
Syscall,
|
||||
},
|
||||
time::TimeSpec,
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
|
||||
use super::{EPollCtlOption, EPollEvent, EventPoll};
|
||||
@ -42,14 +42,14 @@ impl Syscall {
|
||||
|
||||
let mut timespec = None;
|
||||
if timeout == 0 {
|
||||
timespec = Some(TimeSpec::new(0, 0));
|
||||
timespec = Some(PosixTimeSpec::new(0, 0));
|
||||
}
|
||||
|
||||
if timeout > 0 {
|
||||
let sec: i64 = timeout as i64 / 1000;
|
||||
let nsec: i64 = 1000000 * (timeout as i64 % 1000);
|
||||
|
||||
timespec = Some(TimeSpec::new(sec, nsec))
|
||||
timespec = Some(PosixTimeSpec::new(sec, nsec))
|
||||
}
|
||||
|
||||
// 从用户传入的地址中拿到epoll_events
|
||||
|
@ -1,7 +1,7 @@
|
||||
use num_traits::FromPrimitive;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::time::TimeSpec;
|
||||
use crate::time::PosixTimeSpec;
|
||||
|
||||
use super::ProcessControlBlock;
|
||||
|
||||
@ -9,9 +9,9 @@ use super::ProcessControlBlock;
|
||||
#[repr(C)]
|
||||
pub struct RUsage {
|
||||
/// User time used
|
||||
pub ru_utime: TimeSpec,
|
||||
pub ru_utime: PosixTimeSpec,
|
||||
/// System time used
|
||||
pub ru_stime: TimeSpec,
|
||||
pub ru_stime: PosixTimeSpec,
|
||||
|
||||
// 以下是linux的rusage结构体扩展
|
||||
/// Maximum resident set size
|
||||
|
@ -8,6 +8,7 @@ use crate::{
|
||||
arch::{ipc::signal::SigSet, syscall::nr::*},
|
||||
driver::base::device::device_number::DeviceNumber,
|
||||
filesystem::vfs::syscall::{PosixStatfs, PosixStatx},
|
||||
ipc::shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
|
||||
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
||||
mm::syscall::MremapFlags,
|
||||
net::syscall::MsgHdr,
|
||||
@ -39,7 +40,7 @@ use crate::{
|
||||
process::{fork::CloneFlags, syscall::PosixOldUtsName, Pid},
|
||||
time::{
|
||||
syscall::{PosixTimeZone, PosixTimeval},
|
||||
TimeSpec,
|
||||
PosixTimeSpec,
|
||||
},
|
||||
};
|
||||
|
||||
@ -297,13 +298,13 @@ impl Syscall {
|
||||
}
|
||||
|
||||
SYS_NANOSLEEP => {
|
||||
let req = args[0] as *const TimeSpec;
|
||||
let rem = args[1] as *mut TimeSpec;
|
||||
let req = args[0] as *const PosixTimeSpec;
|
||||
let rem = args[1] as *mut PosixTimeSpec;
|
||||
let virt_req = VirtAddr::new(req as usize);
|
||||
let virt_rem = VirtAddr::new(rem as usize);
|
||||
if frame.is_from_user()
|
||||
&& (verify_area(virt_req, core::mem::size_of::<TimeSpec>()).is_err()
|
||||
|| verify_area(virt_rem, core::mem::size_of::<TimeSpec>()).is_err())
|
||||
&& (verify_area(virt_req, core::mem::size_of::<PosixTimeSpec>()).is_err()
|
||||
|| verify_area(virt_rem, core::mem::size_of::<PosixTimeSpec>()).is_err())
|
||||
{
|
||||
Err(SystemError::EFAULT)
|
||||
} else {
|
||||
@ -693,12 +694,12 @@ impl Syscall {
|
||||
let mut timespec = None;
|
||||
if utime != 0 && operation.contains(FutexFlag::FLAGS_HAS_TIMEOUT) {
|
||||
let reader = UserBufferReader::new(
|
||||
utime as *const TimeSpec,
|
||||
core::mem::size_of::<TimeSpec>(),
|
||||
utime as *const PosixTimeSpec,
|
||||
core::mem::size_of::<PosixTimeSpec>(),
|
||||
true,
|
||||
)?;
|
||||
|
||||
timespec = Some(*reader.read_one_from_user::<TimeSpec>(0)?);
|
||||
timespec = Some(*reader.read_one_from_user::<PosixTimeSpec>(0)?);
|
||||
}
|
||||
|
||||
Self::do_futex(uaddr, operation, val, timespec, uaddr2, utime as u32, val3)
|
||||
@ -945,7 +946,7 @@ impl Syscall {
|
||||
|
||||
SYS_CLOCK_GETTIME => {
|
||||
let clockid = args[0] as i32;
|
||||
let timespec = args[1] as *mut TimeSpec;
|
||||
let timespec = args[1] as *mut PosixTimeSpec;
|
||||
Self::clock_gettime(clockid, timespec)
|
||||
}
|
||||
|
||||
@ -1041,6 +1042,33 @@ impl Syscall {
|
||||
Self::uname(name)
|
||||
}
|
||||
|
||||
SYS_SHMGET => {
|
||||
let key = ShmKey::new(args[0]);
|
||||
let size = args[1];
|
||||
let shmflg = ShmFlags::from_bits_truncate(args[2] as u32);
|
||||
|
||||
Self::shmget(key, size, shmflg)
|
||||
}
|
||||
SYS_SHMAT => {
|
||||
let id = ShmId::new(args[0]);
|
||||
let vaddr = VirtAddr::new(args[1]);
|
||||
let shmflg = ShmFlags::from_bits_truncate(args[2] as u32);
|
||||
|
||||
Self::shmat(id, vaddr, shmflg)
|
||||
}
|
||||
SYS_SHMDT => {
|
||||
let vaddr = VirtAddr::new(args[0]);
|
||||
Self::shmdt(vaddr)
|
||||
}
|
||||
SYS_SHMCTL => {
|
||||
let id = ShmId::new(args[0]);
|
||||
let cmd = ShmCtlCmd::from(args[1]);
|
||||
let user_buf = args[2] as *const u8;
|
||||
let from_user = frame.is_from_user();
|
||||
|
||||
Self::shmctl(id, cmd, user_buf, from_user)
|
||||
}
|
||||
|
||||
_ => panic!("Unsupported syscall ID: {}", syscall_num),
|
||||
};
|
||||
|
||||
|
@ -6,7 +6,7 @@ use core::{
|
||||
|
||||
use crate::arch::CurrentTimeArch;
|
||||
|
||||
use self::timekeep::ktime_get_real_ns;
|
||||
use self::{timekeep::ktime_get_real_ns, timekeeping::getnstimeofday};
|
||||
|
||||
pub mod clocksource;
|
||||
pub mod jiffies;
|
||||
@ -46,28 +46,34 @@ pub const FSEC_PER_SEC: u64 = 1000000000000000;
|
||||
/// 表示时间的结构体,符合POSIX标准。
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
#[repr(C)]
|
||||
pub struct TimeSpec {
|
||||
pub struct PosixTimeSpec {
|
||||
pub tv_sec: i64,
|
||||
pub tv_nsec: i64,
|
||||
}
|
||||
|
||||
impl TimeSpec {
|
||||
impl PosixTimeSpec {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(sec: i64, nsec: i64) -> TimeSpec {
|
||||
return TimeSpec {
|
||||
pub fn new(sec: i64, nsec: i64) -> PosixTimeSpec {
|
||||
return PosixTimeSpec {
|
||||
tv_sec: sec,
|
||||
tv_nsec: nsec,
|
||||
};
|
||||
}
|
||||
|
||||
/// 获取当前时间
|
||||
#[inline(always)]
|
||||
pub fn now() -> Self {
|
||||
getnstimeofday()
|
||||
}
|
||||
|
||||
/// 获取当前CPU时间(使用CPU时钟周期计算,会存在回绕问题)
|
||||
pub fn now_cpu_time() -> Self {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
use crate::arch::driver::tsc::TSCManager;
|
||||
let khz = TSCManager::cpu_khz();
|
||||
if unlikely(khz == 0) {
|
||||
return TimeSpec::default();
|
||||
return PosixTimeSpec::default();
|
||||
} else {
|
||||
return Self::from(Duration::from_millis(
|
||||
CurrentTimeArch::get_cycles() as u64 / khz,
|
||||
@ -77,12 +83,17 @@ impl TimeSpec {
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
{
|
||||
return TimeSpec::new(0, 0);
|
||||
return PosixTimeSpec::new(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// 换算成纳秒
|
||||
pub fn total_nanos(&self) -> i64 {
|
||||
self.tv_sec * 1000000000 + self.tv_nsec
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for TimeSpec {
|
||||
impl Sub for PosixTimeSpec {
|
||||
type Output = Duration;
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
let sec = self.tv_sec.checked_sub(rhs.tv_sec).unwrap_or(0);
|
||||
@ -91,17 +102,17 @@ impl Sub for TimeSpec {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Duration> for TimeSpec {
|
||||
impl From<Duration> for PosixTimeSpec {
|
||||
fn from(dur: Duration) -> Self {
|
||||
TimeSpec {
|
||||
PosixTimeSpec {
|
||||
tv_sec: dur.total_micros() as i64 / 1000000,
|
||||
tv_nsec: (dur.total_micros() as i64 % 1000000) * 1000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TimeSpec> for Duration {
|
||||
fn from(val: TimeSpec) -> Self {
|
||||
impl From<PosixTimeSpec> for Duration {
|
||||
fn from(val: PosixTimeSpec) -> Self {
|
||||
Duration::from_micros(val.tv_sec as u64 * 1000000 + val.tv_nsec as u64 / 1000)
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use crate::{
|
||||
|
||||
use super::{
|
||||
timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper},
|
||||
TimeArch, TimeSpec,
|
||||
PosixTimeSpec, TimeArch,
|
||||
};
|
||||
|
||||
/// @brief 休眠指定时间(单位:纳秒)
|
||||
@ -24,7 +24,7 @@ use super::{
|
||||
/// @return Ok(TimeSpec) 剩余休眠时间
|
||||
///
|
||||
/// @return Err(SystemError) 错误码
|
||||
pub fn nanosleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
pub fn nanosleep(sleep_time: PosixTimeSpec) -> Result<PosixTimeSpec, SystemError> {
|
||||
if sleep_time.tv_nsec < 0 || sleep_time.tv_nsec >= 1000000000 {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
@ -34,7 +34,7 @@ pub fn nanosleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
while CurrentTimeArch::get_cycles() < expired_tsc {
|
||||
spin_loop()
|
||||
}
|
||||
return Ok(TimeSpec {
|
||||
return Ok(PosixTimeSpec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
});
|
||||
@ -59,7 +59,7 @@ pub fn nanosleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
let end_time = getnstimeofday();
|
||||
// 返回正确的剩余时间
|
||||
let real_sleep_time = end_time - start_time;
|
||||
let rm_time: TimeSpec = (sleep_time - real_sleep_time.into()).into();
|
||||
let rm_time: PosixTimeSpec = (sleep_time - real_sleep_time.into()).into();
|
||||
|
||||
return Ok(rm_time);
|
||||
}
|
||||
@ -71,7 +71,7 @@ pub fn nanosleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
/// @return Ok(TimeSpec) 剩余休眠时间
|
||||
///
|
||||
/// @return Err(SystemError) 错误码
|
||||
pub fn usleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
pub fn usleep(sleep_time: PosixTimeSpec) -> Result<PosixTimeSpec, SystemError> {
|
||||
match nanosleep(sleep_time) {
|
||||
Ok(value) => return Ok(value),
|
||||
Err(err) => return Err(err),
|
||||
@ -89,7 +89,7 @@ pub fn usleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
/// @return Err(SystemError) 错误码
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rs_usleep(usec: useconds_t) -> i32 {
|
||||
let sleep_time = TimeSpec {
|
||||
let sleep_time = PosixTimeSpec {
|
||||
tv_sec: (usec / 1000000) as i64,
|
||||
tv_nsec: ((usec % 1000000) * 1000) as i64,
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
syscall::{user_access::UserBufferWriter, Syscall},
|
||||
time::{sleep::nanosleep, TimeSpec},
|
||||
time::{sleep::nanosleep, PosixTimeSpec},
|
||||
};
|
||||
|
||||
use super::timekeeping::{do_gettimeofday, getnstimeofday};
|
||||
@ -70,13 +70,13 @@ impl Syscall {
|
||||
///
|
||||
/// @return Err(SystemError) 错误码
|
||||
pub fn nanosleep(
|
||||
sleep_time: *const TimeSpec,
|
||||
rm_time: *mut TimeSpec,
|
||||
sleep_time: *const PosixTimeSpec,
|
||||
rm_time: *mut PosixTimeSpec,
|
||||
) -> Result<usize, SystemError> {
|
||||
if sleep_time.is_null() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
let slt_spec = TimeSpec {
|
||||
let slt_spec = PosixTimeSpec {
|
||||
tv_sec: unsafe { *sleep_time }.tv_sec,
|
||||
tv_nsec: unsafe { *sleep_time }.tv_nsec,
|
||||
};
|
||||
@ -131,7 +131,7 @@ impl Syscall {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn clock_gettime(clock_id: c_int, tp: *mut TimeSpec) -> Result<usize, SystemError> {
|
||||
pub fn clock_gettime(clock_id: c_int, tp: *mut PosixTimeSpec) -> Result<usize, SystemError> {
|
||||
let clock_id = PosixClockID::try_from(clock_id)?;
|
||||
if clock_id != PosixClockID::Realtime {
|
||||
kwarn!("clock_gettime: currently only support Realtime clock, but got {:?}. Defaultly return realtime!!!\n", clock_id);
|
||||
@ -139,8 +139,11 @@ impl Syscall {
|
||||
if tp.is_null() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
let mut tp_buf =
|
||||
UserBufferWriter::new::<TimeSpec>(tp, core::mem::size_of::<TimeSpec>(), true)?;
|
||||
let mut tp_buf = UserBufferWriter::new::<PosixTimeSpec>(
|
||||
tp,
|
||||
core::mem::size_of::<PosixTimeSpec>(),
|
||||
true,
|
||||
)?;
|
||||
|
||||
let timespec = getnstimeofday();
|
||||
|
||||
|
@ -4,7 +4,7 @@ use system_error::SystemError;
|
||||
|
||||
use crate::driver::rtc::interface::rtc_read_time_default;
|
||||
|
||||
use super::TimeSpec;
|
||||
use super::PosixTimeSpec;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type ktime_t = i64;
|
||||
@ -20,7 +20,7 @@ fn ktime_to_ns(kt: ktime_t) -> i64 {
|
||||
/// 注意,由于当前未引入时区,因此本函数默认时区为UTC+8来计算
|
||||
fn ktime_get_real() -> Result<ktime_t, SystemError> {
|
||||
let rtc_time = rtc_read_time_default()?;
|
||||
let time_spec: TimeSpec = rtc_time.into();
|
||||
let time_spec: PosixTimeSpec = rtc_time.into();
|
||||
let r = time_spec.tv_sec * 1_000_000_000 + time_spec.tv_nsec;
|
||||
return Ok(r);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use crate::{
|
||||
time::{
|
||||
jiffies::{clocksource_default_clock, jiffies_init},
|
||||
timekeep::ktime_get_real_ns,
|
||||
TimeSpec,
|
||||
PosixTimeSpec,
|
||||
},
|
||||
};
|
||||
|
||||
@ -64,10 +64,10 @@ pub struct TimekeeperData {
|
||||
ntp_error_shift: i32,
|
||||
/// NTP调整时钟乘法器
|
||||
mult: u32,
|
||||
raw_time: TimeSpec,
|
||||
wall_to_monotonic: TimeSpec,
|
||||
total_sleep_time: TimeSpec,
|
||||
xtime: TimeSpec,
|
||||
raw_time: PosixTimeSpec,
|
||||
wall_to_monotonic: PosixTimeSpec,
|
||||
total_sleep_time: PosixTimeSpec,
|
||||
xtime: PosixTimeSpec,
|
||||
}
|
||||
impl TimekeeperData {
|
||||
pub fn new() -> Self {
|
||||
@ -82,19 +82,19 @@ impl TimekeeperData {
|
||||
ntp_error: Default::default(),
|
||||
ntp_error_shift: Default::default(),
|
||||
mult: Default::default(),
|
||||
xtime: TimeSpec {
|
||||
xtime: PosixTimeSpec {
|
||||
tv_nsec: 0,
|
||||
tv_sec: 0,
|
||||
},
|
||||
wall_to_monotonic: TimeSpec {
|
||||
wall_to_monotonic: PosixTimeSpec {
|
||||
tv_nsec: 0,
|
||||
tv_sec: 0,
|
||||
},
|
||||
total_sleep_time: TimeSpec {
|
||||
total_sleep_time: PosixTimeSpec {
|
||||
tv_nsec: 0,
|
||||
tv_sec: 0,
|
||||
},
|
||||
raw_time: TimeSpec {
|
||||
raw_time: PosixTimeSpec {
|
||||
tv_nsec: 0,
|
||||
tv_sec: 0,
|
||||
},
|
||||
@ -192,11 +192,11 @@ pub fn timekeeper_init() {
|
||||
/// ## 返回值
|
||||
///
|
||||
/// * 'TimeSpec' - 时间戳
|
||||
pub fn getnstimeofday() -> TimeSpec {
|
||||
pub fn getnstimeofday() -> PosixTimeSpec {
|
||||
// kdebug!("enter getnstimeofday");
|
||||
|
||||
let nsecs;
|
||||
let mut xtime: TimeSpec;
|
||||
let mut xtime: PosixTimeSpec;
|
||||
loop {
|
||||
match timekeeper().inner.try_read_irqsave() {
|
||||
None => continue,
|
||||
@ -238,7 +238,7 @@ pub fn do_gettimeofday() -> PosixTimeval {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn do_settimeofday64(time: TimeSpec) -> Result<(), SystemError> {
|
||||
pub fn do_settimeofday64(time: PosixTimeSpec) -> Result<(), SystemError> {
|
||||
timekeeper().inner.write_irqsave().xtime = time;
|
||||
// todo: 模仿linux,实现时间误差校准。
|
||||
// https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/time/timekeeping.c?fi=do_settimeofday64#1312
|
||||
|
@ -7,7 +7,7 @@ use crate::filesystem::vfs::{
|
||||
};
|
||||
use crate::libs::spinlock::SpinLockGuard;
|
||||
use crate::process::ProcessManager;
|
||||
use crate::{arch::KVMArch, libs::spinlock::SpinLock, time::TimeSpec};
|
||||
use crate::{arch::KVMArch, libs::spinlock::SpinLock, time::PosixTimeSpec};
|
||||
use crate::{filesystem, kdebug};
|
||||
// use crate::virt::kvm::{host_stack};
|
||||
use super::push_vm;
|
||||
@ -59,9 +59,9 @@ impl LockedKvmInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::KvmDevice, // 文件夹,block设备,char设备
|
||||
mode: filesystem::vfs::syscall::ModeType::S_IALLUGO,
|
||||
nlinks: 1,
|
||||
|
@ -12,7 +12,7 @@ use crate::syscall::user_access::copy_from_user;
|
||||
use crate::virt::kvm::vcpu::Vcpu;
|
||||
use crate::virt::kvm::vm;
|
||||
use crate::{filesystem, kdebug};
|
||||
use crate::{libs::spinlock::SpinLock, time::TimeSpec};
|
||||
use crate::{libs::spinlock::SpinLock, time::PosixTimeSpec};
|
||||
use alloc::{
|
||||
string::String,
|
||||
sync::{Arc, Weak},
|
||||
@ -70,9 +70,9 @@ impl LockedVcpuInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::KvmDevice, // 文件夹,block设备,char设备
|
||||
mode: filesystem::vfs::syscall::ModeType::S_IALLUGO,
|
||||
nlinks: 1,
|
||||
|
@ -13,7 +13,7 @@ use crate::virt::kvm::host_mem::KvmUserspaceMemoryRegion;
|
||||
use crate::virt::kvm::update_vm;
|
||||
use crate::virt::kvm::vcpu_dev::LockedVcpuInode;
|
||||
use crate::virt::kvm::vm;
|
||||
use crate::{arch::KVMArch, libs::spinlock::SpinLock, time::TimeSpec};
|
||||
use crate::{arch::KVMArch, libs::spinlock::SpinLock, time::PosixTimeSpec};
|
||||
use crate::{filesystem, kdebug};
|
||||
use alloc::{
|
||||
string::String,
|
||||
@ -68,9 +68,9 @@ impl LockedVmInode {
|
||||
size: 0,
|
||||
blk_size: 0,
|
||||
blocks: 0,
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
atime: PosixTimeSpec::default(),
|
||||
mtime: PosixTimeSpec::default(),
|
||||
ctime: PosixTimeSpec::default(),
|
||||
file_type: FileType::KvmDevice, // 文件夹,block设备,char设备
|
||||
mode: filesystem::vfs::syscall::ModeType::S_IALLUGO,
|
||||
nlinks: 1,
|
||||
|
3
user/apps/test_shm/.gitignore
vendored
Normal file
3
user/apps/test_shm/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
info
|
||||
sender
|
||||
receiver
|
25
user/apps/test_shm/Makefile
Normal file
25
user/apps/test_shm/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
ifeq ($(ARCH), x86_64)
|
||||
CROSS_COMPILE=x86_64-linux-musl-
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
CROSS_COMPILE=riscv64-linux-musl-
|
||||
endif
|
||||
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
|
||||
NAME_PREFIX=test_shm_
|
||||
|
||||
all: sender.c receiver.c test_info.c
|
||||
$(CC) -static -o $(NAME_PREFIX)sender sender.c
|
||||
$(CC) -static -o $(NAME_PREFIX)receiver receiver.c
|
||||
$(CC) -static -o $(NAME_PREFIX)info test_info.c
|
||||
|
||||
.PHONY: install clean
|
||||
install: all
|
||||
mv $(NAME_PREFIX)sender $(DADK_CURRENT_BUILD_DIR)/
|
||||
mv $(NAME_PREFIX)receiver $(DADK_CURRENT_BUILD_DIR)/
|
||||
mv $(NAME_PREFIX)info $(DADK_CURRENT_BUILD_DIR)/
|
||||
|
||||
clean:
|
||||
rm $(NAME_PREFIX)receiver $(NAME_PREFIX)sender $(NAME_PREFIX)info *.o
|
||||
|
||||
fmt:
|
40
user/apps/test_shm/receiver.c
Normal file
40
user/apps/test_shm/receiver.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#define SHM_SIZE 9999
|
||||
|
||||
int main()
|
||||
{
|
||||
int shmid;
|
||||
char *shmaddr;
|
||||
key_t key = 6666;
|
||||
|
||||
// 测试shmget
|
||||
shmid = shmget(key, SHM_SIZE, 0666 | IPC_CREAT);
|
||||
if (shmid < 0)
|
||||
{
|
||||
perror("shmget failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 测试shmat
|
||||
shmaddr = shmat(shmid, 0, 0);
|
||||
|
||||
char read_buf[20];
|
||||
memcpy(read_buf, shmaddr, 14);
|
||||
|
||||
printf("Receiver receive: %s\n", read_buf);
|
||||
|
||||
memset(shmaddr, 0, SHM_SIZE);
|
||||
memcpy(shmaddr, "Reveiver Hello!", 16);
|
||||
|
||||
shmdt(shmaddr);
|
||||
|
||||
return 0;
|
||||
}
|
46
user/apps/test_shm/sender.c
Normal file
46
user/apps/test_shm/sender.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#define SHM_SIZE 9999
|
||||
|
||||
int main()
|
||||
{
|
||||
int shmid;
|
||||
char *shmaddr;
|
||||
key_t key = 6666;
|
||||
|
||||
// 测试shmget
|
||||
shmid = shmget(key, SHM_SIZE, 0666 | IPC_CREAT);
|
||||
if (shmid < 0)
|
||||
{
|
||||
perror("shmget failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 测试shmat
|
||||
shmaddr = shmat(shmid, 0, 0);
|
||||
|
||||
memset(shmaddr, 0, SHM_SIZE);
|
||||
memcpy(shmaddr, "Sender Hello!", 14);
|
||||
|
||||
int pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
execl("/bin/test_shm_receiver", NULL, NULL);
|
||||
}
|
||||
|
||||
waitpid(pid, NULL, 0);
|
||||
|
||||
char read_buf[20];
|
||||
memcpy(read_buf, shmaddr, 16);
|
||||
printf("Sender receive: %s\n", read_buf);
|
||||
|
||||
shmdt(shmaddr);
|
||||
shmctl(shmid, IPC_RMID, NULL);
|
||||
}
|
161
user/apps/test_shm/test_info.c
Normal file
161
user/apps/test_shm/test_info.c
Normal file
@ -0,0 +1,161 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
void print_shmidds(struct shmid_ds *shminfo)
|
||||
{
|
||||
struct ipc_perm shm_perm = shminfo->shm_perm;
|
||||
|
||||
printf("ipc_perm:\n");
|
||||
printf("ipc_perm_key: %d\n", shm_perm.__key);
|
||||
printf("uid: %d\n", shm_perm.uid);
|
||||
printf("gid: %d\n", shm_perm.gid);
|
||||
printf("cuid: %d\n", shm_perm.cuid);
|
||||
printf("cgid: %d\n", shm_perm.cgid);
|
||||
printf("mode: %d\n", shm_perm.mode);
|
||||
printf("seq: %d\n", shm_perm.__seq);
|
||||
printf("\n");
|
||||
|
||||
printf("shmid_ds:\n");
|
||||
printf("shm_atime: %lu\n", shminfo->shm_atime);
|
||||
printf("shm_dtime: %lu\n", shminfo->shm_dtime);
|
||||
printf("shm_ctime: %lu\n", shminfo->shm_ctime);
|
||||
printf("shm_segsz: %lu\n", shminfo->shm_segsz);
|
||||
printf("shm_cpid: %d\n", shminfo->shm_cpid);
|
||||
printf("shm_lpid: %d\n", shminfo->shm_lpid);
|
||||
printf("shm_nattch: %lu\n", shminfo->shm_nattch);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
const int SHM_SIZE = 9999;
|
||||
|
||||
int main()
|
||||
{
|
||||
int shmid;
|
||||
char *shmaddr;
|
||||
key_t key = 6666;
|
||||
|
||||
// 测试shmget
|
||||
shmid = shmget(key, SHM_SIZE, 0666 | IPC_CREAT);
|
||||
if (shmid < 0)
|
||||
{
|
||||
perror("shmget failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 测试shmat
|
||||
shmaddr = shmat(shmid, 0, 0);
|
||||
|
||||
// IPC_STAT:
|
||||
printf("\n");
|
||||
printf("IPC_STAT:\n");
|
||||
struct shmid_ds shminfo2;
|
||||
if (shmctl(shmid, IPC_STAT, &shminfo2) == -1)
|
||||
{
|
||||
// 获取共享内存段信息
|
||||
perror("shmctl");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
print_shmidds(&shminfo2);
|
||||
|
||||
// 测试shmctl
|
||||
// IPC_INFO
|
||||
printf("IPC_INFO:\n");
|
||||
struct shminfo shmmetainfo;
|
||||
if (shmctl(shmid, IPC_INFO, &shmmetainfo) == -1)
|
||||
{ // 获取共享内存段信息
|
||||
perror("shmctl");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("shmmax: %lu\n", shmmetainfo.shmmax);
|
||||
printf("shmmin: %lu\n", shmmetainfo.shmmin);
|
||||
printf("shmmni: %lu\n", shmmetainfo.shmmni);
|
||||
printf("shmseg: %lu\n", shmmetainfo.shmseg);
|
||||
printf("shmall: %lu\n", shmmetainfo.shmall);
|
||||
|
||||
// SHM_INFO
|
||||
printf("\n");
|
||||
printf("SHM_INFO:\n");
|
||||
struct shm_info shm_info;
|
||||
if (shmctl(shmid, SHM_INFO, &shm_info) == -1)
|
||||
{ // 获取共享内存段信息
|
||||
perror("shmctl");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("__used_ids: %lu\n", shm_info.__used_ids);
|
||||
printf("shm_tot: %lu\n", shm_info.shm_tot);
|
||||
printf("shm_rss: %lu\n", shm_info.shm_rss);
|
||||
printf("shm_swp: %lu\n", shm_info.shm_swp);
|
||||
printf("__swap_attempts: %lu\n", shm_info.__swap_attempts);
|
||||
printf("__swap_successes: %lu\n", shm_info.__swap_successes);
|
||||
|
||||
// SHM_STAT
|
||||
printf("\n");
|
||||
printf("SHM_STAT:\n");
|
||||
struct shmid_ds shminfo0;
|
||||
if (shmctl(shmid, SHM_STAT, &shminfo0) == -1)
|
||||
{ // 获取共享内存段信息
|
||||
perror("shmctl");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
print_shmidds(&shminfo0);
|
||||
|
||||
// SHM_STAT_ANY
|
||||
printf("SHM_STAT_ANY:\n");
|
||||
struct shmid_ds shminfo1;
|
||||
if (shmctl(shmid, SHM_STAT_ANY, &shminfo1) == -1)
|
||||
{ // 获取共享内存段信息
|
||||
perror("shmctl");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
print_shmidds(&shminfo1);
|
||||
|
||||
// IPC_SET
|
||||
printf("\n");
|
||||
printf("IPC_SET:\n");
|
||||
struct shmid_ds shminfo;
|
||||
shminfo.shm_atime = 1;
|
||||
shminfo.shm_dtime = 2;
|
||||
shminfo.shm_ctime = 3;
|
||||
shminfo.shm_segsz = 4;
|
||||
shminfo.shm_cpid = 5;
|
||||
shminfo.shm_lpid = 6;
|
||||
shminfo.shm_nattch = 7;
|
||||
if (shmctl(shmid, IPC_SET, &shminfo) == -1)
|
||||
{ // 获取共享内存段信息
|
||||
perror("shmctl");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// IPC_RMID
|
||||
printf("\n");
|
||||
printf("IPC_RMID:\n");
|
||||
if (shmctl(shmid, IPC_RMID, NULL) == -1)
|
||||
{ // 获取共享内存段信息
|
||||
perror("shmctl");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// SHM_LOCK
|
||||
printf("\n");
|
||||
printf("SHM_LOCK:\n");
|
||||
if (shmctl(shmid, SHM_LOCK, NULL) == -1)
|
||||
{ // 获取共享内存段信息
|
||||
perror("shmctl");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// SHM_UNLOCK
|
||||
printf("\n");
|
||||
printf("SHM_UNLOCK:\n");
|
||||
if (shmctl(shmid, SHM_UNLOCK, NULL) == -1)
|
||||
{ // 获取共享内存段信息
|
||||
perror("shmctl");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
23
user/dadk/config/test_shm-0.1.0.dadk
Normal file
23
user/dadk/config/test_shm-0.1.0.dadk
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "test_shm",
|
||||
"version": "0.1.0",
|
||||
"description": "测试共享内存",
|
||||
"task_type": {
|
||||
"BuildFromSource": {
|
||||
"Local": {
|
||||
"path": "apps/test_shm"
|
||||
}
|
||||
}
|
||||
},
|
||||
"depends": [ ],
|
||||
"build": {
|
||||
"build_command": "make install -j $(nproc)"
|
||||
},
|
||||
"install": {
|
||||
"in_dragonos_path": "/bin"
|
||||
},
|
||||
"clean": {
|
||||
"clean_command": "make clean"
|
||||
},
|
||||
"envs": []
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user