refactor: simplify the vmm design, single responsibility. But using it should with...
[lunaix-os.git] / lunaix-os / kernel / sched.c
index 35e3cff5c69f2a6164a40009cc48d560eb3e1bc5..a93c9bb5e37a87802df17a761039793bca0cb607 100644 (file)
@@ -1,12 +1,15 @@
 #include <arch/x86/interrupts.h>
 #include <arch/x86/tss.h>
+
 #include <hal/apic.h>
 #include <hal/cpu.h>
+
 #include <lunaix/mm/kalloc.h>
+#include <lunaix/mm/pmm.h>
 #include <lunaix/mm/vmm.h>
 #include <lunaix/process.h>
 #include <lunaix/sched.h>
-
+#include <lunaix/signal.h>
 #include <lunaix/spike.h>
 #include <lunaix/status.h>
 #include <lunaix/syscall.h>
@@ -28,9 +31,11 @@ void
 sched_init()
 {
     size_t pg_size = ROUNDUP(sizeof(struct proc_info) * MAX_PROCESS, 0x1000);
-    assert_msg(vmm_alloc_pages(
-                 KERNEL_PID, &__proc_table, pg_size, PG_PREM_RW, PP_FGPERSIST),
-               "Fail to allocate proc table");
+
+    for (size_t i = 0; i <= pg_size; i += 4096) {
+        uintptr_t pa = pmm_alloc_page(KERNEL_PID, PP_FGPERSIST);
+        vmm_set_mapping(PD_REFERENCED, &__proc_table + i, pa, PG_PREM_RW);
+    }
 
     sched_ctx = (struct scheduler){ ._procs = (struct proc_info*)&__proc_table,
                                     .ptable_len = 0,
@@ -47,20 +52,10 @@ run(struct proc_info* proc)
 
     // FIXME: 这里还是得再考虑一下。
     // tss_update_esp(__current->intr_ctx.esp);
-
-    if (__current->page_table != proc->page_table) {
-        __current = proc;
-        cpu_lcr3(__current->page_table);
-        // from now on, the we are in the kstack of another process
-    } else {
-        __current = proc;
-    }
-
     apic_done_servicing();
 
     asm volatile("pushl %0\n"
-                 "jmp soft_iret\n" ::"r"(&__current->intr_ctx)
-                 : "memory");
+                 "jmp switch_to\n" ::"r"(proc)); // kernel/asm/x86/interrupt.S
 }
 
 void
@@ -70,6 +65,8 @@ schedule()
         return;
     }
 
+    // 上下文切换相当的敏感!我们不希望任何的中断打乱栈的顺序……
+    cpu_disable_interrupt();
     struct proc_info* next;
     int prev_ptr = sched_ctx.procs_index;
     int ptr = prev_ptr;
@@ -81,8 +78,6 @@ schedule()
 
     sched_ctx.procs_index = ptr;
 
-    // 上下文切换相当的敏感!我们不希望任何的中断打乱栈的顺序……
-    cpu_disable_interrupt();
     run(next);
 }
 
@@ -99,6 +94,7 @@ __DEFINE_LXSYSCALL1(unsigned int, sleep, unsigned int, seconds)
     if (!seconds) {
         return 0;
     }
+
     if (__current->timer) {
         return __current->timer->counter / timer_context()->running_frequency;
     }
@@ -118,7 +114,7 @@ __DEFINE_LXSYSCALL1(void, exit, int, status)
 
 __DEFINE_LXSYSCALL(void, yield)
 {
-    sched_yield();
+    schedule();
 }
 
 pid_t
@@ -143,10 +139,13 @@ _wait(pid_t wpid, int* status, int options)
     if (llist_empty(&__current->children)) {
         return -1;
     }
+
+    wpid = wpid ? wpid : -__current->pgid;
+    cpu_enable_interrupt();
 repeat:
     llist_for_each(proc, n, &__current->children, siblings)
     {
-        if (!~wpid || proc->pid == wpid) {
+        if (!~wpid || proc->pid == wpid || proc->pgid == -wpid) {
             if (proc->state == PROC_TERMNAT && !options) {
                 status_flags |= PROCTERM;
                 goto done;
@@ -165,6 +164,7 @@ repeat:
     goto repeat;
 
 done:
+    cpu_disable_interrupt();
     *status = (proc->exit_code & 0xffff) | status_flags;
     return destroy_process(proc->pid);
 }
@@ -201,8 +201,10 @@ push_process(struct proc_info* process)
 
     process = &sched_ctx._procs[index];
 
-    // make sure the address is in the range of process table
+    // make sure the reference is relative to process table
     llist_init_head(&process->children);
+    llist_init_head(&process->grp_member);
+
     // every process is the child of first process (pid=1)
     if (process->parent) {
         llist_append(&process->parent->children, &process->siblings);