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