diff options
author | Ian Moffett <ian@osmora.org> | 2024-06-30 23:37:33 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-06-30 23:39:37 -0400 |
commit | 974d7ce527c9220fcdad44b27b4a2b44054502c2 (patch) | |
tree | ea1b0334915c38bdeec7109fb2c73825925e0729 /sys/kern | |
parent | b947d0c149dd3a36d92343a41a80a6b3f29f5f00 (diff) |
kernel: sched: Add exit1()
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_exit.c | 78 | ||||
-rw-r--r-- | sys/kern/kern_sched.c | 26 |
2 files changed, 99 insertions, 5 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c new file mode 100644 index 0000000..9995f51 --- /dev/null +++ b/sys/kern/kern_exit.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/proc.h> +#include <sys/sched.h> +#include <vm/physmem.h> +#include <vm/dynalloc.h> +#include <vm/vm.h> + +/* + * Kill a thread and deallocate its resources. + * + * @td: Thread to exit + */ +int +exit1(struct proc *td) +{ + struct pcb *pcbp; + struct proc *curtd; + uintptr_t stack; + pid_t target_pid, curpid; + + target_pid = td->pid; + curtd = this_td(); + pcbp = &td->pcb; + + curpid = curtd->pid; + stack = td->stack_base; + td->flags |= PROC_EXITING; + + /* + * If this is on the higher half, it is kernel + * mapped and we need to convert it to a physical + * address. + */ + if (stack >= VM_HIGHER_HALF) { + stack -= VM_HIGHER_HALF; + } + + vm_free_frame(stack, PROC_STACK_PAGES); + pmap_destroy_vas(pcbp->addrsp); + dynfree(td); + + /* + * If we are the thread exiting, reenter the scheduler + * and do not return. + */ + if (target_pid == curpid) + sched_enter(); + + return 0; +} diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index f1bd067..9df541e 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -31,6 +31,7 @@ #include <sys/sched.h> #include <sys/schedvar.h> #include <sys/cdefs.h> +#include <sys/param.h> #include <sys/syslog.h> #include <machine/frame.h> #include <machine/cpu.h> @@ -130,15 +131,30 @@ sched_switch(struct trapframe *tf) struct cpu_info *ci; struct pcb *pcbp; struct proc *next_td, *td; + bool use_current = true; + bool inexec; ci = this_cpu(); td = ci->curtd; - /* Do we have threads to switch to? */ - if ((next_td = sched_dequeue_td()) == NULL) { - sched_oneshot(false); - return; - } + /* + * Get the next thread and use it only if it isn't + * in the middle of an exit, exec, or whatever. + */ + do { + if ((next_td = sched_dequeue_td()) == NULL) { + sched_oneshot(false); + return; + } + + /* + * Don't use this thread if we are currently + * exiting. + */ + if (ISSET(next_td->flags, PROC_EXITING)) { + use_current = false; + } + } while (!use_current); /* Re-enqueue the old thread */ if (td != NULL) { |