X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/20097445f742afff2c263431efcb1c8b596076a8..94a87fe25c5ec021daf16edd64058ed6a37aba7d:/lunaix-os/kernel/sched.c diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/sched.c index 8f65087..7f124c4 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/sched.c @@ -1,12 +1,14 @@ #include #include + #include #include + #include #include #include #include - +#include #include #include #include @@ -58,6 +60,8 @@ run(struct proc_info* proc) apic_done_servicing(); + signal_dispatch(); + asm volatile("pushl %0\n" "jmp soft_iret\n" ::"r"(&__current->intr_ctx) : "memory"); @@ -70,6 +74,8 @@ schedule() return; } + // 上下文切换相当的敏感!我们不希望任何的中断打乱栈的顺序…… + cpu_disable_interrupt(); struct proc_info* next; int prev_ptr = sched_ctx.procs_index; int ptr = prev_ptr; @@ -97,6 +103,7 @@ __DEFINE_LXSYSCALL1(unsigned int, sleep, unsigned int, seconds) if (!seconds) { return 0; } + if (__current->timer) { return __current->timer->counter / timer_context()->running_frequency; } @@ -119,26 +126,54 @@ __DEFINE_LXSYSCALL(void, yield) schedule(); } +pid_t +_wait(pid_t wpid, int* status, int options); + __DEFINE_LXSYSCALL1(pid_t, wait, int*, status) +{ + return _wait(-1, status, 0); +} + +__DEFINE_LXSYSCALL3(pid_t, waitpid, pid_t, pid, int*, status, int, options) +{ + return _wait(pid, status, options); +} + +pid_t +_wait(pid_t wpid, int* status, int options) { pid_t cur = __current->pid; + int status_flags = 0; struct proc_info *proc, *n; if (llist_empty(&__current->children)) { return -1; } + + cpu_enable_interrupt(); repeat: llist_for_each(proc, n, &__current->children, siblings) { - if (proc->state == PROC_TERMNAT) { - goto done; + if (!~wpid || proc->pid == wpid) { + if (proc->state == PROC_TERMNAT && !options) { + status_flags |= PROCTERM; + goto done; + } + if (proc->state == PROC_STOPPED && (options & WUNTRACED)) { + status_flags |= PROCSTOP; + goto done; + } } } - // FIXME: 除了循环,也许有更高效的办法…… - // (在这里进行schedule,需要重写context switch!) + if ((options & WNOHANG)) { + return 0; + } + // 放弃当前的运行机会 + sched_yield(); goto repeat; done: - *status = proc->exit_code; + cpu_disable_interrupt(); + *status = (proc->exit_code & 0xffff) | status_flags; return destroy_process(proc->pid); }