X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/b60166b327a9108b07e3069fa6568a451529ffd9..e47950ba3c4ef27ff19d8bb7ad54d779180e96e9:/lunaix-os/kernel/process/sched.c diff --git a/lunaix-os/kernel/process/sched.c b/lunaix-os/kernel/process/sched.c index c92cde9..945fc01 100644 --- a/lunaix-os/kernel/process/sched.c +++ b/lunaix-os/kernel/process/sched.c @@ -1,7 +1,6 @@ #include #include -#include #include #include @@ -18,18 +17,24 @@ #include #include #include -#include +#include #include +#include + #include +struct thread empty_thread_obj; + volatile struct proc_info* __current; -volatile struct thread* current_thread; +volatile struct thread* current_thread = &empty_thread_obj; struct scheduler sched_ctx; struct cake_pile *proc_pile ,*thread_pile; +#define root_process (sched_ctx.procs[1]) + LOG_MODULE("SCHED") void @@ -53,9 +58,11 @@ run(struct thread* thread) thread->process->state = PS_RUNNING; thread->process->th_active = thread; + procvm_mount_self(vmspace(thread->process)); set_current_executing(thread); switch_context(); + fail("unexpected return from switching"); } @@ -66,10 +73,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(); @@ -80,9 +86,11 @@ cleanup_detached_threads() { continue; } - vmm_mount_pd(VMS_MOUNT_1, vmroot(pos->process)); - destory_thread(VMS_MOUNT_1, pos); - vmm_unmount_pd(VMS_MOUNT_1); + struct proc_mm* mm = vmspace(pos->process); + + procvm_mount(mm); + destory_thread(pos); + procvm_unmount(mm); i++; } @@ -94,13 +102,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; @@ -111,6 +128,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); } @@ -120,8 +138,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; } @@ -168,13 +187,15 @@ 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; __current->state = PS_READY; + } + procvm_unmount_self(vmspace(__current)); check_sleepers(); // round-robin scheduler @@ -200,19 +221,12 @@ schedule() sched_ctx.procs_index = to_check->process->pid; done: - intc_notify_eos(0); + 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) { @@ -248,7 +262,6 @@ __DEFINE_LXSYSCALL1(unsigned int, alarm, unsigned int, seconds) bed->alarm_time = seconds ? now + seconds : 0; - struct proc_info* root_proc = sched_ctx.procs[0]; if (llist_empty(&bed->sleepers)) { llist_append(&sched_ctx.sleepers, &bed->sleepers); } @@ -296,6 +309,7 @@ _wait(pid_t wpid, int* status, int options) } wpid = wpid ? wpid : -__current->pgid; + repeat: llist_for_each(proc, n, &__current->children, siblings) { @@ -314,12 +328,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); } @@ -382,7 +396,7 @@ alloc_process() proc->created = clock_systime(); proc->pgid = proc->pid; - proc->sigreg = vzalloc(sizeof(struct sigregister)); + proc->sigreg = vzalloc(sizeof(struct sigregistry)); proc->fdtable = vzalloc(sizeof(struct v_fdtable)); proc->mm = procvm_create(proc); @@ -427,7 +441,7 @@ commit_process(struct proc_info* process) // every process is the child of first process (pid=1) if (!process->parent) { if (likely(!kernel_process(process))) { - process->parent = sched_ctx.procs[1]; + process->parent = root_process; } else { process->parent = process; } @@ -447,7 +461,7 @@ commit_process(struct proc_info* process) } void -destory_thread(ptr_t vm_mnt, struct thread* thread) +destory_thread(struct thread* thread) { cake_ensure_valid(thread); @@ -458,7 +472,7 @@ destory_thread(ptr_t vm_mnt, struct thread* thread) llist_delete(&thread->sleep.sleepers); waitq_cancel_wait(&thread->waitqueue); - thread_release_mem(thread, vm_mnt); + thread_release_mem(thread); proc->thread_count--; sched_ctx.ttable_len--; @@ -466,10 +480,25 @@ destory_thread(ptr_t vm_mnt, struct thread* thread) cake_release(thread_pile, thread); } +static void +orphan_children(struct proc_info* proc) +{ + struct proc_info *root; + struct proc_info *pos, *n; + + root = root_process; + + llist_for_each(pos, n, &proc->children, siblings) { + pos->parent = root; + llist_append(&root->children, &pos->siblings); + } +} + void delete_process(struct proc_info* proc) { pid_t pid = proc->pid; + struct proc_mm* mm = vmspace(proc); assert(pid); // long live the pid0 !! @@ -501,26 +530,26 @@ delete_process(struct proc_info* proc) vfree(proc->fdtable); - signal_free_registers(proc->sigreg); + signal_free_registry(proc->sigreg); - vmm_mount_pd(VMS_MOUNT_1, vmroot(proc)); + procvm_mount(mm); struct thread *pos, *n; llist_for_each(pos, n, &proc->threads, proc_sibs) { // terminate and destory all thread unconditionally - destory_thread(VMS_MOUNT_1, pos); + destory_thread(pos); } - procvm_cleanup(VMS_MOUNT_1, proc); + orphan_children(proc); - vmm_unmount_pd(VMS_MOUNT_1); + procvm_unmount_release(mm); cake_release(proc_pile, proc); } pid_t destroy_process(pid_t pid) -{ +{ int index = pid; if (index <= 0 || index > sched_ctx.ptable_len) { syscall_result(EINVAL); @@ -535,6 +564,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; @@ -568,7 +599,7 @@ terminate_proccess(struct proc_info* proc, int exit_code) { 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; } }