Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions kernel/src/time/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
31 changes: 14 additions & 17 deletions kernel/src/time/timekeeping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion user/apps/test-mount/src/main.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -14,4 +15,6 @@ fn main() {
} else {
println!("Mount failed");
}
let dur = clock.elapsed();
println!("mount costing time: {} ns", dur.as_nanos());
}