修复clock_gettime返回类型错误,修复小时间间隔duration返回0问题 (#664)

* 修复clock_gettime返回类型错误,修正wtm初始化逻辑

* 修复duration在小时间间隔下为0的问题

* 临时修复时间流逝速度异常,在test-mount中加入运行时间检测
This commit is contained in:
Donkey Kane 2024-03-25 13:04:32 +08:00 committed by GitHub
parent 401699735b
commit 911132c4b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 21 deletions

View File

@ -8,7 +8,7 @@ use crate::{
time::{sleep::nanosleep, TimeSpec},
};
use super::timekeeping::do_gettimeofday;
use super::timekeeping::{do_gettimeofday, getnstimeofday};
pub type PosixTimeT = c_longlong;
pub type PosixSusecondsT = c_int;
@ -142,9 +142,9 @@ impl Syscall {
let mut tp_buf =
UserBufferWriter::new::<TimeSpec>(tp, core::mem::size_of::<TimeSpec>(), true)?;
let posix_time = do_gettimeofday();
let timespec = getnstimeofday();
tp_buf.copy_one_to_user(&posix_time, 0)?;
tp_buf.copy_one_to_user(&timespec, 0)?;
return Ok(0);
}

View File

@ -140,9 +140,10 @@ impl Timekeeper {
let clock = timekeeper.clock.clone().unwrap();
drop(timekeeper);
let clock_now = clock.read();
let clcok_data = clock.clocksource_data();
let clock_delta = clock_now.div(clcok_data.watchdog_last).data() & clcok_data.mask.bits();
return clocksource_cyc2ns(CycleNum(clock_delta), clcok_data.mult, clcok_data.shift);
let clock_data = clock.clocksource_data();
let clock_delta = clock_now.div(clock_data.watchdog_last).data() & clock_data.mask.bits();
// clock_shift的值错误导致时间流逝速度异常+5为临时修改以确保系统正常运作目前追踪到的设置在DragonOS-dev/blob/fix_time/kernel/src/time/jiffies.rs#L18但是修改无效
return clocksource_cyc2ns(CycleNum(clock_delta), clock_data.mult, clock_data.shift + 5);
}
}
pub fn timekeeper() -> &'static Timekeeper {
@ -163,7 +164,7 @@ pub fn timekeeper_init() {
pub fn getnstimeofday() -> TimeSpec {
// kdebug!("enter getnstimeofday");
// let mut nsecs: u64 = 0;0
let nsecs;
let mut _xtime = TimeSpec {
tv_nsec: 0,
tv_sec: 0,
@ -174,15 +175,15 @@ pub fn getnstimeofday() -> TimeSpec {
Some(tk) => {
_xtime = tk.xtime;
drop(tk);
// nsecs = timekeeper().tk_get_ns();
nsecs = timekeeper().tk_get_ns();
// TODO 不同架构可能需要加上不同的偏移量
break;
}
}
}
// xtime.tv_nsec += nsecs as i64;
let sec = __ADDED_SEC.load(Ordering::SeqCst);
_xtime.tv_sec += sec;
_xtime.tv_nsec += nsecs as i64;
// let sec = __ADDED_SEC.load(Ordering::SeqCst);
// _xtime.tv_sec += sec;
while _xtime.tv_nsec >= NSEC_PER_SEC.into() {
_xtime.tv_nsec -= NSEC_PER_SEC as i64;
_xtime.tv_sec += 1;
@ -224,15 +225,11 @@ pub fn timekeeping_init() {
let mut timekeeper = timekeeper().0.write_irqsave();
timekeeper.xtime.tv_nsec = ktime_get_real_ns();
// 初始化wall time到monotonic的时间
let mut nsec = -timekeeper.xtime.tv_nsec;
let mut sec = -timekeeper.xtime.tv_sec;
// FIXME: 这里有个奇怪的奇怪的bug
let num = nsec % NSEC_PER_SEC as i64;
nsec += num * NSEC_PER_SEC as i64;
sec -= num;
timekeeper.wall_to_monotonic.tv_nsec = nsec;
timekeeper.wall_to_monotonic.tv_sec = sec;
//参考https://elixir.bootlin.com/linux/v4.4/source/kernel/time/timekeeping.c#L1251 对wtm进行初始化
(
timekeeper.wall_to_monotonic.tv_nsec,
timekeeper.wall_to_monotonic.tv_sec,
) = (-timekeeper.xtime.tv_nsec, -timekeeper.xtime.tv_sec);
__ADDED_USEC.store(0, Ordering::SeqCst);
__ADDED_SEC.store(0, Ordering::SeqCst);

View File

@ -1,7 +1,8 @@
use core::ffi::{c_char, c_void};
use libc::{mount, MS_BIND};
use std::time;
fn main() {
let clock = time::Instant::now();
let source = b"\0".as_ptr() as *const c_char;
let target = b"/mnt/tmp\0".as_ptr() as *const c_char;
let fstype = b"ramfs\0".as_ptr() as *const c_char;
@ -14,4 +15,6 @@ fn main() {
} else {
println!("Mount failed");
}
let dur = clock.elapsed();
println!("mount costing time: {} ns", dur.as_nanos());
}