X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/bdc143a7aa3f51a46eceec62b0b364599533fa21..0fd474df7001837bde53da0e42e83081827c9641:/lunaix-os/kernel/process/sched.c?ds=sidebyside diff --git a/lunaix-os/kernel/process/sched.c b/lunaix-os/kernel/process/sched.c index 82a2aa9..112741c 100644 --- a/lunaix-os/kernel/process/sched.c +++ b/lunaix-os/kernel/process/sched.c @@ -1,7 +1,7 @@ -#include -#include +#include +#include -#include +#include #include #include @@ -20,13 +20,11 @@ #include #include -#include - #include struct thread empty_thread_obj; -volatile struct proc_info* __current; +volatile struct proc_info* __current = NULL; volatile struct thread* current_thread = &empty_thread_obj; struct scheduler sched_ctx; @@ -62,6 +60,7 @@ run(struct thread* thread) set_current_executing(thread); switch_context(); + fail("unexpected return from switching"); } @@ -72,10 +71,9 @@ run(struct thread* thread) clean-up on these thread, in the preemptible kernel thread. */ -void _preemptible -cleanup_detached_threads() { - ensure_preempt_caller(); - +void +cleanup_detached_threads() +{ // XXX may be a lock on sched_context will ben the most appropriate? cpu_disable_interrupt(); @@ -102,13 +100,22 @@ cleanup_detached_threads() { cpu_enable_interrupt(); } -int +bool 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; @@ -119,6 +126,7 @@ can_schedule(struct thread* thread) if ((thread->state & PS_PAUSED)) { return !!(sh->sig_pending & ~1); } + if ((thread->state & PS_BLOCKED)) { return sigset_test(sh->sig_pending, _SIGINT); } @@ -128,8 +136,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; - return 0; + return false; } + if (sigset_test(sh->sig_pending, _SIGCONT)) { thread->state = PS_READY; } @@ -176,7 +185,7 @@ schedule() 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; @@ -210,19 +219,11 @@ schedule() sched_ctx.procs_index = to_check->process->pid; done: - isrm_notify_eos(0); run(to_check); fail("unexpected return from scheduler"); } -void -sched_pass() -{ - cpu_enable_interrupt(); - cpu_trap_sched(); -} - __DEFINE_LXSYSCALL1(unsigned int, sleep, unsigned int, seconds) { if (!seconds) { @@ -305,6 +306,7 @@ _wait(pid_t wpid, int* status, int options) } wpid = wpid ? wpid : -__current->pgid; + repeat: llist_for_each(proc, n, &__current->children, siblings) { @@ -323,12 +325,12 @@ repeat: return 0; } // 放弃当前的运行机会 - sched_pass(); + yield_current(); goto repeat; done: if (status) { - *status = proc->exit_code | status_flags; + *status = PEXITNUM(status_flags, proc->exit_code); } return destroy_process(proc->pid); } @@ -341,7 +343,7 @@ get_free_pid() { ; if (unlikely(i == MAX_PROCESS)) { - panick("Panic in Ponyville shimmer!"); + fail("Panic in Ponyville shimmer!"); } return i; @@ -391,6 +393,8 @@ alloc_process() proc->created = clock_systime(); proc->pgid = proc->pid; + proc->root = vfs_sysroot; + proc->sigreg = vzalloc(sizeof(struct sigregistry)); proc->fdtable = vzalloc(sizeof(struct v_fdtable)); @@ -544,7 +548,7 @@ delete_process(struct proc_info* proc) pid_t destroy_process(pid_t pid) -{ +{ int index = pid; if (index <= 0 || index > sched_ctx.ptable_len) { syscall_result(EINVAL); @@ -559,6 +563,8 @@ destroy_process(pid_t pid) static void terminate_proc_only(struct proc_info* proc, int exit_code) { + assert(proc->pid != 0); + proc->state = PS_TERMNAT; proc->exit_code = exit_code; @@ -586,13 +592,13 @@ terminate_proccess(struct proc_info* proc, int exit_code) { assert(!kernel_process(proc)); if (proc->pid == 1) { - panick("Attempt to kill init"); + fail("Attempt to kill init"); } terminate_proc_only(proc, exit_code); struct thread *pos, *n; - llist_for_each(pos, n, &__current->threads, proc_sibs) { + llist_for_each(pos, n, &proc->threads, proc_sibs) { pos->state = PS_TERMNAT; } }