From 0266d8058990a496b935abd76417abcfe4e9cffd Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 18 May 2025 15:15:52 +0200 Subject: dev(sched): Improvements and work in progress fixes. what? - The main algorithm got improved for real time tasks, and SMP usage. - The SMP usage was present before, I just reintroduced it after realizing that it won't scale well from what I have right now. - Also removed weird implementations quirks from previous sketch. - Such as the core 0 being reserved for the boot core. - Also moved FS init code after IDT initalization. - To avoid weird FS format behavior. - Wrap HPET signature in a macro. next? - Work on the HAL's userspace transition mechanism. Signed-off-by: Amlal El Mahrouss --- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 30 ++++++++++++++--- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 2 -- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 15 +++++---- dev/kernel/HALKit/AMD64/HalTimerAMD64.cc | 4 ++- dev/kernel/KernelKit/HardwareThreadScheduler.h | 10 +++--- dev/kernel/src/ACPIFactoryInterface.cc | 7 ++-- dev/kernel/src/HardwareThreadScheduler.cc | 8 ++--- dev/kernel/src/UserProcessScheduler.cc | 38 ++++++++++------------ 8 files changed, 64 insertions(+), 50 deletions(-) diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 7e2b8957..eac6c389 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -37,6 +37,9 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "General Access Fault."); + } if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -62,6 +65,10 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Access Fault."); + } + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -101,6 +108,9 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Math Fault."); + } if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -126,6 +136,10 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Generic Fault."); + } + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -146,10 +160,15 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { } EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { - hal_idt_send_eoi(3); - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + while (YES) + ; + } + + hal_idt_send_eoi(3); + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -167,8 +186,6 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { Kernel::kout << "Kernel: SIGTRAP status.\r"; process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; - - idt_handle_scheduler(rip); } /// @brief Handle #UD fault. @@ -180,6 +197,11 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + while (YES) + ; + } + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index 667d3c5b..a6b194d3 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -224,8 +224,6 @@ __NE_INT_32: std - add rsp, 8 - o64 iret IntNormal 33 diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 581af60a..f4585835 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -110,24 +110,25 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - Kernel::HAL::Register64 idt_reg; - idt_reg.Base = reinterpret_cast(kInterruptVectorTable); - - Kernel::HAL::IDTLoader idt_loader; - - idt_loader.Load(idt_reg); - #ifdef __FSKIT_INCLUDES_HEFS__ if (Kernel::HeFS::fs_init_hefs()) { goto hal_spin_kernel; } #endif + if (!Kernel::NeFS::fs_init_nefs()) { kout << "NeFS cannot be formated on the disk. Aborting\r"; dbg_break_point(); } hal_spin_kernel: + Kernel::HAL::Register64 idt_reg; + idt_reg.Base = reinterpret_cast(kInterruptVectorTable); + + Kernel::HAL::IDTLoader idt_loader; + + idt_loader.Load(idt_reg); + while (YES) ; } diff --git a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc b/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc index 79165289..13573880 100644 --- a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc @@ -17,6 +17,8 @@ // timer slot 0 +#define kHPETSignature ("HPET") + #define kHPETCounterRegValue (0x00) #define kHPETConfigRegValue (0x20) #define kHPETCompRegValue (0x24) @@ -46,7 +48,7 @@ using namespace Kernel; HardwareTimer::HardwareTimer(UInt64 ms) : fWaitFor(ms) { auto power = PowerFactoryInterface(kHandoverHeader->f_HardwareTables.f_VendorPtr); - auto hpet = (Detail::HPET_BLOCK*) power.Find("HPET").Leak().Leak(); + auto hpet = (Detail::HPET_BLOCK*) power.Find(kHPETSignature).Leak().Leak(); MUST_PASS(hpet); fDigitalTimer = (UInt8*) hpet->address.Address; diff --git a/dev/kernel/KernelKit/HardwareThreadScheduler.h b/dev/kernel/KernelKit/HardwareThreadScheduler.h index dd8271eb..4a3220bd 100644 --- a/dev/kernel/KernelKit/HardwareThreadScheduler.h +++ b/dev/kernel/KernelKit/HardwareThreadScheduler.h @@ -24,11 +24,11 @@ using ThreadID = UInt32; enum ThreadKind { kAPInvalid, - kAPSystemReserved, // System reserved thread, well user can't use it - kAPStandard, // user thread, cannot be used by Kernel - kAPRealTime, // fallback thread, cannot be used by user if not clear or - // used by Kernel. - kAPBoot, // The core we booted from, the mama. + kAPSystemReserved = 100, // System reserved thread, well user can't use it + kAPStandard, // user thread, cannot be used by Kernel + kAPRealTime, // fallback thread, cannot be used by user if not clear or + // used by Kernel. + kAPBoot, // The core we booted from, the mama. kAPCount, }; diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc index a76caff2..ded49587 100644 --- a/dev/kernel/src/ACPIFactoryInterface.cc +++ b/dev/kernel/src/ACPIFactoryInterface.cc @@ -14,13 +14,12 @@ namespace Kernel { ErrorOr ACPIFactoryInterface::Find(const Char* signature) { MUST_PASS(this->fRsdp); - if (!signature) return ErrorOr{-1}; - - if (*signature == 0) return ErrorOr{-1}; + if (!signature) return ErrorOr{nullptr}; + if (*signature == 0) return ErrorOr{nullptr}; RSDP* rsp_ptr = reinterpret_cast(this->fRsdp); - if (rsp_ptr->Revision <= 1) return ErrorOr{-1}; + if (rsp_ptr->Revision < 1) return ErrorOr{nullptr}; RSDT* xsdt = reinterpret_cast(rsp_ptr->RsdtAddress); diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index 6cb83b3d..eda68104 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -158,12 +158,8 @@ HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept { */ /***********************************************************************************/ Ref HardwareThreadScheduler::operator[](SizeT idx) { - if (idx == 0) { - if (fThreadList[idx].Kind() != kAPSystemReserved) { - fThreadList[idx].fKind = kAPBoot; - } - } else if (idx >= kMaxAPInsideSched) { - static HardwareThread* kFakeThread = nullptr; + if (idx >= kMaxAPInsideSched) { + STATIC HardwareThread* kFakeThread = nullptr; return {kFakeThread}; } diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index b0d56c5d..165cfb5d 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -494,37 +494,28 @@ SizeT UserProcessScheduler::Run() noexcept { //! Check if the process needs to be run. if (UserProcessHelper::CanBeScheduled(process)) { - if (process.StackSize > kSchedMaxStackSz) { - kout << "Process: " << process.Name << ", has not a valid stack size! Crashing it...\r"; - process.Crash(); - continue; - } - kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled...\r"; process.PTime = static_cast(process.Affinity); - if (process.PTime < process.RTime) { + if (process.PTime < process.RTime && AffinityKind::kRealTime != process.Affinity) { if (process.RTime < (Int32) AffinityKind::kVeryHigh) - process.RTime = (Int32) AffinityKind::kLowUsage; + process.RTime = (Int32) AffinityKind::kLowUsage / 2; else if (process.RTime < (Int32) AffinityKind::kHigh) - process.RTime = (Int32) AffinityKind::kStandard; + process.RTime = (Int32) AffinityKind::kStandard / 3; else if (process.RTime < (Int32) AffinityKind::kStandard) - process.RTime = (Int32) AffinityKind::kHigh; + process.RTime = (Int32) AffinityKind::kHigh / 4; - process.PTime += process.RTime; + process.PTime -= process.RTime; process.RTime = 0UL; } if (!UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { - break; + continue; } - - mTeam.AsArray()[this->TheCurrentProcess().Leak().ProcessId] = - this->TheCurrentProcess().Leak(); - - this->TheCurrentProcess() = process; } else { + kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled later...\r"; + ++process.RTime; --process.PTime; } @@ -575,14 +566,13 @@ ErrorOr UserProcessHelper::TheCurrentPID() { /// @retval false cannot be schedulded. Bool UserProcessHelper::CanBeScheduled(const USER_PROCESS& process) { if (process.Status != ProcessStatusKind::kRunning) return No; - + if (process.StackSize > kSchedMaxStackSz) return No; if (!process.Name[0]) return No; // real time processes shouldn't wait that much. if (process.Affinity == AffinityKind::kRealTime) return Yes; - if (process.Signal.SignalID == SIGKILL || process.Signal.SignalID == SIGABRT || - process.Signal.SignalID == SIGTRAP) { + if (process.Signal.SignalID == SIGTRAP) { return No; } @@ -625,7 +615,10 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { UserProcessHelper::TheCurrentPID().Leak().Leak() = UserProcessHelper::TheCurrentPID(); - break; + UserProcessScheduler::The().TheCurrentProcess() = + UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid]; + + return YES; } continue; @@ -653,6 +646,9 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].PTime; HardwareThreadScheduler::The()[index].Leak()->Wake(YES); + UserProcessScheduler::The().TheCurrentProcess() = + UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid]; + return YES; } -- cgit v1.2.3