1 #include <lunaix/process.h>
2 #include <lunaix/sched.h>
3 #include <lunaix/mm/vmm.h>
5 #include <arch/x86/interrupts.h>
8 #include <lunaix/spike.h>
9 #include <lunaix/status.h>
10 #include <lunaix/syslog.h>
12 #define MAX_PROCESS 512
14 struct proc_info* __current;
15 struct proc_info dummy;
17 extern void __proc_table;
19 struct scheduler sched_ctx;
24 size_t pg_size = ROUNDUP(sizeof(struct proc_info) * MAX_PROCESS, 0x1000);
26 vmm_alloc_pages(KERNEL_PID, &__proc_table, pg_size, PG_PREM_RW, PP_FGPERSIST),
27 "Fail to allocate proc table"
30 sched_ctx = (struct scheduler) {
31 ._procs = (struct proc_info*) &__proc_table,
40 if (!sched_ctx.ptable_len) {
44 struct proc_info* next;
45 int prev_ptr = sched_ctx.procs_index;
47 // round-robin scheduler
49 ptr = (ptr + 1) % sched_ctx.ptable_len;
50 next = &sched_ctx._procs[ptr];
51 } while((next->state != PROC_STOPPED && next->state != PROC_CREATED) && ptr != prev_ptr);
53 sched_ctx.procs_index = ptr;
55 __current->state = PROC_STOPPED;
56 next->state = PROC_RUNNING;
60 cpu_lcr3(__current->page_table);
62 apic_done_servicing();
64 asm volatile ("pushl %0\n jmp soft_iret\n"::"r"(&__current->intr_ctx): "memory");
69 for (; i < sched_ctx.ptable_len && sched_ctx._procs[i].state != PROC_DESTROY; i++);
71 if (i == MAX_PROCESS) {
72 __current->k_status = LXPROCFULL;
78 void push_process(struct proc_info* process) {
79 int index = process->pid - 1;
80 if (index < 0 || index > sched_ctx.ptable_len) {
81 __current->k_status = LXINVLDPID;
85 if (index == sched_ctx.ptable_len) {
86 sched_ctx.ptable_len++;
89 process->parent = __current->pid;
90 process->state = PROC_CREATED;
92 sched_ctx._procs[index] = *process;
95 void destroy_process(pid_t pid) {
97 if (index < 0 || index > sched_ctx.ptable_len) {
98 __current->k_status = LXINVLDPID;
102 sched_ctx._procs[index].state = PROC_DESTROY;
104 // TODO: recycle the physical pages used by page tables
107 void terminate_process(int exit_code) {
108 __current->state = PROC_TERMNAT;
109 __current->exit_code = exit_code;
114 struct proc_info* get_process(pid_t pid) {
116 if (index < 0 || index > sched_ctx.ptable_len) {
119 return &sched_ctx._procs[index];