refactor: kernel space yield() for controllable, flexible task switching
authorMinep <zelong56@gmail.com>
Fri, 12 Aug 2022 12:17:22 +0000 (13:17 +0100)
committerMinep <zelong56@gmail.com>
Fri, 12 Aug 2022 12:17:22 +0000 (13:17 +0100)
fix: incorrect control flow in getcwd(2) syscall

12 files changed:
lunaix-os/includes/arch/x86/interrupts.h
lunaix-os/includes/arch/x86/vectors.h
lunaix-os/includes/hal/cpu.h
lunaix-os/includes/lunaix/sched.h
lunaix-os/kernel/asm/x86/idt.c
lunaix-os/kernel/asm/x86/interrupt.S
lunaix-os/kernel/asm/x86/intr_routines.c
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/lxconsole.c
lunaix-os/kernel/sched.c
lunaix-os/kernel/signal.c
lunaix-os/kernel/time/timer.c

index 862ef05bc46bbb4d64f0b4b698e577a222e0b343..94c15e1e7396544f439c457d28f596b096c0f7b4 100644 (file)
@@ -63,6 +63,7 @@ ISR(21)
 
 ISR(32)
 ISR(33)
+ISR(34)
 
 ISR(201)
 ISR(202)
index e4a19688232967d480802c3cece4e1f1ff78861c..9873db6eb9586b5c205b6f02b34e72347548f58b 100644 (file)
@@ -29,6 +29,7 @@
 // LunaixOS related
 #define LUNAIX_SYS_PANIC                32
 #define LUNAIX_SYS_CALL                 33
+#define LUNAIX_SCHED                    34
 
 #define EX_INTERRUPT_BEGIN              200
 
index af56120b9ac29a38a2ad15073f20e790f8c11340..5789d4a41430f955d8c939f4e79d168d445a26cd 100644 (file)
@@ -117,6 +117,12 @@ cpu_invtlb()
         : "r"(interm));
 }
 
+static inline void
+cpu_int(int vect)
+{
+    asm("int %0" ::"i"(vect));
+}
+
 void
 cpu_rdmsr(uint32_t msr_idx, uint32_t* reg_high, uint32_t* reg_low);
 
index 69019f3a7a3c92cc796fd6e79010a4c98415f613..021b55e9e68a58830d5b08b2dd1b6fa8e4fcdd79 100644 (file)
@@ -17,6 +17,6 @@ void
 schedule();
 
 void
-sched_yield();
+sched_yieldk();
 
 #endif /* __LUNAIX_SCHEDULER_H */
index d2578f7dc7d890ff6c66e12a913233b7051dc473..e8b9524e46c41171ef6fa66f636e07c3b210ad9e 100644 (file)
@@ -63,4 +63,6 @@ _init_idt()
     // We make this a non-trap entry, and enable interrupt
     // only when needed!
     _set_idt_intr_entry(LUNAIX_SYS_CALL, 0x08, _asm_isr33, 3);
+
+    _set_idt_intr_entry(LUNAIX_SCHED, 0x08, _asm_isr34, 0);
 }
\ No newline at end of file
index 738214242db8573957dae50312ec285a66c14e80..b4ce936b91ab5ed24a7f14dbe10a098a1a431c0f 100644 (file)
@@ -36,6 +36,7 @@
 
     isr_template LUNAIX_SYS_PANIC
     isr_template LUNAIX_SYS_CALL
+    isr_template LUNAIX_SCHED
 
     isr_template APIC_ERROR_IV
     isr_template APIC_LINT0_IV
index 807dbe421e22ad2fe708e86ba40f69c776b82ef8..813490c2fe84363b9f49c6cadb3eafe444505c01 100644 (file)
@@ -1,6 +1,7 @@
 #include <arch/x86/interrupts.h>
 #include <lunaix/lxconsole.h>
 #include <lunaix/process.h>
+#include <lunaix/sched.h>
 #include <lunaix/spike.h>
 #include <lunaix/syslog.h>
 #include <lunaix/tty/tty.h>
@@ -84,6 +85,12 @@ intr_routine_apic_error(const isr_param* param)
     spin();
 }
 
+void
+intr_routine_sched(const isr_param* param)
+{
+    schedule();
+}
+
 void
 intr_routine_init()
 {
@@ -91,7 +98,10 @@ intr_routine_init()
     intr_subscribe(FAULT_GENERAL_PROTECTION, intr_routine_general_protection);
     intr_subscribe(FAULT_PAGE_FAULT, intr_routine_page_fault);
     intr_subscribe(FAULT_STACK_SEG_FAULT, intr_routine_page_fault);
+
     intr_subscribe(LUNAIX_SYS_PANIC, intr_routine_sys_panic);
+    intr_subscribe(LUNAIX_SCHED, intr_routine_sched);
+
     intr_subscribe(APIC_SPIV_IV, intr_routine_apic_spi);
     intr_subscribe(APIC_ERROR_IV, intr_routine_apic_error);
 
index e13b489226760544a232dacadaff09cda0387517..ad9fd709ea501893b4b58657820fae1290c6bd3e 100644 (file)
@@ -663,9 +663,8 @@ __DEFINE_LXSYSCALL3(int, read, int, fd, void*, buf, size_t, count)
         goto done;
     }
 
