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.
91 lines
2.6 KiB
C
91 lines
2.6 KiB
C
/* Copyright (C) 2021,2022 fef <owo@fef.moe>. All rights reserved. */
|
|
|
|
#pragma once
|
|
|
|
#include <arch/sched.h>
|
|
#include <arch/smp.h>
|
|
|
|
#include <gay/cdefs.h>
|
|
#include <gay/clist.h>
|
|
#include <gay/types.h>
|
|
|
|
enum task_state {
|
|
TASK_READY,
|
|
TASK_BLOCKED,
|
|
TASK_DEAD,
|
|
};
|
|
|
|
struct task {
|
|
/**
|
|
* @brief List node for enqueuing this task in the scheduler's pipeline.
|
|
* When the task is currently running, this is invalid because the task
|
|
* is not in any queue.
|
|
*/
|
|
struct clist run_queue;
|
|
tcb_t tcb;
|
|
struct task *parent;
|
|
pid_t pid;
|
|
/**
|
|
* @brief 0 = interruptable, > 0 = uninterruptible, < 0 = we messed up.
|
|
* Increment/decrement using `critical_enter()`/`critical_leave()`.
|
|
*/
|
|
volatile int critnest;
|
|
enum task_state state;
|
|
};
|
|
|
|
/**
|
|
* @brief The task that is currently running on this particular cpu core.
|
|
* May not be accessed from irq context.
|
|
*
|
|
* This will become a macro which calls some function once we have SMP support,
|
|
* so if you need to access it multiple times from the same place you should
|
|
* copy it into a local variable first to avoid extra overhead.
|
|
*
|
|
* For the same reason, don't assign values to this directly, and use
|
|
* `set_current()` instead.
|
|
*/
|
|
extern struct task *current_array[CFG_MAX_CPU];
|
|
#define current (current_array[smp_cpuid()])
|
|
|
|
/**
|
|
* @brief Update the `current` task.
|
|
* You will almost never need this because `switch_to()` does it automatically.
|
|
*/
|
|
static inline void set_current(struct task *task)
|
|
{
|
|
current_array[smp_cpuid()] = task;
|
|
}
|
|
|
|
extern struct task kernel_task;
|
|
|
|
/**
|
|
* @brief Initialize the scheduler.
|
|
*
|
|
* @return 0 on success, or a negative error number on failure
|
|
*/
|
|
int sched_init(void);
|
|
|
|
/**
|
|
* @brief Main scheduler routine.
|
|
* Calling this function will result in the current task being suspended and put
|
|
* back to the queue, and a new one is selected to be run next. The scheduler
|
|
* is free to choose the current task again, in which case this call does not
|
|
* sleep. The function returns when the scheduler has been invoked again and
|
|
* decided to give this task its next turn.
|
|
*/
|
|
void schedule(void);
|
|
|
|
/**
|
|
* @brief Perform an in-kernel task switch.
|
|
* `new` must not be equal to `old` or the whole thing probably blows up.
|
|
*
|
|
* The Linux kernel has a similar function with the same name, except that the
|
|
* arguments are in reverse order because i find it funny to cause unnecessary
|
|
* confusion which will undoubtedly result in a lot of bugs further down the
|
|
* road that are going to take weeks to find.
|
|
*
|
|
* @param new New task to switch to
|
|
* @param old Current task
|
|
*/
|
|
void switch_to(struct task *new, struct task *old);
|