]> Zhao Yanbai Git Server - kernel.git/commitdiff
优化AP展示进程运行时间的格式
authorzhaoyanbai <zhaoyanbai@126.com>
Sat, 15 Aug 2026 01:50:27 +0000 (09:50 +0800)
committerzhaoyanbai <zhaoyanbai@126.com>
Sat, 15 Aug 2026 01:50:27 +0000 (09:50 +0800)
include/system.h
kernel/ap.c
kernel/hpet.c
kernel/sched.c
kernel/system.c
kernel/task_root.c

index e8231d81177120e0725e18932aeb2cb4044e56b5..dce336f596736f68843a3dba0d4d92b2086964f6 100644 (file)
@@ -275,7 +275,9 @@ bool in_critical_zone();
 #define LEAVE_CRITICAL_ZONE(x) leave_critical_zone()
 #define IN_CRITICAL_ZONE() in_critical_zone()
 
-#endif
+uint64_t read_uint64_consistent(volatile uint64_t* p);
+
+#endif  // !ASM
 
 #define DISABLE_IDE 1
 
index 4a10353e7764ee221cd5481f558a2f18386823b8..bf70d43adf7a6dd3219756d09093dd00477ce5e1 100644 (file)
@@ -314,32 +314,37 @@ static char* format_runtime_tsc(uint64_t tsc) {
     uint64_t runtime_tsc = tsc;
     uint64_t _ms = 0;
     uint64_t _us = 0;
-    uint64_t _ns = 0;
+    // uint64_t _ns = 0;
     uint64_t _remainder = 0;
+
+    assert(tsc_khz != 0);
+
     udiv64(runtime_tsc, tsc_khz, &_ms, &_remainder);
     udiv64(_remainder * 1000, tsc_khz, &_us, &_remainder);
-    udiv64(_remainder * 1000, tsc_khz, &_ns, NULL);
+    // udiv64(_remainder * 1000, tsc_khz, &_ns, NULL);
 
     uint64_t total_seconds = 0;
-    uint64_t days = 0;
-    uint64_t hours = 0;
-    uint64_t minutes = 0;
-    uint64_t seconds = 0;
 
     // total_seconds = ms / 1000;
     // ms = ms % 1000
     udiv64(_ms, 1000, &total_seconds, &_ms);
 
+    static char buffer[64];
+    buffer[0] = 0;
+
+#if 0
+    uint64_t days = 0;
+    uint64_t hours = 0;
+    uint64_t minutes = 0;
+    uint64_t seconds = 0;
+
     // days = total_seconds / (60 * 60 * 24);
     udiv64(total_seconds, 60 * 60 * 24, &days, &total_seconds);
     udiv64(total_seconds, 60 * 60, &hours, &total_seconds);
     udiv64(total_seconds, 60, &minutes, &seconds);
 
-    static char buffer[64];
     char tmp[16];
 
-    buffer[0] = 0;
-
     if (days > 0) {
         sprintf(tmp, "%lud", days);
         strcat(buffer, tmp);
@@ -360,15 +365,23 @@ static char* format_runtime_tsc(uint64_t tsc) {
     uint32_t _ms32 = (uint32_t)_ms;
     uint32_t _us32 = (uint32_t)_us;
     _us32 /= 100;  // 保留1位小数
-    sprintf(tmp, ".%03u.%u", _ms32, _us32);
+    sprintf(tmp, ".%03u%u", _ms32, _us32);
     strcat(buffer, tmp);
+#else
+    uint64_t seconds = total_seconds;
+    uint32_t _ms32 = (uint32_t)_ms;
+    uint32_t _us32 = (uint32_t)_us;
+    _us32 /= 100;  // 保留1位小数
+    sprintf(buffer, "%lu.%03u%u", seconds, _ms32, _us32);
+#endif
 
     return (char*)buffer;
 }
+
 void print_all_tasks() {
     extern task_t* monitor_tasks[];
 
-    ap_printl(MPL_TASK_TITLE, "         NAME      STATE LT/PI REASON     TICKS     RUNTIME");
+    ap_printl(MPL_TASK_TITLE, "         NAME      STATE LT/PI REASON     TICKS          RUNTIME");
 
     for (int i = 0; i < 10; i++) {
         task_t* p = monitor_tasks[i];
@@ -377,9 +390,17 @@ void print_all_tasks() {
             continue;
         }
 
-        char* runtime_str = format_runtime_tsc(p->st_runtime_tsc);
+        // 此处非严格意义上的统计,只用于monitor
+        // 因为中间若正好发生 schedule 结算,可能发生多算或少算,影响有限,所以用最简单的实现
+        uint64_t runtime_tsc = read_uint64_consistent(&p->st_runtime_tsc);
+        uint64_t last_exec_tsc = read_uint64_consistent(&p->st_last_exec_tsc);
+        if (last_exec_tsc != 0) {  // 如果进程还在运行中,则算上还没结算的时间差
+            runtime_tsc += rdtsc() - last_exec_tsc;
+        }
+
+        char* runtime_str = format_runtime_tsc(runtime_tsc);
 
-        ap_printl(MPL_TASK_0 + p->pid, "%08x %-6s:%u %s %02d/%02u %-10s %-9lu %16s",
+        ap_printl(MPL_TASK_0 + p->pid, "%08x %-6s:%u %s %02d/%02u %-10s %-9lu %12s",
                   p,                     //
                   p->name,               //
                   p->pid,                //
index 7a0d2e0fdff481d647dcde93986d728683773c1b..a43a0e81b68353073d2e9c8f386dc9ca3bf29ac4 100644 (file)
@@ -223,7 +223,7 @@ void hpet_calibrate_tsc(uint32_t hz) {
     // tsc_khz = tsc_delta * hz / 1000;
     udiv64(tsc_delta * hz, 1000, &tsc_khz, NULL);
 
-    printk("TSC frequency: %u KHz\n", tsc_khz);
+    printk("TSC frequency: %lu KHz\n", tsc_khz);
 }
 
 void hpet_init() {
index 4720a5a6e394d1fed0f55153e2a296caf0889c34..bb26559593b88b77047cb1cc98be00cc600ff247 100644 (file)
@@ -62,7 +62,7 @@ void init_root_task() {
 
     task_init_lists(&root_task);
     task_init_stats(&root_task);
-    root_task.st_last_exec_tsc = rdtsc();
+    // root_task.st_last_exec_tsc = rdtsc();
 
     list_add(&root_task.list, &all_tasks);
 
index 04c5fba5d24387df7185d5cc4f1ee7fc2d68d785..0b3ca1e991b02e6121f91bbace5fe5ffc4ff2d12 100644 (file)
@@ -275,6 +275,22 @@ void udiv64(uint64_t dividend, uint64_t divisor, uint64_t* quotient, uint64_t* r
     }
 }
 
+uint64_t read_uint64_consistent(volatile uint64_t* p) {
+    uint32_t hi1 = 0;
+    uint32_t low = 0;
+    uint32_t hi2 = 0;
+
+    volatile uint32_t* w = (volatile uint32_t*)p;
+
+    do {
+        hi1 = w[1];
+        low = w[0];
+        hi2 = w[1];
+    } while (hi1 != hi2);
+
+    return ((uint64_t)hi1 << 32) | low;
+}
+
 paddr_t get_rcba_paddr() {
     uint32_t rcba = pci_get_rcba();
 
index d29285af502048f4ba4e5a2afcc8ea5d663c5b0c..0c01c299d6a46ed2f824ff850604a3a6a519e0c3 100644 (file)
@@ -73,7 +73,7 @@ void root_task_entry() {
            p--;
     }
 #endif
-
+    current->st_last_exec_tsc = rdtsc();
     sti();
 
     kernel_task("init", init_task_entry, NULL);