Second Extended Filesystem (ext2) and other improvements (#33)
[lunaix-os.git] / lunaix-os / kernel / process / sched.c
index 82a2aa9abc15b9c4a13a15e950218c1f4f2b9412..574d593a0db86c0960b5bfd50a830a80206c2c2c 100644 (file)
@@ -62,6 +62,7 @@ run(struct thread* thread)
     set_current_executing(thread);
 
     switch_context();
     set_current_executing(thread);
 
     switch_context();
+
     fail("unexpected return from switching");
 }
 
     fail("unexpected return from switching");
 }
 
@@ -102,13 +103,22 @@ cleanup_detached_threads() {
     cpu_enable_interrupt();
 }
 
     cpu_enable_interrupt();
 }
 
-int
+bool
 can_schedule(struct thread* thread)
 {
     if (!thread) {
         return 0;
     }
 
 can_schedule(struct thread* thread)
 {
     if (!thread) {
         return 0;
     }
 
+    if (proc_terminated(thread)) {
+        return false;
+    }
+
+    if (preempt_check_stalled(thread)) {
+        thread_flags_set(thread, TH_STALLED);
+        return true;
+    }
+
     if (unlikely(kernel_process(thread->process))) {
         // a kernel process is always runnable
         return thread->state == PS_READY;
     if (unlikely(kernel_process(thread->process))) {
         // a kernel process is always runnable
         return thread->state == PS_READY;
@@ -119,6 +129,7 @@ can_schedule(struct thread* thread)
     if ((thread->state & PS_PAUSED)) {
         return !!(sh->sig_pending & ~1);
     }
     if ((thread->state & PS_PAUSED)) {
         return !!(sh->sig_pending & ~1);
     }
+
     if ((thread->state & PS_BLOCKED)) {
         return sigset_test(sh->sig_pending, _SIGINT);
     }
     if ((thread->state & PS_BLOCKED)) {
         return sigset_test(sh->sig_pending, _SIGINT);
     }
@@ -128,8 +139,9 @@ can_schedule(struct thread* thread)
         // all other threads are also SIGSTOP (as per POSIX-2008.1)
         // In which case, the entire process is stopped.
         thread->state = PS_STOPPED;
         // all other threads are also SIGSTOP (as per POSIX-2008.1)
         // In which case, the entire process is stopped.
         thread->state = PS_STOPPED;
-        return 0;
+        return false;
     }
     }
+    
     if (sigset_test(sh->sig_pending, _SIGCONT)) {
         thread->state = PS_READY;
     }
     if (sigset_test(sh->sig_pending, _SIGCONT)) {
         thread->state = PS_READY;
     }
@@ -176,7 +188,7 @@ schedule()
     assert(sched_ctx.ptable_len && sched_ctx.ttable_len);
 
     // 上下文切换相当的敏感!我们不希望任何的中断打乱栈的顺序……
     assert(sched_ctx.ptable_len && sched_ctx.ttable_len);
 
     // 上下文切换相当的敏感!我们不希望任何的中断打乱栈的顺序……
-    cpu_disable_interrupt();
+    no_preemption();
 
     if (!(current_thread->state & ~PS_RUNNING)) {
         current_thread->state = PS_READY;
 
     if (!(current_thread->state & ~PS_RUNNING)) {
         current_thread->state = PS_READY;
@@ -216,13 +228,6 @@ done:
     fail("unexpected return from scheduler");
 }
 
     fail("unexpected return from scheduler");
 }
 
-void
-sched_pass()
-{
-    cpu_enable_interrupt();
-    cpu_trap_sched();
-}
-
 __DEFINE_LXSYSCALL1(unsigned int, sleep, unsigned int, seconds)
 {
     if (!seconds) {
 __DEFINE_LXSYSCALL1(unsigned int, sleep, unsigned int, seconds)
 {
     if (!seconds) {
@@ -305,6 +310,7 @@ _wait(pid_t wpid, int* status, int options)
     }
 
     wpid = wpid ? wpid : -__current->pgid;
     }
 
     wpid = wpid ? wpid : -__current->pgid;
+
 repeat:
     llist_for_each(proc, n, &__current->children, siblings)
     {
 repeat:
     llist_for_each(proc, n, &__current->children, siblings)
     {
@@ -323,12 +329,12 @@ repeat:
         return 0;
     }
     // 放弃当前的运行机会
         return 0;
     }
     // 放弃当前的运行机会
-    sched_pass();
+    yield_current();
     goto repeat;
 
 done:
     if (status) {
     goto repeat;
 
 done:
     if (status) {
-        *status = proc->exit_code | status_flags;
+        *status = PEXITNUM(status_flags, proc->exit_code);
     }
     return destroy_process(proc->pid);
 }
     }
     return destroy_process(proc->pid);
 }