mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
Create a new framebuffer driver. Also hackily passing frame buffer size in the list of init handles to all processes and mapping the framebuffer into all processes. Changed bootloader passing frame buffer as a module to its own struct.
112 lines
3.0 KiB
C++
112 lines
3.0 KiB
C++
#pragma once
|
|
/// \file scheduler.h
|
|
/// The task scheduler and related definitions
|
|
|
|
#include <stdint.h>
|
|
#include "objects/thread.h"
|
|
|
|
class lapic;
|
|
class process;
|
|
struct page_table;
|
|
struct cpu_state;
|
|
|
|
extern "C" void isr_handler(cpu_state*);
|
|
extern "C" void task_switch(TCB *next);
|
|
|
|
|
|
/// The task scheduler
|
|
class scheduler
|
|
{
|
|
public:
|
|
/// Total number of priority levels
|
|
static const uint8_t num_priorities = 8;
|
|
|
|
/// Maximum (least urgent/interactive) priority
|
|
static const uint8_t max_priority = num_priorities - 1;
|
|
|
|
/// Default priority on process creation
|
|
static const uint8_t default_priority = 1;
|
|
|
|
/// Lowest (most urgent) priority achieved via promotion
|
|
static const uint8_t promote_limit = 1;
|
|
|
|
/// How long the base timer quantum is, in us
|
|
static const uint64_t quantum_micros = 500;
|
|
|
|
/// How many quanta a process gets before being rescheduled
|
|
static const uint16_t process_quanta = 10;
|
|
|
|
/// Constructor.
|
|
/// \arg apic Pointer to the local APIC object
|
|
scheduler(lapic *apic);
|
|
|
|
/// Create a new process from a program image in memory.
|
|
/// \arg phys Physical address of the loaded program image
|
|
/// \arg virt Virtual address of the loaded program image
|
|
/// \arg size Size of the program image, in bytes
|
|
/// \arg entry Virtual address of the program entrypoint
|
|
/// \returns The main thread of the loaded process
|
|
thread * load_process(uintptr_t phys, uintptr_t virt, size_t size, uintptr_t entry);
|
|
|
|
/// Create a new kernel task
|
|
/// \arg proc Function to run as a kernel task
|
|
/// \arg priority Priority to start the process with
|
|
/// \arg constant True if this task cannot be promoted/demoted
|
|
void create_kernel_task(
|
|
void (*task)(),
|
|
uint8_t priority,
|
|
bool constant = false);
|
|
|
|
/// Get the quantum for a given priority.
|
|
uint32_t quantum(int priority);
|
|
|
|
/// Start the scheduler working. This may involve starting
|
|
/// timer interrupts or other preemption methods.
|
|
void start();
|
|
|
|
/// Run the scheduler, possibly switching to a new task
|
|
void schedule();
|
|
|
|
/// Get the current TCB.
|
|
/// \returns A pointer to the current thread's TCB
|
|
inline TCB * current() { return m_current; }
|
|
|
|
inline void add_thread(TCB *t) { m_blocked.push_back(static_cast<tcb_node*>(t)); }
|
|
|
|
/// Get a reference to the system scheduler
|
|
/// \returns A reference to the global system scheduler
|
|
static scheduler & get() { return *s_instance; }
|
|
|
|
private:
|
|
friend uintptr_t syscall_dispatch(uintptr_t, cpu_state &);
|
|
friend class process;
|
|
|
|
static constexpr uint64_t promote_frequency = 10;
|
|
|
|
/// Create a new process object. This process will have its pid
|
|
/// set but nothing else.
|
|
/// \arg user True if this thread will enter userspace
|
|
/// \returns The new process' main thread
|
|
thread * create_process(bool user);
|
|
|
|
void prune(uint64_t now);
|
|
void check_promotions(uint64_t now);
|
|
|
|
lapic *m_apic;
|
|
|
|
uint32_t m_next_pid;
|
|
uint32_t m_tick_count;
|
|
|
|
process *m_kernel_process;
|
|
tcb_node *m_current;
|
|
tcb_list m_runlists[num_priorities];
|
|
tcb_list m_blocked;
|
|
|
|
// TODO: lol a real clock
|
|
uint64_t m_clock = 0;
|
|
uint64_t m_last_promotion;
|
|
|
|
static scheduler *s_instance;
|
|
};
|
|
|