-    cpu_enable_interrupt();
-    errno = file->ops.read(file, buf, count, file->f_pos);
-    cpu_disable_interrupt();
+    __SYSCALL_INTERRUPTIBLE(
+      { errno = file->ops.read(file, buf, count, file->f_pos); })
 
     if (errno > 0) {
         file->f_pos += errno;
@@ -690,9 +689,8 @@ __DEFINE_LXSYSCALL3(int, write, int, fd, void*, buf, size_t, count)
         goto done;
     }
 
-    cpu_enable_interrupt();
-    errno = file->ops.write(file, buf, count, file->f_pos);
-    cpu_disable_interrupt();
+    __SYSCALL_INTERRUPTIBLE(
+      { errno = file->ops.write(file, buf, count, file->f_pos); })
 
     if (errno > 0) {
         file->f_pos += errno;
@@ -1103,15 +1101,17 @@ __DEFINE_LXSYSCALL2(char*, getcwd, char*, buf, size_t, size)
         goto done;
     }
 
+    size_t len = 0;
+
     if (!__current->cwd) {
         *buf = PATH_DELIM;
-        goto done;
-    }
-
-    size_t len = vfs_get_path(__current->cwd, buf, size, 0);
-    if (len == size) {
-        errno = ERANGE;
-        goto done;
+        len = 1;
+    } else {
+        len = vfs_get_path(__current->cwd, buf, size, 0);
+        if (len == size) {
+            errno = ERANGE;
+            goto done;
+        }
     }
 
     buf[len + 1] = '\0';
index e58e3f108fb7de8da6504ad617e1f1911f00afea..785330a4aa4b5d78b4ea9e06421281b55b48ea2f 100644 (file)
@@ -69,7 +69,7 @@ __tty_read(struct device* dev, void* buf, size_t offset, size_t len)
         //  When a key is arrived, one of the processes will win the race and
         //  swallow it (advancing the key buffer pointer)
         if (!kbd_recv_key(&keyevent)) {
-            sched_yield();
+            sched_yieldk();
             continue;
         }
         if (!(keyevent.state & KBD_KEY_FPRESSED)) {
index be9952519fe282993a29154123c89a90f8d7b249..4a0e254151799fdc6fc32674a36172c890be16c7 100644 (file)
@@ -145,6 +145,12 @@ redo:
     run(next);
 }
 
+void
+sched_yieldk()
+{
+    cpu_int(LUNAIX_SCHED);
+}
+
 __DEFINE_LXSYSCALL1(unsigned int, sleep, unsigned int, seconds)
 {
     if (!seconds) {
@@ -219,7 +225,6 @@ _wait(pid_t wpid, int* status, int options)
     }
 
     wpid = wpid ? wpid : -__current->pgid;
-    cpu_enable_interrupt();
 repeat:
     llist_for_each(proc, n, &__current->children, siblings)
     {
@@ -238,11 +243,10 @@ repeat:
         return 0;
     }
     // 放弃当前的运行机会
-    sched_yield();
+    sched_yieldk();
     goto repeat;
 
 done:
-    cpu_disable_interrupt();
     status_flags |= PEXITSIG * (proc->sig_inprogress != 0);
     if (status) {
         *status = proc->exit_code | status_flags;
@@ -330,7 +334,7 @@ destroy_process(pid_t pid)
     struct mm_region *pos, *n;
     llist_for_each(pos, n, &proc->mm.regions.head, head)
     {
-        lxfree(pos);
+        vfree(pos);
     }
 
     vmm_mount_pd(PD_MOUNT_1, proc->page_table);
index db1d4ff8ac89817f550905763fe3161196d55a4c..5f0c868789d9af36d6286dfae989b9a385e28546 100644 (file)
@@ -188,11 +188,10 @@ __do_pause()
 {
     __current->flags |= PROC_FINPAUSE;
 
-    __SYSCALL_INTERRUPTIBLE({
-        while ((__current->flags & PROC_FINPAUSE)) {
-            sched_yield();
-        }
-    })
+    while ((__current->flags & PROC_FINPAUSE)) {
+        sched_yieldk();
+    }
+
     __current->k_status = EINTR;
 }
 
index f479f581a34f6849593824bdb5dc1d37f4bcb59e..51c2c7fd11f942e1df888185b21d160060f9010b 100644 (file)
@@ -213,12 +213,6 @@ timer_update(const isr_param* param)
     }
 }
 
-void
-sched_yield()
-{
-    sched_ticks_counter = sched_ticks;
-}
-
 static void
 temp_intr_routine_rtc_tick(const isr_param* param)
 {