You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.4 KiB
C
98 lines
2.4 KiB
C
/* See the end of this file for copyright and license terms. */
|
|
|
|
#include <arch/cpufunc.h>
|
|
#include <arch/sched.h>
|
|
|
|
#include <gay/clist.h>
|
|
#include <gay/sched.h>
|
|
#include <gay/types.h>
|
|
|
|
struct task kernel_task = {
|
|
.parent = nil,
|
|
.pid = 0,
|
|
.state = TASK_READY,
|
|
};
|
|
|
|
struct task *current_array[CFG_MAX_CPU] = {
|
|
&kernel_task,
|
|
};
|
|
|
|
/*
|
|
* Two run queues, one active and one inactive. The scheduler takes tasks out
|
|
* of the active queue, runs them if possible, and then puts them into the
|
|
* inactive queue if they aren't dead. When the active queue gets empty, the
|
|
* queues are switched and everything starts over again.
|
|
* The `current` task is always in neither queue.
|
|
*/
|
|
static struct clist _run_queues[2];
|
|
static struct clist *active_queue = &_run_queues[0];
|
|
static struct clist *inactive_queue = &_run_queues[1];
|
|
|
|
int sched_init(void)
|
|
{
|
|
clist_init(active_queue);
|
|
clist_init(inactive_queue);
|
|
return 0;
|
|
}
|
|
|
|
void schedule(void)
|
|
{
|
|
struct task *old = current;
|
|
struct task *new = nil;
|
|
|
|
clist_add(inactive_queue, &old->run_queue);
|
|
|
|
/* Dijkstra would be so mad if he saw this */
|
|
try_again:
|
|
if (clist_is_empty(active_queue)) {
|
|
struct clist *tmp = active_queue;
|
|
active_queue = inactive_queue;
|
|
inactive_queue = tmp;
|
|
}
|
|
|
|
struct task *cursor, *tmp;
|
|
clist_foreach_entry_safe(active_queue, cursor, tmp, run_queue) {
|
|
clist_del(&cursor->run_queue);
|
|
if (cursor->state == TASK_READY) {
|
|
new = cursor;
|
|
break;
|
|
} else if (cursor->state == TASK_BLOCKED) {
|
|
clist_add(inactive_queue, &cursor->run_queue);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This should really make the CPU go idle rather than constantly
|
|
* looping around until some event occurs, but i have no idea how to do
|
|
* that (yet)
|
|
*/
|
|
if (new == nil)
|
|
goto try_again;
|
|
|
|
if (new != old)
|
|
switch_to(new, old);
|
|
}
|
|
|
|
void switch_to(struct task *new, struct task *old)
|
|
{
|
|
disable_intr();
|
|
set_current(new);
|
|
arch_switch_to(&new->tcb, &old->tcb);
|
|
set_current(old);
|
|
enable_intr();
|
|
}
|
|
|
|
/*
|
|
* This file is part of GayBSD.
|
|
* Copyright (c) 2021 fef <owo@fef.moe>.
|
|
*
|
|
* GayBSD is nonviolent software: you may only use, redistribute, and/or
|
|
* modify it under the terms of the Cooperative Nonviolent Public License
|
|
* (CNPL) as found in the LICENSE file in the source code root directory
|
|
* or at <https://git.pixie.town/thufie/npl-builder>; either version 7
|
|
* of the license, or (at your option) any later version.
|
|
*
|
|
* GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
|
|
* permitted by applicable law. See the CNPL for details.
|
|
*/
|