mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-10 23:09:18 +00:00
Refactor task scheduler
This commit is contained in:
150
include/scheduler.hpp
Normal file
150
include/scheduler.hpp
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <task.hpp>
|
||||
#include <lock.hpp>
|
||||
|
||||
namespace Tasking::Scheduler
|
||||
{
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
Task *ctx = nullptr;
|
||||
std::atomic_size_t SchedulerTicks = 0;
|
||||
std::atomic_size_t LastTaskTicks = 0;
|
||||
std::atomic_int LastCore = 0;
|
||||
std::atomic_bool StopScheduler = false;
|
||||
std::atomic_bool SchedulerUpdateTrapFrame = false;
|
||||
|
||||
/**
|
||||
* Remove a thread from the scheduler
|
||||
*
|
||||
* @note This function is NOT thread safe
|
||||
* @note This function does not check if
|
||||
* the thread is valid nor if it has
|
||||
* Terminated status
|
||||
*/
|
||||
virtual bool RemoveThread(TCB *tcb)
|
||||
{
|
||||
assert(!"RemoveThread not implemented");
|
||||
};
|
||||
|
||||
/**
|
||||
* @note This function is NOT thread safe
|
||||
*/
|
||||
virtual bool RemoveProcess(PCB *pcb)
|
||||
{
|
||||
assert(!"RemoveProcess not implemented");
|
||||
}
|
||||
|
||||
virtual PCB *GetProcessByID(TID ID)
|
||||
{
|
||||
assert(!"GetProcessByID not implemented");
|
||||
}
|
||||
|
||||
virtual TCB *GetThreadByID(TID ID)
|
||||
{
|
||||
assert(!"GetThreadByID not implemented");
|
||||
}
|
||||
|
||||
virtual std::list<PCB *> &GetProcessList()
|
||||
{
|
||||
assert(!"GetProcessList not implemented");
|
||||
}
|
||||
|
||||
virtual void StartIdleProcess()
|
||||
{
|
||||
assert(!"StartIdleProcess not implemented");
|
||||
}
|
||||
|
||||
virtual void StartScheduler()
|
||||
{
|
||||
assert(!"StartScheduler not implemented");
|
||||
}
|
||||
|
||||
virtual void Yield()
|
||||
{
|
||||
assert(!"Yield not implemented");
|
||||
}
|
||||
|
||||
virtual void PushProcess(PCB *pcb)
|
||||
{
|
||||
assert(!"PushProcess not implemented");
|
||||
}
|
||||
|
||||
virtual void PopProcess(PCB *pcb)
|
||||
{
|
||||
assert(!"PopProcess not implemented");
|
||||
}
|
||||
|
||||
Base(Task *_ctx)
|
||||
: ctx(_ctx) {}
|
||||
|
||||
~Base() {}
|
||||
};
|
||||
|
||||
class Custom : public Base,
|
||||
public Interrupts::Handler
|
||||
{
|
||||
private:
|
||||
NewLock(SchedulerLock);
|
||||
|
||||
public:
|
||||
std::list<PCB *> ProcessList;
|
||||
|
||||
PCB *IdleProcess = nullptr;
|
||||
TCB *IdleThread = nullptr;
|
||||
|
||||
bool RemoveThread(TCB *tcb) final;
|
||||
bool RemoveProcess(PCB *pcb) final;
|
||||
PCB *GetProcessByID(TID ID) final;
|
||||
TCB *GetThreadByID(TID ID) final;
|
||||
std::list<PCB *> &GetProcessList() final;
|
||||
void StartIdleProcess() final;
|
||||
void StartScheduler() final;
|
||||
void Yield() final;
|
||||
void PushProcess(PCB *pcb) final;
|
||||
void PopProcess(PCB *pcb) final;
|
||||
|
||||
void OneShot(int TimeSlice);
|
||||
|
||||
void UpdateUsage(TaskInfo *Info,
|
||||
TaskExecutionMode Mode,
|
||||
int Core);
|
||||
|
||||
bool FindNewProcess(void *CPUDataPointer);
|
||||
bool GetNextAvailableThread(void *CPUDataPointer);
|
||||
bool GetNextAvailableProcess(void *CPUDataPointer);
|
||||
bool SchedulerSearchProcessThread(void *CPUDataPointer);
|
||||
void UpdateProcessState();
|
||||
void WakeUpThreads();
|
||||
void CleanupTerminated();
|
||||
|
||||
void Schedule(CPU::TrapFrame *Frame);
|
||||
void OnInterruptReceived(CPU::TrapFrame *Frame) final;
|
||||
|
||||
Custom(Task *ctx);
|
||||
virtual ~Custom();
|
||||
};
|
||||
|
||||
class RoundRobin : public Base,
|
||||
public Interrupts::Handler
|
||||
{
|
||||
};
|
||||
}
|
115
include/task.hpp
115
include/task.hpp
@ -467,7 +467,7 @@ namespace Tasking
|
||||
~PCB();
|
||||
};
|
||||
|
||||
class Task : public Interrupts::Handler
|
||||
class Task
|
||||
{
|
||||
private:
|
||||
NewLock(SchedulerLock);
|
||||
@ -476,114 +476,43 @@ namespace Tasking
|
||||
PID NextPID = 0;
|
||||
TID NextTID = 0;
|
||||
|
||||
std::list<PCB *> ProcessList;
|
||||
PCB *KernelProcess = nullptr;
|
||||
PCB *IdleProcess = nullptr;
|
||||
TCB *IdleThread = nullptr;
|
||||
std::atomic_size_t SchedulerTicks = 0;
|
||||
std::atomic_size_t LastTaskTicks = 0;
|
||||
std::atomic_int LastCore = 0;
|
||||
std::atomic_bool StopScheduler = false;
|
||||
std::atomic_bool SchedulerUpdateTrapFrame = false;
|
||||
|
||||
bool InvalidPCB(PCB *pcb);
|
||||
bool InvalidTCB(TCB *tcb);
|
||||
void *Scheduler = nullptr;
|
||||
void *__sched_ctx = nullptr;
|
||||
|
||||
/**
|
||||
* Remove a thread from the scheduler
|
||||
*
|
||||
* @note This function is NOT thread safe
|
||||
* @note This function does not check if
|
||||
* the thread is valid nor if it has
|
||||
* Terminated status
|
||||
*/
|
||||
bool RemoveThread(TCB *tcb);
|
||||
constexpr TaskArchitecture GetKArch()
|
||||
{
|
||||
#if defined(a64)
|
||||
return x64;
|
||||
#elif defined(a32)
|
||||
return x32;
|
||||
#elif defined(aa64)
|
||||
return ARM64;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @note This function is NOT thread safe
|
||||
*/
|
||||
bool RemoveProcess(PCB *pcb);
|
||||
|
||||
void UpdateUsage(TaskInfo *Info,
|
||||
TaskExecutionMode Mode,
|
||||
int Core);
|
||||
|
||||
/**
|
||||
* @note This function is NOT thread safe
|
||||
*/
|
||||
bool FindNewProcess(void *CPUDataPointer);
|
||||
|
||||
/**
|
||||
* @note This function is NOT thread safe
|
||||
*/
|
||||
bool GetNextAvailableThread(void *CPUDataPointer);
|
||||
|
||||
/**
|
||||
* @note This function is NOT thread safe
|
||||
*/
|
||||
bool GetNextAvailableProcess(void *CPUDataPointer);
|
||||
|
||||
/**
|
||||
* @note This function is NOT thread safe
|
||||
*/
|
||||
bool SchedulerSearchProcessThread(void *CPUDataPointer);
|
||||
|
||||
/**
|
||||
* @note This function is NOT thread safe
|
||||
*/
|
||||
void UpdateProcessState();
|
||||
|
||||
/**
|
||||
* @note This function is NOT thread safe
|
||||
*/
|
||||
void WakeUpThreads();
|
||||
|
||||
/**
|
||||
* @note This function is NOT thread safe
|
||||
*/
|
||||
void CleanupTerminated();
|
||||
|
||||
/**
|
||||
* @note This function is NOT thread safe
|
||||
*/
|
||||
void Schedule(CPU::TrapFrame *Frame);
|
||||
|
||||
void OnInterruptReceived(CPU::TrapFrame *Frame) final;
|
||||
void PushProcess(PCB *pcb);
|
||||
void PopProcess(PCB *pcb);
|
||||
|
||||
public:
|
||||
void *GetScheduler() { return Scheduler; }
|
||||
PCB *GetKernelProcess() { return KernelProcess; }
|
||||
size_t GetSchedulerTicks() { return SchedulerTicks.load(); }
|
||||
size_t GetLastTaskTicks() { return LastTaskTicks.load(); }
|
||||
int GetLastCore() { return LastCore.load(); }
|
||||
std::list<PCB *> GetProcessList() { return ProcessList; }
|
||||
void Panic() { StopScheduler = true; }
|
||||
bool IsPanic() { return StopScheduler; }
|
||||
std::list<PCB *> GetProcessList();
|
||||
void Panic();
|
||||
bool IsPanic();
|
||||
|
||||
/**
|
||||
* Yield the current thread and switch
|
||||
* to another thread if available
|
||||
*/
|
||||
__always_inline inline void Yield()
|
||||
{
|
||||
/* This will trigger the IRQ16
|
||||
instantly so we won't execute
|
||||
the next instruction */
|
||||
#if defined(a86)
|
||||
asmv("int $0x30");
|
||||
#elif defined(aa64)
|
||||
asmv("svc #0x30");
|
||||
#endif
|
||||
}
|
||||
void Yield();
|
||||
|
||||
/**
|
||||
* Update the current thread's trap frame
|
||||
* without switching to another thread
|
||||
*/
|
||||
__always_inline inline void UpdateFrame()
|
||||
{
|
||||
SchedulerUpdateTrapFrame = true;
|
||||
Yield();
|
||||
}
|
||||
void UpdateFrame();
|
||||
|
||||
void SignalShutdown();
|
||||
|
||||
@ -670,6 +599,4 @@ namespace Tasking
|
||||
#define thisProcess GetCurrentCPU()->CurrentProcess.load()
|
||||
#define thisThread GetCurrentCPU()->CurrentThread.load()
|
||||
|
||||
extern "C" void TaskingScheduler_OneShot(int TimeSlice);
|
||||
|
||||
#endif // !__FENNIX_KERNEL_TASKING_H__
|
||||
|
Reference in New Issue
Block a user