diff options
author | Ian Moffett <ian@osmora.org> | 2024-03-14 20:57:12 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-03-14 21:43:09 -0400 |
commit | d0f81e3d2afdf7a89fd466799f2d900da9f2ac40 (patch) | |
tree | 2c058bfff5091da15caffee8e8b666b5c5864c8e /sys/kern/kern_sched.c | |
parent | 3e3ff0acccfbb1d251a9b9bacbf0851c9de69561 (diff) |
kernel: sched: Add exit routine
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/kern/kern_sched.c')
-rw-r--r-- | sys/kern/kern_sched.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index f985f62..c3d1e09 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -280,6 +280,50 @@ sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv, return td; } +static void +sched_destroy_td(struct proc *td) +{ + processor_free_pcb(td); + + /* + * User stacks are allocated with vm_alloc_pageframe(), + * while kernel stacks are allocated with dynalloc(). + * We want to check if we are a user program or kernel + * program to perform the proper deallocation method. + */ + if (td->is_user) { + vm_free_pageframe(td->stack_base, STACK_PAGES); + } else { + dynfree((void *)td->stack_base); + } + + pmap_free_vas(vm_get_ctx(), td->addrsp); + dynfree(td); +} + +void +sched_exit(void) +{ + struct sched_state *state; + struct cpu_info *ci; + struct proc *td; + struct vas kvas = vm_get_kvas(); + + intr_mask(); + + /* Get the thread running on the current processor */ + ci = this_cpu(); + state = &ci->sched_state; + td = state->td; + + /* Switch back to the kernel address space and destroy ourself */ + pmap_switch_vas(vm_get_ctx(), kvas); + sched_destroy_td(td); + + intr_unmask(); + sched_enter(); +} + /* * Thread context switch routine */ |