From ba6ad79344ae5c3fc7cdd113e34fd699808c1ab1 Mon Sep 17 00:00:00 2001 From: acevest Date: Mon, 12 Jan 2026 21:24:49 +0800 Subject: [PATCH] =?utf8?q?=E6=B7=BB=E5=8A=A0=E7=A6=81=E6=AD=A2=E6=8A=A2?= =?utf8?q?=E5=8D=A0=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- fs/file.c | 12 ++++++------ include/irq.h | 9 --------- include/system.h | 11 +++++++++++ kernel/irq.c | 16 +++------------- kernel/printk.c | 6 +++--- kernel/system.c | 15 +++++++++++++++ 6 files changed, 38 insertions(+), 31 deletions(-) diff --git a/fs/file.c b/fs/file.c index 2f1dc0a..7ce7015 100644 --- a/fs/file.c +++ b/fs/file.c @@ -62,7 +62,7 @@ page_t* find_hash_page(address_space_t* mapping, uint32_t index) { p = p->hash_next; } - EXIT_CRITICAL_ZONE(EFLAGS); + LEAVE_CRITICAL_ZONE(EFLAGS); return page; } @@ -78,7 +78,7 @@ void add_page_to_hash(page_t* page, address_space_t* mapping, uint32_t index) { p = page_hash_table[hash]; page->hash_next = p; page_hash_table[hash] = page; - EXIT_CRITICAL_ZONE(EFLAGS); + LEAVE_CRITICAL_ZONE(EFLAGS); } void add_page_to_inode(address_space_t* mapping, page_t* page) { @@ -88,7 +88,7 @@ void add_page_to_inode(address_space_t* mapping, page_t* page) { ENTER_CRITICAL_ZONE(EFLAGS); list_add(&page->list, &mapping->pages); - EXIT_CRITICAL_ZONE(EFLAGS); + LEAVE_CRITICAL_ZONE(EFLAGS); } page_t* get_cached_page(address_space_t* mapping, uint32_t index) { @@ -106,7 +106,7 @@ page_t* get_cached_page(address_space_t* mapping, uint32_t index) { ENTER_CRITICAL_ZONE(EFLAGS); list_add(&page->list, &mapping->pages); - EXIT_CRITICAL_ZONE(EFLAGS); + LEAVE_CRITICAL_ZONE(EFLAGS); } return page; @@ -148,11 +148,11 @@ file_t* get_empty_filp() { if (p->f_state == 0) { p->f_state = 1; fp = p; - EXIT_CRITICAL_ZONE(EFLAGS); + LEAVE_CRITICAL_ZONE(EFLAGS); break; } - EXIT_CRITICAL_ZONE(EFLAGS); + LEAVE_CRITICAL_ZONE(EFLAGS); } } diff --git a/include/irq.h b/include/irq.h index 2993270..3d629a9 100644 --- a/include/irq.h +++ b/include/irq.h @@ -76,15 +76,6 @@ bool irq_disabled(); __asm__ __volatile__("pushl %0; popfl" ::"g"(x) : "memory", "cc"); \ } while (0) -void enter_critical_zone(); -void exit_critical_zone(); - -#define ENTER_CRITICAL_ZONE(x) \ - volatile uint32_t __critical_zone_eflags_##x = 0; \ - irq_save(__critical_zone_eflags_##x); - -#define EXIT_CRITICAL_ZONE(x) irq_restore(__critical_zone_eflags_##x); - #define IRQ_CLOCK 0x00 #define IRQ_KEYBOARD 0x01 #define IRQ_CASCADE 0x02 diff --git a/include/system.h b/include/system.h index b2e9142..74c4de2 100644 --- a/include/system.h +++ b/include/system.h @@ -259,6 +259,17 @@ void boot_delay(int ticks); void io_mfence(); paddr_t get_rcba_paddr(); + +extern uint32_t preempt_count; + +void enter_critical_zone(); +void leave_critical_zone(); +bool in_critical_zone(); + +#define ENTER_CRITICAL_ZONE(x) enter_critical_zone() +#define LEAVE_CRITICAL_ZONE(x) leave_critical_zone() +#define IN_CRITICAL_ZONE() in_critical_zone() + #endif #define DISABLE_IDE 1 diff --git a/kernel/irq.c b/kernel/irq.c index 95d27f2..b40d7fb 100644 --- a/kernel/irq.c +++ b/kernel/irq.c @@ -99,7 +99,9 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t* regs) { enable_irq(); // 如果需要调度程序 - schedule(); + if (!IN_CRITICAL_ZONE()) { + schedule(); + } #endif } @@ -283,18 +285,6 @@ int disable_no_irq_chip(unsigned int irq) { irq_chip_t no_irq_chip = {.name = "none", .enable = enable_no_irq_chip, .disable = disable_no_irq_chip}; irq_desc_t no_irq_desc = {.chip = &no_irq_chip, .action = NULL, .status = 0, .depth = 0}; -// 单CPU -// 这里的代码有BUG,如果嵌套调用的话 -// __critical_zone_eflags的值会被统一设置为最里层时的eflags -// 意味着如果IF置位了的话,必定会丢失这个信息 -static volatile uint32_t __critical_zone_eflags; -void enter_critical_zone() { - irq_save(__critical_zone_eflags); -} -void exit_critical_zone() { - irq_restore(__critical_zone_eflags); -} - void irq_set_chip(unsigned int irq, irq_chip_t* chip) { assert(irq < NR_IRQS); assert(chip != NULL); diff --git a/kernel/printk.c b/kernel/printk.c index 3ea2c80..635820d 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -33,7 +33,7 @@ int printk(const char* fmtstr, ...) { tty_write(default_tty, pkbuf, (size_t)size); serial_write(pkbuf, (size_t)size); - EXIT_CRITICAL_ZONE(EFLAGS); + LEAVE_CRITICAL_ZONE(EFLAGS); return 0; } @@ -47,7 +47,7 @@ int printd(const char* fmtstr, ...) { tty_write(debug_tty, pdbuf, (size_t)size); serial_write(pdbuf, (size_t)size); - EXIT_CRITICAL_ZONE(EFLAGS); + LEAVE_CRITICAL_ZONE(EFLAGS); return 0; } @@ -60,6 +60,6 @@ int printlo(unsigned int xpos, unsigned int ypos, const char* fmtstr, ...) { tty_write_at(monitor_tty, xpos, ypos, plobuf, (size_t)size); - EXIT_CRITICAL_ZONE(EFLAGS); + LEAVE_CRITICAL_ZONE(EFLAGS); return 0; } diff --git a/kernel/system.c b/kernel/system.c index 25aad4c..18f5b2a 100644 --- a/kernel/system.c +++ b/kernel/system.c @@ -251,3 +251,18 @@ paddr_t get_rcba_paddr() { return rcba_paddr; } + +// +uint32_t preempt_count = 0; + +void enter_critical_zone() { + preempt_count++; +} + +void leave_critical_zone() { + preempt_count--; +} + +bool in_critical_zone() { + return preempt_count > 0; +} -- 2.47.0