diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2025-12-11 16:34:51 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2025-12-11 16:34:51 +0800 |
| commit | 27fc7bda593c8bd2c24a334a368772b5f15d4e9e (patch) | |
| tree | cee97c7b0ba2701be3981b587902e03ba8b85e12 /src/kernel/proc/proc.cc | |
| parent | 497e4a1b2f6f9181518e9887991c0464bd8f6bcf (diff) | |
| download | lume-27fc7bda593c8bd2c24a334a368772b5f15d4e9e.tar.gz lume-27fc7bda593c8bd2c24a334a368772b5f15d4e9e.tar.xz | |
feat:Cooperative Multitasking
Diffstat (limited to 'src/kernel/proc/proc.cc')
| -rw-r--r-- | src/kernel/proc/proc.cc | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/src/kernel/proc/proc.cc b/src/kernel/proc/proc.cc new file mode 100644 index 0000000..469b7eb --- /dev/null +++ b/src/kernel/proc/proc.cc @@ -0,0 +1,113 @@ +#include "kernel/proc.h" +#include "kernel/pmm.h" +#include "drivers/uart.h" + +#define NPROC 10 + +void str_copy(char *dst, const char *src) +{ + while (*src) + *dst++ = *src++; + *dst = 0; +} + +extern "C" void swtch(struct Context *old_ctx, struct Context *new_ctx); + +struct Proc procs[NPROC]; +struct Context main_context; + +namespace ProcManager +{ + void init() + { + for (int i = 0; i < NPROC; i++) + { + procs[i].state = UNUSED; + } + } + + void create_kernel_thread(void (*func)(), const char *name) + { + struct Proc *p = nullptr; + for(int i = 0; i < NPROC; i++) + { + if(procs[i].state == UNUSED) + { + p = &procs[i]; + p->pid = i + 1; + break; + } + } + + if (!p) + { + Drivers::uart_puts("Error: No free process slots!\n"); + return; + } + + p->kstack = PMM::alloc_page(); + if (!p->kstack) + { + Drivers::uart_puts("Error: Alloc kstack failed!\n"); + return; + } + + p->context.ra = (uint64)func; + + p->context.sp = (uint64)p->kstack + 4096; + + p->state = RUNNABLE; + str_copy(p->name, name); + + Drivers::uart_puts("[Proc] Created thread: "); + Drivers::uart_puts(name); + Drivers::uart_puts("\n"); + } + + void yield() + { + struct Proc *p = nullptr; + for(int i = 0; i < NPROC; i++) + { + if (procs[i].state == RUNNING) + { + p = &procs[i]; + break; + } + } + if(p) + { + p->state = RUNNABLE; + swtch(&p->context, &main_context); + } + } + + void scheduler() + { + struct Proc *p = nullptr; + Drivers::uart_puts("[Proc] Scheduler started.\n"); + + for (;;) + { + // int nothing_to_run = 1; + + intr_off(); + + for (p = procs; p < &procs[NPROC]; p++) + { + if (p->state == RUNNABLE) + { + // nothing_to_run = 0; + + p->state = RUNNING; + + intr_on(); + + swtch(&main_context, &p->context); + + intr_off(); + } + } + } + } +}
\ No newline at end of file |
