From 8612b6ce7afc903999ccf0b65bd65019484d2fad Mon Sep 17 00:00:00 2001 From: LoGin Date: Tue, 19 Dec 2023 11:56:14 +0800 Subject: [PATCH] =?UTF-8?q?bugfix:=20=E4=BF=AE=E5=A4=8D=E6=97=A0=E6=B3=95s?= =?UTF-8?q?leep=E7=9A=84=E9=97=AE=E9=A2=98=E4=BB=A5=E5=8F=8A=E8=BF=9B?= =?UTF-8?q?=E7=A8=8B=E5=A4=84=E4=BA=8Eblock(true)=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=97=B6=E6=97=A0=E6=B3=95=E8=A2=AB=E4=BF=A1=E5=8F=B7=E5=94=A4?= =?UTF-8?q?=E9=86=92&=E5=94=A4=E9=86=92=E5=90=8E=E4=B8=8D=E5=A4=84?= =?UTF-8?q?=E7=90=86=E4=BF=A1=E5=8F=B7=E7=9A=84=E9=97=AE=E9=A2=98=20(#470)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/arch/x86_64/asm/entry.S | 4 ++++ kernel/src/arch/x86_64/ipc/signal.rs | 2 +- kernel/src/ipc/signal.rs | 28 +++++++++++++------------ kernel/src/syscall/mod.rs | 6 ------ kernel/src/time/mod.rs | 29 +++++++++++++++++++++++++- kernel/src/time/sleep.rs | 25 +++++++++++----------- user/dadk/config/nova_shell-0.1.0.dadk | 2 +- user/dadk/config/relibc-0.1.0.dadk | 4 ++-- 8 files changed, 64 insertions(+), 36 deletions(-) diff --git a/kernel/src/arch/x86_64/asm/entry.S b/kernel/src/arch/x86_64/asm/entry.S index a5d526c2b..abfc3d35c 100644 --- a/kernel/src/arch/x86_64/asm/entry.S +++ b/kernel/src/arch/x86_64/asm/entry.S @@ -374,6 +374,10 @@ ENTRY(syscall_64) callq *%rdx //调用服务程序 + // 将原本要返回的栈帧的栈指针传入do_signal的第一个参数 + movq %rsp, %rdi + callq do_signal + cli // === 恢复调用现场 === diff --git a/kernel/src/arch/x86_64/ipc/signal.rs b/kernel/src/arch/x86_64/ipc/signal.rs index 70c31ae07..f2a882640 100644 --- a/kernel/src/arch/x86_64/ipc/signal.rs +++ b/kernel/src/arch/x86_64/ipc/signal.rs @@ -495,7 +495,7 @@ impl SignalArch for X86_64SignalArch { } fn sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64 { - let frame = (trap_frame.rsp as usize) as *mut SigFrame; + let frame = (trap_frame.rsp as usize - size_of::()) as *mut SigFrame; // 如果当前的rsp不来自用户态,则认为产生了错误(或被SROP攻击) if UserBufferWriter::new(frame, size_of::(), true).is_err() { diff --git a/kernel/src/ipc/signal.rs b/kernel/src/ipc/signal.rs index b47dd001a..be5b92bc8 100644 --- a/kernel/src/ipc/signal.rs +++ b/kernel/src/ipc/signal.rs @@ -141,12 +141,7 @@ impl Signal { /// @param pt siginfo结构体中,pid字段代表的含义 fn complete_signal(&self, pcb: Arc, pt: PidType) { // kdebug!("complete_signal"); - // todo: 将信号产生的消息通知到正在监听这个信号的进程(引入signalfd之后,在这里调用signalfd_notify) - // 将这个信号加到目标进程的sig_pending中 - pcb.sig_info_mut() - .sig_pending_mut() - .signal_mut() - .insert(self.clone().into()); + compiler_fence(core::sync::atomic::Ordering::SeqCst); // ===== 寻找需要wakeup的目标进程 ===== // 备注:由于当前没有进程组的概念,每个进程只有1个对应的线程,因此不需要通知进程组内的每个进程。 @@ -154,11 +149,17 @@ impl Signal { // let _signal = pcb.sig_struct(); - let mut _target: Option> = None; + let target_pcb: Option>; // 判断目标进程是否想接收这个信号 if self.wants_signal(pcb.clone()) { - _target = Some(pcb.clone()); + // todo: 将信号产生的消息通知到正在监听这个信号的进程(引入signalfd之后,在这里调用signalfd_notify) + // 将这个信号加到目标进程的sig_pending中 + pcb.sig_info_mut() + .sig_pending_mut() + .signal_mut() + .insert(self.clone().into()); + target_pcb = Some(pcb.clone()); } else if pt == PidType::PID { /* * There is just one thread and it does not need to be woken. @@ -176,9 +177,9 @@ impl Signal { // TODO:引入进程组后,在这里挑选一个进程来唤醒,让它执行相应的操作。 compiler_fence(core::sync::atomic::Ordering::SeqCst); // TODO: 到这里,信号已经被放置在共享的pending队列中,我们在这里把目标进程唤醒。 - if _target.is_some() { - let guard = pcb.sig_struct(); - signal_wake_up(pcb.clone(), guard, *self == Signal::SIGKILL); + if let Some(target_pcb) = target_pcb { + let guard = target_pcb.sig_struct(); + signal_wake_up(target_pcb.clone(), guard, *self == Signal::SIGKILL); } } @@ -201,7 +202,9 @@ impl Signal { return true; } - if pcb.sched_info().state().is_blocked() { + if pcb.sched_info().state().is_blocked() + && (pcb.sched_info().state().is_blocked_interruptable() == false) + { return false; } @@ -209,7 +212,6 @@ impl Signal { // 检查目标进程是否有信号正在等待处理,如果是,则返回false,否则返回true if pcb.sig_info().sig_pending().signal().bits() == 0 { - assert!(pcb.sig_info().sig_pending().queue().q.is_empty()); return true; } else { return false; diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index cc1891fea..b0c4d40c8 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -702,12 +702,6 @@ impl Syscall { Self::sigaction(sig, act, old_act, frame.from_user()) } - SYS_RT_SIGRETURN => { - // 由于目前signal机制的实现,与x86_64强关联,因此暂时在arch/x86_64/syscall.rs中调用 - // todo: 未来需要将signal机制与平台解耦 - todo!() - } - SYS_GETPID => Self::getpid().map(|pid| pid.into()), SYS_SCHED => Self::sched(frame.from_user()), diff --git a/kernel/src/time/mod.rs b/kernel/src/time/mod.rs index 9e70f7074..2a119ef23 100644 --- a/kernel/src/time/mod.rs +++ b/kernel/src/time/mod.rs @@ -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 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 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 diff --git a/kernel/src/time/sleep.rs b/kernel/src/time/sleep.rs index c1c2ff643..aa3517f8f 100644 --- a/kernel/src/time/sleep.rs +++ b/kernel/src/time/sleep.rs @@ -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 { 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 { 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::new(ProcessManager::current_pcb()); - let timer: Arc = Timer::new( - handler, - next_n_us_timer_jiffies((sleep_time.tv_nsec / 1000) as u64), - ); + let timer: Arc = 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 休眠指定时间(单位:微秒) diff --git a/user/dadk/config/nova_shell-0.1.0.dadk b/user/dadk/config/nova_shell-0.1.0.dadk index f1d79db5f..9b56ad406 100644 --- a/user/dadk/config/nova_shell-0.1.0.dadk +++ b/user/dadk/config/nova_shell-0.1.0.dadk @@ -6,7 +6,7 @@ "BuildFromSource": { "Git": { "url": "https://git.mirrors.dragonos.org.cn/DragonOS-Community/NovaShell.git", - "revision": "95738b235f" + "revision": "4160a0a0de" } } }, diff --git a/user/dadk/config/relibc-0.1.0.dadk b/user/dadk/config/relibc-0.1.0.dadk index 508f28f2d..a90b830a5 100644 --- a/user/dadk/config/relibc-0.1.0.dadk +++ b/user/dadk/config/relibc-0.1.0.dadk @@ -5,8 +5,8 @@ "task_type": { "BuildFromSource": { "Git": { - "url": "https://git.mirrors.dragonos.org/DragonOS-Community/relibc.git", - "revision": "3ef630632f" + "url": "https://git.mirrors.dragonos.org.cn/DragonOS-Community/relibc.git", + "revision": "27e779dc23" } } },