From da70596895d8135e08f8caac6978117697b4c021 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 18 Aug 2024 21:39:29 +0200 Subject: [REFACTOR] Improved project structure. Signed-off-by: Amlal El Mahrouss --- dev/Kernel/Sources/ProcessScheduler.cxx | 464 -------------------------------- 1 file changed, 464 deletions(-) delete mode 100644 dev/Kernel/Sources/ProcessScheduler.cxx (limited to 'dev/Kernel/Sources/ProcessScheduler.cxx') diff --git a/dev/Kernel/Sources/ProcessScheduler.cxx b/dev/Kernel/Sources/ProcessScheduler.cxx deleted file mode 100644 index 8ca94b60..00000000 --- a/dev/Kernel/Sources/ProcessScheduler.cxx +++ /dev/null @@ -1,464 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Technologies. - -------------------------------------------- */ - -/***********************************************************************************/ -/// @file ProcessScheduler.cxx -/// @brief MicroKernel process scheduler. -/***********************************************************************************/ - -#include -#include -#include -#include -#include -#include - -///! BUGS: 0 - -/***********************************************************************************/ -/* This file handles the process scheduling. */ -/***********************************************************************************/ - -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Exit Code global - /***********************************************************************************/ - - STATIC Int32 cLastExitCode = 0U; - - /// @brief Gets the last exit code. - /// @note Not thread-safe. - /// @return Int32 the last exit code. - const Int32& sched_get_exit_code(void) noexcept - { - return cLastExitCode; - } - - /***********************************************************************************/ - /// @brief crash current process. - /***********************************************************************************/ - - void PROCESS_HEADER_BLOCK::Crash() - { - kcout << (*this->Name == 0 ? "Kernel" : this->Name) << ": crashed. (id = "; - kcout << number(kErrorProcessFault); - kcout << ")\r"; - - if (Kernel::ProcessScheduler::The().Leak().CurrentTeam().AsArray().Count() < 1) - { - kcout << "*** BAD PROCESS ***\rTerminating as we are the only process...\r"; - ke_stop(RUNTIME_CHECK_PROCESS); - } - - this->Exit(kErrorProcessFault); - } - - /// @brief Gets the local last exit code. - /// @note Not thread-safe. - /// @return Int32 the last exit code. - const Int32& PROCESS_HEADER_BLOCK::GetExitCode() noexcept - { - return this->fLastExitCode; - } - - Int32& PROCESS_HEADER_BLOCK::GetLocalCode() noexcept - { - return fLocalCode; - } - - void PROCESS_HEADER_BLOCK::Wake(const bool should_wakeup) - { - this->Status = - should_wakeup ? ProcessStatus::kRunning : ProcessStatus::kFrozen; - } - - /***********************************************************************************/ - - VoidPtr PROCESS_HEADER_BLOCK::New(const SizeT& sz) - { - if (this->HeapCursor) - { - if (this->FreeMemory < 1) - { - ErrLocal() = kErrorHeapOutOfMemory; - - /* We're going out of memory! crash... */ - this->Crash(); - - return nullptr; - } - - this->HeapCursor = reinterpret_cast((UIntPtr)this->HeapCursor + (sizeof(sz))); - VoidPtr ptr = this->HeapCursor; - - ++this->UsedMemory; - --this->FreeMemory; - - return ptr; - } - - return nullptr; - } - - /***********************************************************************************/ - - /* @brief checks if runtime pointer is in region. */ - bool rt_is_in_pool(VoidPtr pool_ptr, VoidPtr pool, const SizeT& pool_ptr_cur_sz, const SizeT& pool_ptr_used_sz) - { - if (pool == nullptr || - pool_ptr == nullptr) - return false; - - UIntPtr* uint_pool_ptr = (UIntPtr*)pool_ptr; - UIntPtr* uint_pool = (UIntPtr*)pool; - - return (UIntPtr)&uint_pool > (UIntPtr)&uint_pool_ptr && - pool_ptr_cur_sz > pool_ptr_used_sz; - } - - /* @brief free pointer from usage. */ - Boolean PROCESS_HEADER_BLOCK::Delete(VoidPtr ptr, const SizeT& sz) - { - if (sz < 1 || this->HeapCursor == this->HeapPtr) - return false; - - // also check for the amount of allocations we've done so far. - if (this->UsedMemory < 1) - return false; - - if (rt_is_in_pool(ptr, this->HeapCursor, this->UsedMemory, this->FreeMemory)) - { - this->HeapCursor = (VoidPtr)((UIntPtr)this->HeapCursor - (sizeof(sz))); - rt_zero_memory(ptr, sz); - - ++this->FreeMemory; - --this->UsedMemory; - - return true; - } - - return false; - } - - /// @brief process name getter. - const Char* PROCESS_HEADER_BLOCK::GetProcessName() noexcept - { - return this->Name; - } - - /// @brief process selector getter. - const ProcessLevelRing& PROCESS_HEADER_BLOCK::GetLevelRing() noexcept - { - return this->Selector; - } - - /// @brief process status getter. - const ProcessStatus& PROCESS_HEADER_BLOCK::GetStatus() noexcept - { - return this->Status; - } - - /***********************************************************************************/ - - /** - @brief Affinity is the time slot allowed for the process. - */ - const AffinityKind& PROCESS_HEADER_BLOCK::GetAffinity() noexcept - { - return this->Affinity; - } - - /** - @brief Standard exit proc. - */ - void PROCESS_HEADER_BLOCK::Exit(const Int32& exit_code) - { - if (this->ProcessId != - ProcessScheduler::The().Leak().TheCurrent().Leak().ProcessId) - ke_stop(RUNTIME_CHECK_PROCESS); - - fLastExitCode = exit_code; - cLastExitCode = exit_code; - - //! Delete image if not done already. - if (this->Image) - mm_delete_ke_heap(this->Image); - - if (this->StackFrame) - mm_delete_ke_heap((VoidPtr)this->StackFrame); - - this->Image = nullptr; - this->StackFrame = nullptr; - - if (this->Kind == kSharedObjectKind) - { - bool success = false; - rtl_fini_shared_object(this, this->DLLPtr, &success); - - if (success) - { - this->DLLPtr = nullptr; - } - } - - ProcessScheduler::The().Leak().Remove(this->ProcessId); - } - - /// @brief Add process to list. - /// @param process - /// @return - SizeT ProcessScheduler::Add(Ref& process) - { - if (!process.Leak().Image) - { - if (process.Leak().Kind != PROCESS_HEADER_BLOCK::kSharedObjectKind) - { - return -kErrorNoEntrypoint; - } - } - - if (mTeam.AsArray().Count() > kSchedProcessLimitPerTeam) - return -kErrorOutOfTeamSlot; - - kcout << "ProcessScheduler:: adding process to team...\r"; - - // Create heap according to type of process. - if (process.Leak().Kind == PROCESS_HEADER_BLOCK::kAppKind) - { - process.Leak().HeapPtr = sched_new_heap(kProcessHeapUser | kProcessHeapRw, process.Leak().SizeMemory); - } - else if (process.Leak().Kind == PROCESS_HEADER_BLOCK::kSharedObjectKind) - { - process.Leak().DLLPtr = rtl_init_shared_object(&process.Leak()); - process.Leak().HeapPtr = sched_new_heap(kProcessHeapUser | kProcessHeapRw | kProcessHeapShared, process.Leak().SizeMemory); - } - else - { - // Something went wrong, do not continue, process may be incorrect. - process.Leak().Crash(); - return -kErrorProcessFault; - } - - process.Leak().StackFrame = reinterpret_cast( - mm_new_ke_heap(sizeof(HAL::StackFrame), Yes, Yes)); - - MUST_PASS(process.Leak().StackFrame); - - if (process.Leak().Image) - { - process.Leak().StackFrame->BP = reinterpret_cast(process.Leak().Image); - } - else - { - if (process.Leak().Kind != PROCESS_HEADER_BLOCK::kSharedObjectKind) - { - process.Leak().Crash(); - return -kErrorProcessFault; - } - } - - if (!process.Leak().StackFrame->SP) - process.Leak().StackFrame->SP = reinterpret_cast(mm_new_ke_heap(sizeof(UInt8) * 8196, Yes, Yes)); - - process.Leak().Status = ProcessStatus::kStarting; - - process.Leak().ProcessId = (mTeam.AsArray().Count() - 1); - process.Leak().HeapCursor = process.Leak().HeapPtr; - - MUST_PASS(mTeam.AsArray().Add(process)); - - return (mTeam.AsArray().Count() - 1); - } - - /// @brief Remove process from list. - /// @param processSlot process slot inside team. - /// @retval true process was removed. - /// @retval false process doesn't exist in team. - Bool ProcessScheduler::Remove(SizeT processSlot) - { - // check if process is within range. - if (processSlot > mTeam.AsArray().Count()) - return false; - - // also check if the process isn't a dummy one. - if (mTeam.AsArray()[processSlot].Leak().Leak().Image == nullptr) - return false; - - kcout << "ProcessScheduler: removing process\r"; - - return mTeam.AsArray().Remove(processSlot); - } - - /// @brief Run scheduler. - /// @return - SizeT ProcessScheduler::Run() noexcept - { - SizeT process_index = 0; //! we store this guy to tell the scheduler how many - //! things we have scheduled. - - for (; process_index < mTeam.AsArray().Count(); ++process_index) - { - auto process = mTeam.AsArray()[process_index]; - - //! check if process needs to be scheduled. - if (ProcessHelper::CanBeScheduled(process.Leak())) - { - auto unwrapped_process = *process.Leak(); - - // set the current process. - mTeam.AsRef() = unwrapped_process; - - // tell helper to find a core to schedule on. - ProcessHelper::Switch(unwrapped_process.StackFrame, - unwrapped_process.ProcessId); - - unwrapped_process.PTime = static_cast(unwrapped_process.Affinity); - - kcout << unwrapped_process.Name << ": has been switched to process core.\r"; - } - else - { - // otherwise increment the P-time. - --mTeam.AsRef().Leak().PTime; - } - } - - return process_index; - } - - /// @brief Gets the current scheduled team. - /// @return - ProcessTeam& ProcessScheduler::CurrentTeam() - { - return mTeam; - } - - /// @internal - STATIC Ref cSchedulerRef; - - /// @brief Shared instance of the process scheduler. - /// @return - Ref& ProcessScheduler::The() - { - return cSchedulerRef; - } - - /// @brief Gets current running process. - /// @return - Ref& ProcessScheduler::TheCurrent() - { - return mTeam.AsRef(); - } - - /// @brief Current proccess id getter. - /// @return Process ID integer. - PID& ProcessHelper::TheCurrentPID() - { - kcout << "ProcessHelper::TheCurrentPID: Leaking ProcessId...\r"; - return ProcessScheduler::The().Leak().TheCurrent().Leak().ProcessId; - } - - /// @brief Check if process can be schedulded. - /// @param process the process reference. - /// @retval true can be schedulded. - /// @retval false cannot be schedulded. - bool ProcessHelper::CanBeScheduled(Ref& process) - { - if (process.Leak().Status == ProcessStatus::kFrozen || - process.Leak().Status == ProcessStatus::kDead) - return false; - - if (process.Leak().Kind == PROCESS_HEADER_BLOCK::kSharedObjectKind) - { - if (auto start = process.Leak().DLLPtr->Load(kPefStart, rt_string_len(kPefStart), kPefCode); - start) - { - process.Leak().Image = start; - process.Leak().StackFrame->BP = reinterpret_cast(start); - } - } - - if (process.Leak().GetStatus() == ProcessStatus::kStarting) - { - if (process.Leak().PTime <= 0) - { - process.Leak().Status = ProcessStatus::kRunning; - process.Leak().Affinity = AffinityKind::kStandard; - - return true; - } - - ++process.Leak().PTime; - } - - return process.Leak().PTime > 0; - } - - /** - * @brief Spin scheduler class. - */ - - SizeT ProcessHelper::StartScheduling() - { - auto& process_ref = ProcessScheduler::The().Leak(); - SizeT ret = process_ref.Run(); - - return ret; - } - - /** - * \brief Does a context switch in a CPU. - * \param the_stack the stackframe of the running app. - * \param new_pid the process's PID. - */ - - bool ProcessHelper::Switch(HAL::StackFrame* the_stack, const PID& new_pid) - { - if (!the_stack || new_pid < 0) - return false; - - for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Leak().Count(); ++index) - { - if (HardwareThreadScheduler::The().Leak()[index].Leak()->Kind() == kInvalidHart) - continue; - - if (HardwareThreadScheduler::The().Leak()[index].Leak()->StackFrame() == the_stack) - { - HardwareThreadScheduler::The().Leak()[index].Leak()->Busy(false); - continue; - } - - if (HardwareThreadScheduler::The().Leak()[index].Leak()->IsBusy()) - continue; - - if (HardwareThreadScheduler::The().Leak()[index].Leak()->Kind() != - ThreadKind::kHartBoot && - HardwareThreadScheduler::The().Leak()[index].Leak()->Kind() != - ThreadKind::kHartSystemReserved) - { - HardwareThreadScheduler::The().Leak()[index].Leak()->Busy(true); - ProcessHelper::TheCurrentPID() = new_pid; - - return HardwareThreadScheduler::The().Leak()[index].Leak()->Switch(the_stack); - } - } - - return false; - } - - /// @brief this checks if any process is on the team. - ProcessScheduler::operator bool() - { - return mTeam.AsArray().Count() > 0; - } - - /// @brief this checks if no process is on the team. - bool ProcessScheduler::operator!() - { - return mTeam.AsArray().Count() == 0; - } -} // namespace Kernel -- cgit v1.2.3