Переглянути джерело

refactor(time): 将nanosleep系统调用适配新的syscall table (#1233)

Signed-off-by: longjin <longjin@DragonOS.org>
LoGin 1 день тому
батько
коміт
c8af029744

+ 0 - 15
kernel/src/syscall/mod.rs

@@ -264,21 +264,6 @@ impl Syscall {
                 Self::mkdir_at(dirfd, path, mode)
             }
 
-            SYS_NANOSLEEP => {
-                let req = args[0] as *const PosixTimeSpec;
-                let rem = args[1] as *mut PosixTimeSpec;
-                let virt_req = VirtAddr::new(req as usize);
-                let virt_rem = VirtAddr::new(rem as usize);
-                if frame.is_from_user()
-                    && (verify_area(virt_req, core::mem::size_of::<PosixTimeSpec>()).is_err()
-                        || verify_area(virt_rem, core::mem::size_of::<PosixTimeSpec>()).is_err())
-                {
-                    Err(SystemError::EFAULT)
-                } else {
-                    Self::nanosleep(req, rem)
-                }
-            }
-
             SYS_CLOCK => Self::clock(),
             SYS_UNLINKAT => {
                 let dirfd = args[0] as i32;

+ 2 - 34
kernel/src/time/syscall.rs → kernel/src/time/syscall/mod.rs

@@ -8,10 +8,11 @@ use system_error::SystemError;
 use crate::{
     process::{timer::AlarmTimer, ProcessManager},
     syscall::{user_access::UserBufferWriter, Syscall},
-    time::{sleep::nanosleep, PosixTimeSpec},
+    time::PosixTimeSpec,
 };
 
 use super::timekeeping::{do_gettimeofday, getnstimeofday};
+mod sys_nanosleep;
 
 pub type PosixTimeT = c_longlong;
 pub type PosixSusecondsT = c_int;
@@ -63,39 +64,6 @@ impl TryFrom<i32> for PosixClockID {
 }
 
 impl Syscall {
-    /// @brief 休眠指定时间(单位:纳秒)(提供给C的接口)
-    ///
-    /// @param sleep_time 指定休眠的时间
-    ///
-    /// @param rm_time 剩余休眠时间(传出参数)
-    ///
-    /// @return Ok(i32) 0
-    ///
-    /// @return Err(SystemError) 错误码
-    pub fn nanosleep(
-        sleep_time: *const PosixTimeSpec,
-        rm_time: *mut PosixTimeSpec,
-    ) -> Result<usize, SystemError> {
-        if sleep_time.is_null() {
-            return Err(SystemError::EFAULT);
-        }
-
-        let slt_spec = PosixTimeSpec {
-            tv_sec: unsafe { *sleep_time }.tv_sec,
-            tv_nsec: unsafe { *sleep_time }.tv_nsec,
-        };
-
-        let r: Result<usize, SystemError> = nanosleep(slt_spec).map(|slt_spec| {
-            if !rm_time.is_null() {
-                unsafe { *rm_time }.tv_sec = slt_spec.tv_sec;
-                unsafe { *rm_time }.tv_nsec = slt_spec.tv_nsec;
-            }
-            0
-        });
-
-        return r;
-    }
-
     /// 获取cpu时间
     ///
     /// todo: 该系统调用与Linux不一致,将来需要删除该系统调用!!! 删的时候记得改C版本的libc

+ 70 - 0
kernel/src/time/syscall/sys_nanosleep.rs

@@ -0,0 +1,70 @@
+use crate::arch::interrupt::TrapFrame;
+use crate::arch::syscall::nr::SYS_NANOSLEEP;
+use crate::syscall::table::{FormattedSyscallParam, Syscall};
+use crate::syscall::user_access::{UserBufferReader, UserBufferWriter};
+use crate::time::sleep::nanosleep;
+use crate::time::PosixTimeSpec;
+use alloc::vec::Vec;
+use system_error::SystemError;
+
+pub struct SysNanosleep;
+
+impl SysNanosleep {
+    fn sleep_time(args: &[usize]) -> *const PosixTimeSpec {
+        args[0] as *const PosixTimeSpec
+    }
+
+    fn rm_time(args: &[usize]) -> *mut PosixTimeSpec {
+        args[1] as *mut PosixTimeSpec
+    }
+}
+
+impl Syscall for SysNanosleep {
+    fn num_args(&self) -> usize {
+        1
+    }
+
+    fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
+        let sleep_time_reader = UserBufferReader::new(
+            Self::sleep_time(args),
+            core::mem::size_of::<PosixTimeSpec>(),
+            true,
+        )?;
+        let rm_time_ptr = Self::rm_time(args);
+        let mut rm_time_writer = if !rm_time_ptr.is_null() {
+            Some(UserBufferWriter::new(
+                rm_time_ptr,
+                core::mem::size_of::<PosixTimeSpec>(),
+                true,
+            )?)
+        } else {
+            None
+        };
+
+        let sleep_time = sleep_time_reader.read_one_from_user::<PosixTimeSpec>(0)?;
+
+        let slt_spec = PosixTimeSpec {
+            tv_sec: sleep_time.tv_sec,
+            tv_nsec: sleep_time.tv_nsec,
+        };
+        let r = nanosleep(slt_spec)?;
+        if let Some(ref mut rm_time) = rm_time_writer {
+            // 如果rm_time不为null,则将剩余时间写入rm_time
+            rm_time.copy_one_to_user(&r, 0)?;
+        }
+
+        return Ok(0);
+    }
+
+    fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
+        vec![
+            FormattedSyscallParam::new(
+                "sleep_time",
+                format!("{:#x}", Self::sleep_time(args) as usize),
+            ),
+            FormattedSyscallParam::new("rm_time", format!("{:#x}", Self::rm_time(args) as usize)),
+        ]
+    }
+}
+
+syscall_table_macros::declare_syscall!(SYS_NANOSLEEP, SysNanosleep);