4
1
mirror of https://github.com/DragonOS-Community/DragonOS.git synced 2025-06-21 14:23:39 +00:00

软中断&定时器重构 (#223)

* 软中断&定时器重构

Co-authored-by: houmkh<houjiaying@DragonOS.org>

* 修改timer的clock()

* 删除debug信息

---------

Co-authored-by: houmkh <1119644616@qq.com>
This commit is contained in:
login
2023-04-02 17:09:33 +08:00
committed by GitHub
parent 6d345b7742
commit bacd691c9e
33 changed files with 896 additions and 672 deletions

139
kernel/src/time/sleep.rs Normal file

@ -0,0 +1,139 @@
use core::{arch::x86_64::_rdtsc, hint::spin_loop, ptr::null_mut};
use alloc::{boxed::Box, sync::Arc};
use crate::{
arch::{
asm::current::current_pcb,
interrupt::{cli, sti},
sched::sched,
},
include::bindings::bindings::{timespec, useconds_t, Cpu_tsc_freq},
syscall::SystemError,
};
use super::{
timer::{next_n_us_timer_jiffies, Timer, WakeUpHelper},
TimeSpec,
};
/// @brief 休眠指定时间(单位:纳秒)
///
/// @param sleep_time 指定休眠的时间
///
/// @return Ok(TimeSpec) 剩余休眠时间
///
/// @return Err(SystemError) 错误码
pub fn nano_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
if sleep_time.tv_nsec < 0 || sleep_time.tv_nsec >= 1000000000 {
return Err(SystemError::EINVAL);
}
// 对于小于500us的时间使用spin/rdtsc来进行定时
if sleep_time.tv_nsec < 500000 {
let expired_tsc: u64 =
unsafe { _rdtsc() + (sleep_time.tv_nsec as u64 * Cpu_tsc_freq) / 1000000000 };
while unsafe { _rdtsc() } < expired_tsc {
spin_loop()
}
return Ok(TimeSpec {
tv_sec: 0,
tv_nsec: 0,
});
}
// 创建定时器
let handler: Box<WakeUpHelper> = WakeUpHelper::new(current_pcb());
let timer: Arc<Timer> = Timer::new(
handler,
next_n_us_timer_jiffies((sleep_time.tv_nsec / 1000) as u64),
);
cli();
timer.activate();
unsafe {
current_pcb().mark_sleep_interruptible();
}
sti();
sched();
// TODO: 增加信号唤醒的功能后,返回正确的剩余时间
return Ok(TimeSpec {
tv_sec: 0,
tv_nsec: 0,
});
}
/// @brief 休眠指定时间(单位:微秒)
///
/// @param usec 微秒
///
/// @return Ok(TimeSpec) 剩余休眠时间
///
/// @return Err(SystemError) 错误码
pub fn us_sleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
match nano_sleep(sleep_time) {
Ok(value) => return Ok(value),
Err(err) => return Err(err),
};
}
//===== 以下为提供给C的接口 =====
/// @brief 休眠指定时间单位纳秒提供给C的接口
///
/// @param sleep_time 指定休眠的时间
///
/// @param rm_time 剩余休眠时间(传出参数)
///
/// @return Ok(i32) 0
///
/// @return Err(SystemError) 错误码
#[no_mangle]
pub extern "C" fn rs_nanosleep(sleep_time: *const timespec, rm_time: *mut timespec) -> i32 {
if sleep_time == null_mut() {
return SystemError::EINVAL.to_posix_errno();
}
let slt_spec = TimeSpec {
tv_sec: unsafe { *sleep_time }.tv_sec,
tv_nsec: unsafe { *sleep_time }.tv_nsec,
};
match nano_sleep(slt_spec) {
Ok(value) => {
if rm_time != null_mut() {
unsafe { *rm_time }.tv_sec = value.tv_sec;
unsafe { *rm_time }.tv_nsec = value.tv_nsec;
}
return 0;
}
Err(err) => {
return err.to_posix_errno();
}
}
}
/// @brief 休眠指定时间单位微秒提供给C的接口
///
/// @param usec 微秒
///
/// @return Ok(i32) 0
///
/// @return Err(SystemError) 错误码
#[no_mangle]
pub extern "C" fn rs_usleep(usec: useconds_t) -> i32 {
let sleep_time = TimeSpec {
tv_sec: (usec / 1000000) as i64,
tv_nsec: ((usec % 1000000) * 1000) as i64,
};
match us_sleep(sleep_time) {
Ok(_) => {
return 0;
}
Err(err) => {
return err.to_posix_errno();
}
};
}