-#include <sys/abi.h>
-#include <sys/mm/mempart.h>
+#include <asm/abi.h>
+#include <asm/mempart.h>
-#include <hal/intc.h>
-#include <sys/cpu.h>
+#include <asm/cpu.h>
#include <lunaix/fs/taskfs.h>
#include <lunaix/mm/cake.h>
#include <lunaix/status.h>
#include <lunaix/syscall.h>
#include <lunaix/syslog.h>
-#include <lunaix/pcontext.h>
+#include <lunaix/hart_state.h>
#include <lunaix/kpreempt.h>
#include <klibc/string.h>
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;
struct cake_pile *proc_pile ,*thread_pile;
+#define root_process (sched_ctx.procs[1])
+
LOG_MODULE("SCHED")
void
set_current_executing(thread);
switch_context();
+
fail("unexpected return from switching");
}
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();
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;
if ((thread->state & PS_PAUSED)) {
return !!(sh->sig_pending & ~1);
}
+
if ((thread->state & PS_BLOCKED)) {
return sigset_test(sh->sig_pending, _SIGINT);
}
// 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;
}
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;
sched_ctx.procs_index = to_check->process->pid;
done:
- intc_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) {
- return 0;
- }
-
- time_t systime = clock_systime() / 1000;
- struct haybed* bed = ¤t_thread->sleep;
-
- if (bed->wakeup_time) {
- return (bed->wakeup_time - systime);
- }
-
- bed->wakeup_time = systime + seconds;
-
- if (llist_empty(&bed->sleepers)) {
- llist_append(&sched_ctx.sleepers, &bed->sleepers);
- }
-
- store_retval(seconds);
-
- block_current_thread();
- schedule();
-
- return 0;
-}
-
__DEFINE_LXSYSCALL1(unsigned int, alarm, unsigned int, seconds)
{
struct haybed* bed = ¤t_thread->sleep;
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);
}
}
wpid = wpid ? wpid : -__current->pgid;
+
repeat:
llist_for_each(proc, n, &__current->children, siblings)
{
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);
}
;
if (unlikely(i == MAX_PROCESS)) {
- panick("Panic in Ponyville shimmer!");
+ fail("Panic in Ponyville shimmer!");
}
return i;
proc->created = clock_systime();
proc->pgid = proc->pid;
- proc->sigreg = vzalloc(sizeof(struct sigregister));
- proc->fdtable = vzalloc(sizeof(struct v_fdtable));
+ proc->root = vfs_sysroot;
+
+ proc->sigreg = vzalloc(sizeof(struct sigregistry));
+ proc->fdtable = fdtable_create();
proc->mm = procvm_create(proc);
// 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;
}
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)
{
vfree(proc->fdtable);
- signal_free_registers(proc->sigreg);
+ signal_free_registry(proc->sigreg);
procvm_mount(mm);
destory_thread(pos);
}
+ orphan_children(proc);
+
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);
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;
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;
}
}
// 如果其父进程的状态是terminated 或 destroy中的一种
// 或者其父进程是在该进程之后创建的,那么该进程为孤儿进程
return proc_terminated(parent) || parent->created > proc->created;
-}
\ No newline at end of file
+}
+