X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/a5338b60e111972364a8bc6f07011c6defd213d2..6d75e31596b5ac2e638c8a31c6c2185ee4053b6b:/lunaix-os/kernel/sched.c diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/sched.c index be99525..9061e80 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/sched.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -16,7 +17,8 @@ #include #include -#define MAX_PROCESS 512 +#define PROC_TABLE_SIZE 8192 +#define MAX_PROCESS (PROC_TABLE_SIZE / sizeof(uintptr_t)) volatile struct proc_info* __current; @@ -24,20 +26,25 @@ struct proc_info dummy; struct scheduler sched_ctx; +struct cake_pile* proc_pile; + LOG_MODULE("SCHED") void sched_init() { - size_t pg_size = ROUNDUP(sizeof(struct proc_info) * MAX_PROCESS, 0x1000); + // size_t pg_size = ROUNDUP(sizeof(struct proc_info) * MAX_PROCESS, 0x1000); - for (size_t i = 0; i <= pg_size; i += 4096) { - uintptr_t pa = pmm_alloc_page(KERNEL_PID, PP_FGPERSIST); - vmm_set_mapping( - PD_REFERENCED, PROC_START + i, pa, PG_PREM_RW, VMAP_NULL); - } + // for (size_t i = 0; i <= pg_size; i += 4096) { + // uintptr_t pa = pmm_alloc_page(KERNEL_PID, PP_FGPERSIST); + // vmm_set_mapping( + // PD_REFERENCED, PROC_START + i, pa, PG_PREM_RW, VMAP_NULL); + // } - sched_ctx = (struct scheduler){ ._procs = (struct proc_info*)PROC_START, + proc_pile = cake_new_pile("proc", sizeof(struct proc_info), 1, 0); + cake_set_constructor(proc_pile, cake_ctor_zeroing); + + sched_ctx = (struct scheduler){ ._procs = vzalloc(PROC_TABLE_SIZE), .ptable_len = 0, .procs_index = 0 }; } @@ -80,7 +87,7 @@ can_schedule(struct proc_info* proc) void check_sleepers() { - struct proc_info* leader = &sched_ctx._procs[0]; + struct proc_info* leader = sched_ctx._procs[0]; struct proc_info *pos, *n; time_t now = clock_systime(); llist_for_each(pos, n, &leader->sleep.sleepers, sleep.sleepers) @@ -94,7 +101,7 @@ check_sleepers() if (wtime && now >= wtime) { pos->sleep.wakeup_time = 0; - pos->state = PS_STOPPED; + pos->state = PS_READY; } if (atime && now >= atime) { @@ -123,7 +130,7 @@ schedule() int ptr = prev_ptr; if (!(__current->state & ~PS_RUNNING)) { - __current->state = PS_STOPPED; + __current->state = PS_READY; } check_sleepers(); @@ -132,8 +139,8 @@ schedule() redo: do { ptr = (ptr + 1) % sched_ctx.ptable_len; - next = &sched_ctx._procs[ptr]; - } while (next->state != PS_STOPPED && ptr != prev_ptr); + next = sched_ctx._procs[ptr]; + } while (!next || (next->state != PS_READY && ptr != prev_ptr)); sched_ctx.procs_index = ptr; @@ -145,6 +152,13 @@ redo: run(next); } +void +sched_yieldk() +{ + cpu_enable_interrupt(); + cpu_int(LUNAIX_SCHED); +} + __DEFINE_LXSYSCALL1(unsigned int, sleep, unsigned int, seconds) { if (!seconds) { @@ -155,9 +169,9 @@ __DEFINE_LXSYSCALL1(unsigned int, sleep, unsigned int, seconds) return (__current->sleep.wakeup_time - clock_systime()) / 1000U; } + struct proc_info* root_proc = sched_ctx._procs[0]; __current->sleep.wakeup_time = clock_systime() + seconds * 1000; - llist_append(&sched_ctx._procs[0].sleep.sleepers, - &__current->sleep.sleepers); + llist_append(&root_proc->sleep.sleepers, &__current->sleep.sleepers); __current->intr_ctx.registers.eax = seconds; __current->state = PS_BLOCKED; @@ -171,9 +185,9 @@ __DEFINE_LXSYSCALL1(unsigned int, alarm, unsigned int, seconds) __current->sleep.alarm_time = seconds ? now + seconds * 1000 : 0; + struct proc_info* root_proc = sched_ctx._procs[0]; if (llist_empty(&__current->sleep.sleepers)) { - llist_append(&sched_ctx._procs[0].sleep.sleepers, - &__current->sleep.sleepers); + llist_append(&root_proc->sleep.sleepers, &__current->sleep.sleepers); } return prev_ddl ? (prev_ddl - now) / 1000 : 0; @@ -219,7 +233,6 @@ _wait(pid_t wpid, int* status, int options) } wpid = wpid ? wpid : -__current->pgid; - cpu_enable_interrupt(); repeat: llist_for_each(proc, n, &__current->children, siblings) { @@ -228,7 +241,7 @@ repeat: status_flags |= PEXITTERM; goto done; } - if (proc->state == PS_STOPPED && (options & WUNTRACED)) { + if (proc->state == PS_READY && (options & WUNTRACED)) { status_flags |= PEXITSTOP; goto done; } @@ -238,11 +251,10 @@ repeat: return 0; } // 放弃当前的运行机会 - sched_yield(); + sched_yieldk(); goto repeat; done: - cpu_disable_interrupt(); status_flags |= PEXITSIG * (proc->sig_inprogress != 0); if (status) { *status = proc->exit_code | status_flags; @@ -254,8 +266,7 @@ struct proc_info* alloc_process() { pid_t i = 0; - for (; i < sched_ctx.ptable_len && sched_ctx._procs[i].state != PS_DESTROY; - i++) + for (; i < sched_ctx.ptable_len && sched_ctx._procs[i]; i++) ; if (i == MAX_PROCESS) { @@ -266,8 +277,7 @@ alloc_process() sched_ctx.ptable_len++; } - struct proc_info* proc = &sched_ctx._procs[i]; - memset(proc, 0, sizeof(*proc)); + struct proc_info* proc = cake_grab(proc_pile); proc->state = PS_CREATED; proc->pid = i; @@ -275,10 +285,13 @@ alloc_process() proc->pgid = proc->pid; proc->fdtable = vzalloc(sizeof(struct v_fdtable)); - llist_init_head(&proc->mm.regions); + llist_init_head(&proc->mm.regions.head); llist_init_head(&proc->children); llist_init_head(&proc->grp_member); llist_init_head(&proc->sleep.sleepers); + waitq_init(&proc->waitqueue); + + sched_ctx._procs[i] = proc; return proc; } @@ -286,7 +299,7 @@ alloc_process() void commit_process(struct proc_info* process) { - assert(process == &sched_ctx._procs[process->pid]); + assert(process == sched_ctx._procs[process->pid]); if (process->state != PS_CREATED) { __current->k_status = EINVAL; @@ -295,12 +308,12 @@ commit_process(struct proc_info* process) // every process is the child of first process (pid=1) if (!process->parent) { - process->parent = &sched_ctx._procs[1]; + process->parent = sched_ctx._procs[1]; } llist_append(&process->parent->children, &process->siblings); - process->state = PS_STOPPED; + process->state = PS_READY; } // from @@ -315,8 +328,9 @@ destroy_process(pid_t pid) __current->k_status = EINVAL; return; } - struct proc_info* proc = &sched_ctx._procs[index]; - proc->state = PS_DESTROY; + struct proc_info* proc = sched_ctx._procs[index]; + sched_ctx._procs[index] = 0; + llist_delete(&proc->siblings); for (size_t i = 0; i < VFS_MAX_FD; i++) { @@ -330,7 +344,7 @@ destroy_process(pid_t pid) struct mm_region *pos, *n; llist_for_each(pos, n, &proc->mm.regions.head, head) { - lxfree(pos); + vfree(pos); } vmm_mount_pd(PD_MOUNT_1, proc->page_table); @@ -339,6 +353,8 @@ destroy_process(pid_t pid) vmm_unmount_pd(PD_MOUNT_1); + cake_release(proc_pile, proc); + return pid; } @@ -358,7 +374,7 @@ get_process(pid_t pid) if (index < 0 || index > sched_ctx.ptable_len) { return NULL; } - return &sched_ctx._procs[index]; + return sched_ctx._procs[index]; } int @@ -368,7 +384,7 @@ orphaned_proc(pid_t pid) return 0; if (pid >= sched_ctx.ptable_len) return 0; - struct proc_info* proc = &sched_ctx._procs[pid]; + struct proc_info* proc = sched_ctx._procs[pid]; struct proc_info* parent = proc->parent; // 如果其父进程的状态是terminated 或 destroy中的一种