实现SystemV共享内存 (#690)

* 实现SystemV共享内存

* 测试shm

* 添加测试程序

* 完善细节

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

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

---------

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

View File

@ -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)
}
}

View File

@ -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,
};

View File

@ -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();

View File

@ -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);
}

View File

@ -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