Browse Source

:new: 使用rdtsc进行精确定时

fslongjin 2 years ago
parent
commit
90203803d3
2 changed files with 20 additions and 10 deletions
  1. 1 0
      kernel/process/process.c
  2. 19 10
      kernel/time/sleep.c

+ 1 - 0
kernel/process/process.c

@@ -5,6 +5,7 @@
 #include <common/stdio.h>
 #include <common/compiler.h>
 #include <common/libELF/elf.h>
+#include <common/time.h>
 #include <driver/video/video.h>
 #include <driver/usb/usb.h>
 #include <exception/gate.h>

+ 19 - 10
kernel/time/sleep.c

@@ -4,6 +4,9 @@
 #include <process/process.h>
 #include <sched/sched.h>
 #include <mm/slab.h>
+#include <common/cpu.h>
+#include <common/glib.h>
+
 /**
  * @brief nanosleep定时事件到期后,唤醒指定的进程
  *
@@ -24,26 +27,32 @@ void nanosleep_handler(void *pcb)
 int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
 {
     int64_t total_ns = rqtp->tv_nsec;
-    // kdebug("totalns = %ld", total_ns);
+
     if (total_ns < 0 || total_ns >= 1000000000)
         return -EINVAL;
 
-    // todo: 对于小于500us的时间,使用spin/rdtsc来进行定时
-    if (total_ns < 50000)
-        return 0;
-
+    // 对于小于500us的时间,使用spin/rdtsc来进行定时
     if (total_ns < 500000)
-        total_ns = 500000;
+    {
+        kdebug("use rdtsc to nanosleep");
+        uint64_t expired_tsc = rdtsc() + (total_ns * Cpu_tsc_freq) / 1000000000;
+        while (rdtsc() < expired_tsc)
+            pause();
+
+        if (rmtp != NULL)
+        {
+            rmtp->tv_nsec = 0;
+            rmtp->tv_sec = 0;
+        }
+        return 0;
+    }
 
     // 增加定时任务
     struct timer_func_list_t *sleep_task = (struct timer_func_list_t *)kmalloc(sizeof(struct timer_func_list_t), 0);
     memset(sleep_task, 0, sizeof(struct timer_func_list_t));
 
-    
-
-    
     timer_func_init_us(sleep_task, &nanosleep_handler, (void *)current_pcb, total_ns / 1000);
-    
+
     timer_func_add(sleep_task);
 
     current_pcb->state = PROC_INTERRUPTIBLE;