From 7380bba6c4c3ee2687eb2bf25b7907a7d2b47a7c Mon Sep 17 00:00:00 2001 From: zhaoyanbai Date: Sat, 15 Aug 2026 09:50:27 +0800 Subject: [PATCH] =?utf8?q?=E4=BC=98=E5=8C=96AP=E5=B1=95=E7=A4=BA=E8=BF=9B?= =?utf8?q?=E7=A8=8B=E8=BF=90=E8=A1=8C=E6=97=B6=E9=97=B4=E7=9A=84=E6=A0=BC?= =?utf8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- include/system.h | 4 +++- kernel/ap.c | 47 +++++++++++++++++++++++++++++++++------------- kernel/hpet.c | 2 +- kernel/sched.c | 2 +- kernel/system.c | 16 ++++++++++++++++ kernel/task_root.c | 2 +- 6 files changed, 56 insertions(+), 17 deletions(-) diff --git a/include/system.h b/include/system.h index e8231d8..dce336f 100644 --- a/include/system.h +++ b/include/system.h @@ -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 diff --git a/kernel/ap.c b/kernel/ap.c index 4a10353..bf70d43 100644 --- a/kernel/ap.c +++ b/kernel/ap.c @@ -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, // diff --git a/kernel/hpet.c b/kernel/hpet.c index 7a0d2e0..a43a0e8 100644 --- a/kernel/hpet.c +++ b/kernel/hpet.c @@ -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() { diff --git a/kernel/sched.c b/kernel/sched.c index 4720a5a..bb26559 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -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); diff --git a/kernel/system.c b/kernel/system.c index 04c5fba..0b3ca1e 100644 --- a/kernel/system.c +++ b/kernel/system.c @@ -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(); diff --git a/kernel/task_root.c b/kernel/task_root.c index d29285a..0c01c29 100644 --- a/kernel/task_root.c +++ b/kernel/task_root.c @@ -73,7 +73,7 @@ void root_task_entry() { p--; } #endif - + current->st_last_exec_tsc = rdtsc(); sti(); kernel_task("init", init_task_entry, NULL); -- 2.55.0