diff options
| author | Amlal <amlalelmahrouss@icloud.com> | 2024-09-05 19:13:02 +0000 |
|---|---|---|
| committer | Amlal <amlalelmahrouss@icloud.com> | 2024-09-05 19:13:02 +0000 |
| commit | 621e814da6d5005ade8a1fe3f378a363db559cf7 (patch) | |
| tree | 438f1337c0eb2ae83cf3d409c29848d396be08b2 /dev/ZKA/Sources/UserProcessScheduler.cxx | |
| parent | cc9ce57cac59bd443e2319e3b8f427172b93f7da (diff) | |
| parent | 3b60a1e87ab02a1b72d8bb9f7392780899d5a0d7 (diff) | |
Merged in major-refactor (pull request #19)
Major refactor
Diffstat (limited to 'dev/ZKA/Sources/UserProcessScheduler.cxx')
| -rw-r--r-- | dev/ZKA/Sources/UserProcessScheduler.cxx | 215 |
1 files changed, 103 insertions, 112 deletions
diff --git a/dev/ZKA/Sources/UserProcessScheduler.cxx b/dev/ZKA/Sources/UserProcessScheduler.cxx index dc142b18..8c46b1cf 100644 --- a/dev/ZKA/Sources/UserProcessScheduler.cxx +++ b/dev/ZKA/Sources/UserProcessScheduler.cxx @@ -2,16 +2,19 @@ Copyright ZKA Technologies. + FILE: UserProcessScheduler.cxx + PURPOSE: User sided process scheduler. + ------------------------------------------- */ /***********************************************************************************/ /// @file UserProcessScheduler.cxx -/// @brief User UserProcess scheduler. +/// @brief User Process scheduler. /***********************************************************************************/ #include <KernelKit/UserProcessScheduler.hxx> -#include <KernelKit/PEFDLLInterface.hxx> -#include <KernelKit/MP.hxx> +#include <KernelKit/IPEFDLLObject.hxx> +#include <KernelKit/HardwareThreadScheduler.hxx> #include <KernelKit/Heap.hxx> #include <NewKit/String.hxx> #include <KernelKit/LPC.hxx> @@ -19,7 +22,7 @@ ///! BUGS: 0 /***********************************************************************************/ -/* TODO: Document more the Kernel, sdk and kits. */ +/** TODO: Document the Kernel, SDK and kits. */ /***********************************************************************************/ namespace Kernel @@ -28,10 +31,10 @@ namespace Kernel /// @brief Exit Code global variable. /***********************************************************************************/ - UInt32 cLastExitCode = 0U; + STATIC UInt32 cLastExitCode = 0U; /***********************************************************************************/ - /// @brief UserProcess scheduler instance. + /// @brief User Process scheduler global object. /***********************************************************************************/ UserProcessScheduler* cProcessScheduler = nullptr; @@ -53,11 +56,9 @@ namespace Kernel if (this->Name == 0) return; - kcout << this->Name << ": crashed. (id = " << number(kErrorProcessFault) << endl; + kcout << this->Name << ": crashed, ID = " << number(kErrorProcessFault) << endl; this->Exit(kErrorProcessFault); - - UserProcessHelper::StartScheduling(); } /// @brief Gets the local last exit code. @@ -85,27 +86,45 @@ namespace Kernel /***********************************************************************************/ + /** @brief Add pointer to entry. */ VoidPtr UserProcess::New(const SizeT& sz) { - if (this->HeapCursor) +#ifdef __ZKA_AMD64__ + auto pd = hal_read_cr3(); + hal_write_cr3(this->MemoryPD); + + auto ptr = mm_new_ke_heap(sz, Yes, Yes); + + hal_write_cr3(reinterpret_cast<UIntPtr>(pd)); +#else + auto ptr = mm_new_ke_heap(sz, Yes, Yes); +#endif + + if (!this->MemoryEntryList) { - if (this->FreeMemory < 1) - { - ErrLocal() = kErrorHeapOutOfMemory; + this->MemoryEntryList = new UserProcess::PROCESS_MEMORY_ENTRY(); + this->MemoryEntryList->MemoryEntry = ptr; - /* We're going out of memory! crash... */ - this->Crash(); + this->MemoryEntryList->MemoryPrev = nullptr; + this->MemoryEntryList->MemoryNext = nullptr; - return nullptr; - } + return ptr; + } + else + { + auto entry = this->MemoryEntryList; - this->HeapCursor = reinterpret_cast<VoidPtr>((UIntPtr)this->HeapCursor + (sizeof(sz))); - VoidPtr cursor = this->HeapCursor; + while (entry->MemoryNext) + { + if (entry->MemoryNext) + entry = entry->MemoryNext; + } - ++this->UsedMemory; - --this->FreeMemory; + entry->MemoryNext = new UserProcess::PROCESS_MEMORY_ENTRY(); + entry->MemoryNext->MemoryEntry = ptr; - return cursor; + entry->MemoryNext->MemoryPrev = entry; + entry->MemoryNext->MemoryNext = nullptr; } return nullptr; @@ -113,39 +132,31 @@ namespace Kernel /***********************************************************************************/ - /* @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. */ + /** @brief Free pointer from usage. */ Boolean UserProcess::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; + auto entry = this->MemoryEntryList; - if (rt_is_in_pool(ptr, this->HeapCursor, this->UsedMemory, this->FreeMemory)) + while (entry->MemoryNext) { - this->HeapCursor = (VoidPtr)((UIntPtr)this->HeapCursor - (sizeof(sz))); - rt_zero_memory(ptr, sz); + if (entry->MemoryEntry == ptr) + { +#ifdef __ZKA_AMD64__ + auto pd = hal_read_cr3(); + hal_write_cr3(this->MemoryPD); + + bool ret = mm_delete_ke_heap(ptr); + hal_write_cr3(reinterpret_cast<UIntPtr>(pd)); - ++this->FreeMemory; - --this->UsedMemory; + return ret; +#else + bool ret = mm_delete_ke_heap(ptr); + return ret; +#endif + } - return true; + if (entry->MemoryNext) + entry = entry->MemoryNext; } return false; @@ -185,7 +196,7 @@ namespace Kernel void UserProcess::Exit(const Int32& exit_code) { this->Status = ProcessStatusKind::kDead; - + fLastExitCode = exit_code; cLastExitCode = exit_code; @@ -213,7 +224,8 @@ namespace Kernel if (this->StackReserve) delete[] this->StackReserve; - cProcessScheduler->Remove(this->ProcessId); + if (this->ProcessId > 0) + UserProcessScheduler::The().Remove(this->ProcessId); } /// @brief Add process to list. @@ -221,46 +233,34 @@ namespace Kernel /// @return the process index inside the team. SizeT UserProcessScheduler::Add(UserProcess& process) { - if (!process.Image) - { - return -kErrorInvalidData; - } +#ifdef __ZKA_AMD64__ + process.MemoryPD = reinterpret_cast<UIntPtr>(hal_read_cr3()); +#endif // __ZKA_AMD64__ - kcout << "UserProcessScheduler: Adding process to team...\r"; + process.StackFrame = (HAL::StackFrame*)process.New(sizeof(HAL::StackFrame)); - // Create heap according to type of process. - if (process.Kind == UserProcess::kExeKind) - { - process.HeapPtr = mm_new_ke_heap(process.SizeMemory, true, true); - } - else if (process.Kind == UserProcess::kDLLKind) + if (!process.StackFrame) { - process.DLLPtr = rtl_init_shared_object(&process); - process.HeapPtr = mm_new_ke_heap(process.SizeMemory, true, true); - } - else - { - // Something went wrong, do not continue, process may be incorrect. process.Crash(); return -kErrorProcessFault; } - process.StackFrame = new HAL::StackFrame(); - - MUST_PASS(process.StackFrame); + // Create heap according to type of process. + if (process.Kind == UserProcess::kDLLKind) + { + process.DLLPtr = rtl_init_shared_object(&process); + } if (process.Image) { // get preferred stack size by app. const auto cMaxStackSize = process.StackSize; + process.StackReserve = (UInt8*)process.New(sizeof(UInt8) * cMaxStackSize); - process.StackReserve = (UInt8*)mm_new_ke_heap(cMaxStackSize, Yes, Yes); - - // if stack pointer isn't valid. - if (!process.StackReserve) + if (process.StackReserve) { - process.StackReserve = (UInt8*)mm_new_ke_heap(kSchedMaxStackSz, Yes, Yes); - kcout << "newoskrnl.exe: Use fallback reserve size.\r"; + process.Crash(); + return -kErrorProcessFault; } } else @@ -272,18 +272,16 @@ namespace Kernel } } - process.Status = ProcessStatusKind::kStarting; - + process.Status = ProcessStatusKind::kStarting; process.ProcessId = mTeam.mProcessAmount; ++mTeam.mProcessAmount; - process.HeapCursor = process.HeapPtr; + while (1) + ; mTeam.AsArray()[process.ProcessId] = process; - kcout << "UserProcessScheduler: Adding process to team [ OK ]...\r"; - return process.ProcessId; } @@ -298,22 +296,16 @@ namespace Kernel /***********************************************************************************/ /// @brief Remove process from list. - /// @param processSlot process slot inside team. + /// @param process_id process slot inside team. /// @retval true process was removed. /// @retval false process doesn't exist in team. - Bool UserProcessScheduler::Remove(ProcessID processSlot) + Bool UserProcessScheduler::Remove(ProcessID process_id) { // check if process is within range. - if (processSlot > mTeam.AsArray().Count()) + if (process_id > mTeam.AsArray().Count()) return false; - // also check if the process isn't a dummy one. - if (mTeam.AsArray()[processSlot].Image == nullptr) - return false; - - kcout << "UserProcessScheduler: Removing process...\r"; - - mTeam.AsArray()[processSlot].Status = ProcessStatusKind::kDead; + mTeam.AsArray()[process_id].Status = ProcessStatusKind::kDead; --mTeam.mProcessAmount; return true; @@ -334,7 +326,7 @@ namespace Kernel if (UserProcessHelper::CanBeScheduled(process)) { // set the current process. - mTeam.AsRef() = process; + mTeam.AsRef() = mTeam.AsArray()[process.ProcessId]; process.PTime = static_cast<Int32>(process.Affinity); @@ -342,7 +334,7 @@ namespace Kernel // tell helper to find a core to schedule on. if (!UserProcessHelper::Switch(process.Image, &process.StackReserve[process.StackSize], process.StackFrame, - process.ProcessId)) + process.ProcessId)) { process.Crash(); continue; @@ -386,6 +378,16 @@ namespace Kernel return cProcessScheduler->CurrentProcess().Leak().ProcessId; } + Void UserProcessHelper::Init() + { + if (mm_is_valid_heap(cProcessScheduler)) + delete cProcessScheduler; + + cProcessScheduler = nullptr; + cProcessScheduler = new UserProcessScheduler(); + MUST_PASS(cProcessScheduler); + } + /// @brief Check if process can be schedulded. /// @param process the process reference. /// @retval true can be schedulded. @@ -401,7 +403,7 @@ namespace Kernel if (auto start = process.DLLPtr->Load<VoidPtr>(kPefStart, rt_string_len(kPefStart), kPefCode); start) { - process.Image = start; + process.Image = start; } } @@ -414,14 +416,6 @@ namespace Kernel SizeT UserProcessHelper::StartScheduling() { - if (!cProcessScheduler) - { - cProcessScheduler = new UserProcessScheduler(); - MUST_PASS(cProcessScheduler); - - kcout << "newoskrnl.exe: Team capacity: " << number(cProcessScheduler->CurrentTeam().AsArray().Capacity()) << endl; - } - SizeT ret = cProcessScheduler->Run(); return ret; } @@ -437,8 +431,6 @@ namespace Kernel if (!stack || !frame_ptr || !image_ptr || new_pid < 0) return false; - kcout << "newoskrnl.exe: Finding hardware thread...\r"; - for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Count(); ++index) { if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kInvalidHart) @@ -452,17 +444,16 @@ namespace Kernel HardwareThreadScheduler::The()[index].Leak()->Kind() != ThreadKind::kHartSystemReserved) { - HardwareThreadScheduler::The()[index].Leak()->Busy(true); - + PID prev_pid = UserProcessHelper::TheCurrentPID(); UserProcessHelper::TheCurrentPID() = new_pid; - kcout << "newoskrnl.exe: Found hardware thread...\r"; - bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(image_ptr, stack, frame_ptr); - HardwareThreadScheduler::The()[index].Leak()->Busy(false); - - return ret; + if (!ret) + { + UserProcessHelper::TheCurrentPID() = prev_pid; + continue; + } } } |
