mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-22 02:53:23 +00:00
bugfix: 修复无法sleep的问题以及进程处于block(true)状态时无法被信号唤醒&唤醒后不处理信号的问题 (#470)
This commit is contained in:
@ -1,4 +1,7 @@
|
||||
use core::{fmt, ops};
|
||||
use core::{
|
||||
fmt,
|
||||
ops::{self, Sub},
|
||||
};
|
||||
|
||||
use self::timekeep::ktime_get_real_ns;
|
||||
|
||||
@ -54,6 +57,30 @@ impl TimeSpec {
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for TimeSpec {
|
||||
type Output = Duration;
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
let sec = self.tv_sec.checked_sub(rhs.tv_sec).unwrap_or(0);
|
||||
let nsec = self.tv_nsec.checked_sub(rhs.tv_nsec).unwrap_or(0);
|
||||
Duration::from_micros((sec * 1000000 + nsec / 1000) as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Duration> for TimeSpec {
|
||||
fn from(dur: Duration) -> Self {
|
||||
TimeSpec {
|
||||
tv_sec: dur.total_micros() as i64 / 1000000,
|
||||
tv_nsec: (dur.total_micros() as i64 % 1000000) * 1000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Duration> for TimeSpec {
|
||||
fn into(self) -> Duration {
|
||||
Duration::from_micros(self.tv_sec as u64 * 1000000 + self.tv_nsec as u64 / 1000)
|
||||
}
|
||||
}
|
||||
|
||||
/// A representation of an absolute time value.
|
||||
///
|
||||
/// The `Instant` type is a wrapper around a `i64` value that
|
||||
|
@ -8,6 +8,7 @@ use crate::{
|
||||
include::bindings::bindings::{useconds_t, Cpu_tsc_freq},
|
||||
process::ProcessManager,
|
||||
syscall::SystemError,
|
||||
time::timekeeping::getnstimeofday,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@ -27,8 +28,7 @@ pub fn nanosleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
// 对于小于500us的时间,使用spin/rdtsc来进行定时
|
||||
|
||||
if sleep_time.tv_nsec < 500000 {
|
||||
if sleep_time.tv_nsec < 500000 && sleep_time.tv_sec == 0 {
|
||||
let expired_tsc: u64 = unsafe {
|
||||
CurrentTimeArch::get_cycles() as u64
|
||||
+ (sleep_time.tv_nsec as u64 * Cpu_tsc_freq) / 1000000000
|
||||
@ -41,28 +41,29 @@ pub fn nanosleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
|
||||
tv_nsec: 0,
|
||||
});
|
||||
}
|
||||
|
||||
let total_sleep_time_us: u64 =
|
||||
sleep_time.tv_sec as u64 * 1000000 + sleep_time.tv_nsec as u64 / 1000;
|
||||
// 创建定时器
|
||||
let handler: Box<WakeUpHelper> = WakeUpHelper::new(ProcessManager::current_pcb());
|
||||
let timer: Arc<Timer> = Timer::new(
|
||||
handler,
|
||||
next_n_us_timer_jiffies((sleep_time.tv_nsec / 1000) as u64),
|
||||
);
|
||||
let timer: Arc<Timer> = Timer::new(handler, next_n_us_timer_jiffies(total_sleep_time_us));
|
||||
|
||||
let irq_guard: crate::exception::IrqFlagsGuard =
|
||||
unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||
ProcessManager::mark_sleep(true).ok();
|
||||
|
||||
let start_time = getnstimeofday();
|
||||
timer.activate();
|
||||
|
||||
drop(irq_guard);
|
||||
|
||||
sched();
|
||||
|
||||
// TODO: 增加信号唤醒的功能后,返回正确的剩余时间
|
||||
let end_time = getnstimeofday();
|
||||
// 返回正确的剩余时间
|
||||
let real_sleep_time = end_time - start_time;
|
||||
let rm_time: TimeSpec = (sleep_time - real_sleep_time.into()).into();
|
||||
|
||||
return Ok(TimeSpec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
});
|
||||
return Ok(rm_time);
|
||||
}
|
||||
|
||||
/// @brief 休眠指定时间(单位:微秒)
|
||||
|
Reference in New Issue
Block a user