From 5cd8a2ac2f85bdb43ac33bbdbe0d085d21027c41 Mon Sep 17 00:00:00 2001
From: pierrecashon <2938806204@qq.com>
Date: Thu, 10 Apr 2025 21:20:11 +0800
Subject: [PATCH] dev-add_clock_nanosleep

---
 os/src/syscall/mod.rs                      |  7 ++++
 os/src/syscall/process.rs                  | 48 ++++++++++++++++++++++
 testcase/basic/riscv64/busybox_testcode.sh |  4 +-
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs
index d696217..db7e9df 100644
--- a/os/src/syscall/mod.rs
+++ b/os/src/syscall/mod.rs
@@ -44,6 +44,7 @@ const SYSCALL_SET_ROBUST_LIST:usize = 99;
 const SYSCALL_GET_ROBUST_LIST:usize = 100;
 const SYSCALL_NANOSLEEP: usize = 101;
 const SYSCALL_CLOCK_GETTIME: usize =113;
+const SYSCALL_CLOCK_NANOSLEEP: usize =115;
 const SYSCALL_SYSLOG: usize = 116;
 const SYSCALL_YIELD: usize = 124;
 const SYSCALL_SETGID: usize = 144;
@@ -286,6 +287,9 @@ pub fn syscall(syscall_id: usize, args: [usize; 6]) -> isize {
         SYSCALL_CLOCK_GETTIME => {
             result = sys_clock_gettime(args[0], args[1] as *mut TimeSpec);
         }
+        SYSCALL_CLOCK_NANOSLEEP => {
+            result = sys_clock_nanosleep(args[0],args[1], args[2] as *const TimeSpec,args[3] as *mut TimeSpec);
+        }
         SYSCALL_RENAMEAT2 => {
             result = sys_renameat2(args[0] as isize, args[1] as *const u8, args[2] as isize,args[3] as *const u8,args[4]);
         }
@@ -525,6 +529,9 @@ fn sysid_to_string(syscall_id: usize)->String{
         SYSCALL_RENAMEAT2 => {
             ret.push_str("sys_renameat2");
         }
+        SYSCALL_CLOCK_NANOSLEEP => {
+            ret.push_str("sys_clock_nanosleep");
+        }
         _ => panic!("Unsupported syscall_id: {}", syscall_id),
     }
     ret
diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs
index 8ffda32..6685297 100644
--- a/os/src/syscall/process.rs
+++ b/os/src/syscall/process.rs
@@ -676,3 +676,51 @@ pub fn sys_sigreturn() -> isize {
         -1
     }
 }
+
+pub fn sys_clock_nanosleep(clockid: usize,flags:usize,request:*const TimeSpec,remain:*mut TimeSpec)->SysResult<isize>{
+    pub const TIMER_ABSTIME: usize = 1;
+    match clockid {
+        CLOCK_REALTIME | CLOCK_MONOTONIC => {
+            let token = current_user_token();
+            let request = translated_ref(token, request);
+            let req= request.sec * 1000000000 + request.usec; 
+            let total_time;
+            let mut rem:TimeSpec = TimeSpec{sec:0,usec:0};
+            if flags == TIMER_ABSTIME {
+                let current_time = Time::now().to_nsec();
+                // request time is absolutely
+                if req.le(&current_time) {
+                    return Ok(0);
+                }
+                total_time = req - current_time;
+            } else {
+                total_time = req;
+            };
+            let start_time = Time::now().to_nsec();
+            loop{
+                let current_time = Time::now().to_nsec();
+                if current_time - start_time < total_time{
+                    rem.sec = (total_time - current_time + start_time) / 1000000000;
+                    rem.usec = (total_time - current_time + start_time) % 1000000000;
+                    suspend_current_and_run_next();
+                }
+                else{
+                    rem.sec = 0;
+                    rem.usec = 0;
+                    break;
+                }
+            }
+            if rem.sec == 0 &&rem.usec == 0 {
+                Ok(0)
+            } else {
+                if !remain.is_null() {
+                    *translated_refmut(token, remain) = rem;
+                }
+                Err(SysError::EINTR)
+            }
+        }
+        _ => {
+            return Err(SysError::EINVAL);
+        }
+    }
+}
diff --git a/testcase/basic/riscv64/busybox_testcode.sh b/testcase/basic/riscv64/busybox_testcode.sh
index 1bf2ca9..823b1b7 100644
--- a/testcase/basic/riscv64/busybox_testcode.sh
+++ b/testcase/basic/riscv64/busybox_testcode.sh
@@ -1,6 +1,6 @@
 #!/busybox sh
 
-#./busybox echo "#### OS COMP TEST GROUP START busybox-glibc ####"
+./busybox echo "#### OS COMP TEST GROUP START busybox-glibc ####"
 # RST=result.txt
 # if [ -f $RST ];then
 # 	rm $RST
@@ -24,4 +24,4 @@ do
 done
 
 # echo "TEST END" >> $RST
-#./busybox echo "#### OS COMP TEST GROUP END busybox-glibc ####"
+./busybox echo "#### OS COMP TEST GROUP END busybox-glibc ####"
-- 
GitLab