From 2c4b02249ec4355a73b826909ab1889e45871faf Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sat, 31 Aug 2024 10:47:14 +0200 Subject: Saving progress on User scheduler implementation. + Working on RISC-V, ARM64, POWER64 HALs, to be able to distribute mulitple versions of the product. Signed-off-by: Amlal El Mahrouss --- dev/ZKA/KernelKit/CodeManager.hxx | 4 +- dev/ZKA/KernelKit/DriveManager.hxx | 2 +- dev/ZKA/KernelKit/Heap.hxx | 8 +- dev/ZKA/KernelKit/LPC.hxx | 8 +- dev/ZKA/KernelKit/MP.hxx | 8 +- dev/ZKA/KernelKit/PEFDLLInterface.hxx | 4 +- dev/ZKA/KernelKit/ProcessScheduler.hxx | 303 ---------------------------- dev/ZKA/KernelKit/Semaphore.hxx | 10 +- dev/ZKA/KernelKit/ThreadLocalStorage.hxx | 14 +- dev/ZKA/KernelKit/ThreadLocalStorage.inl | 6 +- dev/ZKA/KernelKit/User.hxx | 5 +- dev/ZKA/KernelKit/UserProcessScheduler.hxx | 306 +++++++++++++++++++++++++++++ 12 files changed, 339 insertions(+), 339 deletions(-) delete mode 100644 dev/ZKA/KernelKit/ProcessScheduler.hxx create mode 100644 dev/ZKA/KernelKit/UserProcessScheduler.hxx (limited to 'dev/ZKA/KernelKit') diff --git a/dev/ZKA/KernelKit/CodeManager.hxx b/dev/ZKA/KernelKit/CodeManager.hxx index 513e65b7..aa384123 100644 --- a/dev/ZKA/KernelKit/CodeManager.hxx +++ b/dev/ZKA/KernelKit/CodeManager.hxx @@ -23,8 +23,8 @@ namespace Kernel /// @brief Main process entrypoint. typedef void (*MainKind)(void); - /// @brief Executes a new process from a function. kernel code only. - /// @note This sets up a new stack, anything on the main function that calls the kernel will not be accessible. + /// @brief Executes a new process from a function. Kernel code only. + /// @note This sets up a new stack, anything on the main function that calls the Kernel will not be accessible. /// @param main the start of the process. /// @return if the process was started or not. bool execute_from_image(MainKind main, const Char* process_name) noexcept; diff --git a/dev/ZKA/KernelKit/DriveManager.hxx b/dev/ZKA/KernelKit/DriveManager.hxx index 04a0ded5..9d90a42c 100644 --- a/dev/ZKA/KernelKit/DriveManager.hxx +++ b/dev/ZKA/KernelKit/DriveManager.hxx @@ -7,7 +7,7 @@ #ifndef __INC_DRIVE_MANAGER_HXX__ #define __INC_DRIVE_MANAGER_HXX__ -#include +#include #include #include #include diff --git a/dev/ZKA/KernelKit/Heap.hxx b/dev/ZKA/KernelKit/Heap.hxx index 0046fc58..5ce5a293 100644 --- a/dev/ZKA/KernelKit/Heap.hxx +++ b/dev/ZKA/KernelKit/Heap.hxx @@ -9,7 +9,7 @@ // last-rev 30/01/24 // file: KernelHeap.hxx -// description: heap allocation for the kernel. +// description: heap allocation for the Kernel. #include @@ -25,7 +25,7 @@ namespace Kernel /// @return voidPtr mm_realloc_ke_heap(voidPtr allocatedPtr, SizeT newSz); - /// @brief Check if pointer is a valid kernel pointer. + /// @brief Check if pointer is a valid Kernel pointer. /// @param allocatedPtr the pointer /// @return if it exists. Boolean mm_is_valid_heap(VoidPtr allocatedPtr); @@ -35,14 +35,14 @@ namespace Kernel /// @param rw read write (true to enable it) /// @param user is it accesible by user processes? /// @return The newly allocated pointer. - voidPtr mm_new_ke_heap(const SizeT sz, const Bool rw, const Bool user); + VoidPtr mm_new_ke_heap(const SizeT sz, const Bool rw, const Bool user); /// @brief Protect the heap with a CRC value. /// @param allocatedPtr pointer. /// @return if it valid: point has crc now., otherwise fail. Boolean mm_protect_ke_heap(VoidPtr allocatedPtr); - /// @brief Makes a kernel heap page. + /// @brief Makes a Kernel page. /// @param allocatedPtr the page pointer. /// @return Int32 mm_make_ke_page(VoidPtr allocatedPtr); diff --git a/dev/ZKA/KernelKit/LPC.hxx b/dev/ZKA/KernelKit/LPC.hxx index 152e7295..746f0d2a 100644 --- a/dev/ZKA/KernelKit/LPC.hxx +++ b/dev/ZKA/KernelKit/LPC.hxx @@ -9,11 +9,11 @@ #include /// @file LPC.hxx -/// @brief Local Process Codes. +/// @brief Local UserProcess Codes. -#define ErrLocalIsOk() (Kernel::ProcessScheduler::The().CurrentProcess().Leak().GetLocalCode() == Kernel::kErrorSuccess) -#define ErrLocalFailed() (Kernel::ProcessScheduler::The().CurrentProcess().Leak().GetLocalCode() != Kernel::kErrorSuccess) -#define ErrLocal() Kernel::ProcessScheduler::The().CurrentProcess().Leak().GetLocalCode() +#define ErrLocalIsOk() (Kernel::UserProcessScheduler::The().CurrentProcess().Leak().GetLocalCode() == Kernel::kErrorSuccess) +#define ErrLocalFailed() (Kernel::UserProcessScheduler::The().CurrentProcess().Leak().GetLocalCode() != Kernel::kErrorSuccess) +#define ErrLocal() Kernel::UserProcessScheduler::The().CurrentProcess().Leak().GetLocalCode() namespace Kernel { diff --git a/dev/ZKA/KernelKit/MP.hxx b/dev/ZKA/KernelKit/MP.hxx index d2704b23..03b8b6fa 100644 --- a/dev/ZKA/KernelKit/MP.hxx +++ b/dev/ZKA/KernelKit/MP.hxx @@ -26,9 +26,9 @@ namespace Kernel enum ThreadKind { kHartSystemReserved, // System reserved thread, well user can't use it - kHartStandard, // user thread, cannot be used by kernel + kHartStandard, // user thread, cannot be used by Kernel kHartFallback, // fallback thread, cannot be used by user if not clear or - // used by kernel. + // used by Kernel. kHartBoot, // The core we booted from, the mama. kInvalidHart, kHartCount, @@ -70,7 +70,7 @@ namespace Kernel private: HAL::StackFrame* fStack{nullptr}; - ThreadKind fKind{ThreadKind::kInvalidHart}; + ThreadKind fKind{ThreadKind::kHartStandard}; ThreadID fID{0}; ProcessID fSourcePID{-1}; bool fWakeup{false}; @@ -106,7 +106,7 @@ namespace Kernel public: /// @brief Shared instance of the MP Manager. /// @return the reference to the mp manager class. - static Ref The(); + STATIC HardwareThreadScheduler& The(); public: /// @brief Returns the amount of threads present in the system. diff --git a/dev/ZKA/KernelKit/PEFDLLInterface.hxx b/dev/ZKA/KernelKit/PEFDLLInterface.hxx index 3c0187f1..cfedd07c 100644 --- a/dev/ZKA/KernelKit/PEFDLLInterface.hxx +++ b/dev/ZKA/KernelKit/PEFDLLInterface.hxx @@ -98,8 +98,8 @@ namespace Kernel typedef PEFDLLInterface* DLLInterfacePtr; - EXTERN_C DLLInterfacePtr rtl_init_shared_object(PROCESS_HEADER_BLOCK* header); - EXTERN_C Void rtl_fini_shared_object(PROCESS_HEADER_BLOCK* header, DLLInterfacePtr lib, Bool* successful); + EXTERN_C DLLInterfacePtr rtl_init_shared_object(UserProcess* header); + EXTERN_C Void rtl_fini_shared_object(UserProcess* header, DLLInterfacePtr lib, Bool* successful); } // namespace Kernel #endif /* ifndef __KERNELKIT_SHARED_OBJECT_HXX__ */ diff --git a/dev/ZKA/KernelKit/ProcessScheduler.hxx b/dev/ZKA/KernelKit/ProcessScheduler.hxx deleted file mode 100644 index 5534c591..00000000 --- a/dev/ZKA/KernelKit/ProcessScheduler.hxx +++ /dev/null @@ -1,303 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Technologies. - -------------------------------------------- */ - -#ifndef _INC_PROCESS_SCHEDULER_HXX_ -#define _INC_PROCESS_SCHEDULER_HXX_ - -#include -#include -#include -#include - -#define kSchedMinMicroTime (AffinityKind::kStandard) -#define kSchedInvalidPID (-1) - -#define kSchedProcessLimitPerTeam (16U) - -//////////////////////////////////////////////////// - -// LAST REV: Mon Feb 12 13:52:01 CET 2024 - -//////////////////////////////////////////////////// - -namespace Kernel -{ - //! @brief Forward declarations. - struct PROCESS_HEADER_BLOCK; - - class PEFDLLInterface; - class ProcessTeam; - class ProcessScheduler; - class ProcessHelper; - - //! @brief Process identifier. - typedef Int64 ProcessID; - - //! @brief Process name length. - inline constexpr SizeT kProcessLen = 256U; - - //! @brief Process status enum. - enum class ProcessStatus : Int32 - { - kStarting, - kRunning, - kKilled, - kFrozen, - kDead - }; - - //! @brief Affinity is the amount of nano-seconds this process is going - //! to run. - enum class AffinityKind : Int32 - { - kInvalid = 300, - kVeryHigh = 250, - kHigh = 200, - kStandard = 150, - kLowUsage = 100, - kVeryLowUsage = 50, - }; - - // operator overloading. - - inline bool operator<(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int < rhs_int; - } - - inline bool operator>(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int > rhs_int; - } - - inline bool operator<=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int <= rhs_int; - } - - inline bool operator>=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int >= rhs_int; - } - - // end of operator overloading. - - enum ProcessSubsystemEnum - { - eProcessSubsystemSecurity, - eProcessSubsystemNative, - eProcessSubsystemInvalid, - eProcessSubsystemCount, - }; - - using ProcessSubsystem = ProcessSubsystemEnum; - using ProcessTime = UInt64; - using PID = Int64; - - // for permission manager, tells where we run the code. - enum class ProcessLevelRing : Int32 - { - kRingStdUser = 1, - kRingSuperUser = 2, - kRingGuestUser = 5, - kRingCount = 5, - }; - - // Helper types. - using ImagePtr = VoidPtr; - using HeapPtrKind = VoidPtr; - - /// @name PROCESS_HEADER_BLOCK - /// @brief Process Header Block (PHB). - /// Holds information about the running process/thread. - struct PROCESS_HEADER_BLOCK final - { - public: - explicit PROCESS_HEADER_BLOCK(VoidPtr startImage = nullptr) - : Image(startImage) - { - } - - ~PROCESS_HEADER_BLOCK() = default; - - ZKA_COPY_DEFAULT(PROCESS_HEADER_BLOCK) - - public: - void SetEntrypoint(UIntPtr& imageStart) noexcept; - const UInt32& GetExitCode() noexcept; - - public: - Char Name[kProcessLen] = {"PROCESS #0 (TEAM 0)"}; - ProcessSubsystem SubSystem{ProcessSubsystem::eProcessSubsystemInvalid}; - User* AssignedOwner{nullptr}; - HAL::StackFramePtr StackFrame{nullptr}; - AffinityKind Affinity{AffinityKind::kStandard}; - ProcessStatus Status{ProcessStatus::kDead}; - - // Memory, images pointers. - HeapPtrKind HeapCursor{nullptr}; - ImagePtr Image{nullptr}; - HeapPtrKind HeapPtr{nullptr}; - - // shared library handle, reserved for kSharedObjectKind types of executables only. - PEFDLLInterface* DLLPtr{nullptr}; - PROCESS_HEADER_BLOCK* Parent{nullptr}; - - // Memory usage. - SizeT UsedMemory{0}; - SizeT FreeMemory{0}; - SizeT SizeMemory{gib_cast(4)}; - - enum - { - kExeKind = 1, - kSharedObjectKind = 2, - kKindCount, - }; - - ProcessTime PTime{0}; - PID ProcessId{kSchedInvalidPID}; - Int32 Kind{kExeKind}; - - public: - //! @brief boolean operator, check status. - operator bool() - { - return Status != ProcessStatus::kDead; - } - - ///! @brief Crashes the app, exits with code ~0. - Void Crash(); - - ///! @brief Exits the app. - Void Exit(const Int32& exit_code = 0); - - ///! @brief TLS allocate. - ///! @param sz size of new ptr. - VoidPtr New(const SizeT& sz); - - ///! @brief TLS free. - ///! @param ptr the pointer to free. - ///! @param sz the size of it. - Boolean Delete(VoidPtr ptr, const SizeT& sz); - - ///! @brief Wakes up threads. - Void Wake(const bool wakeup = false); - - // PROCESS_HEADER_BLOCK getters. - public: - ///! @brief Get the process's name - ///! @example 'C Runtime Library' - const Char* GetProcessName() noexcept; - - //! @brief return local error code of process. - //! @return Int32 local error code. - Int32& GetLocalCode() noexcept; - - const User* GetOwner() noexcept; - const ProcessStatus& GetStatus() noexcept; - const AffinityKind& GetAffinity() noexcept; - - private: - UInt32 fLastExitCode{0}; - Int32 fLocalCode{0}; - - friend ProcessScheduler; - friend ProcessHelper; - }; - - /// \brief Processs Team (contains multiple processes inside it.) - /// Equivalent to a process batch - class ProcessTeam final - { - public: - explicit ProcessTeam() = default; - ~ProcessTeam() = default; - - ZKA_COPY_DEFAULT(ProcessTeam); - - Array& AsArray(); - Ref& AsRef(); - ProcessID& Id() noexcept; - - public: - Array mProcessList; - Ref mCurrentProcess; - SizeT mProcessAmount{0}; - ProcessID mTeamId{0}; - }; - - using PROCESS_HEADER_BLOCK_PTR = PROCESS_HEADER_BLOCK*; - - /// @brief PROCESS_HEADER_BLOCK manager class. - /// The main class which you call to schedule an app. - class ProcessScheduler final - { - public: - explicit ProcessScheduler() = default; - - ~ProcessScheduler() = default; - - ZKA_COPY_DEFAULT(ProcessScheduler) - - operator bool(); - bool operator!(); - - public: - ProcessTeam& CurrentTeam(); - - public: - SizeT Add(PROCESS_HEADER_BLOCK& processRef); - Bool Remove(ProcessID processSlot); - - public: - Ref& CurrentProcess(); - SizeT Run() noexcept; - - public: - STATIC ProcessScheduler& The(); - - private: - ProcessTeam mTeam; - }; - - /* - * \brief Process helper class, which contains needed utilities for the scheduler. - */ - - class ProcessHelper final - { - public: - STATIC bool Switch(HAL::StackFramePtr new_stack, const PID& new_pid); - STATIC bool CanBeScheduled(PROCESS_HEADER_BLOCK& process); - STATIC PID& TheCurrentPID(); - STATIC SizeT StartScheduling(); - }; - - const UInt32& sched_get_exit_code(void) noexcept; -} // namespace Kernel - -#include - -//////////////////////////////////////////////////// - -// END - -//////////////////////////////////////////////////// - -#endif /* ifndef _INC_PROCESS_SCHEDULER_HXX_ */ diff --git a/dev/ZKA/KernelKit/Semaphore.hxx b/dev/ZKA/KernelKit/Semaphore.hxx index 685b00a3..74c5f8da 100644 --- a/dev/ZKA/KernelKit/Semaphore.hxx +++ b/dev/ZKA/KernelKit/Semaphore.hxx @@ -12,9 +12,9 @@ namespace Kernel { - class PROCESS_HEADER_BLOCK; + class UserProcess; - typedef PROCESS_HEADER_BLOCK* PROCESS_HEADER_BLOCK_PTR; + typedef UserProcess* UserProcessPtr; /// @brief Access control class, which locks a task until one is done. class Semaphore final @@ -31,13 +31,13 @@ namespace Kernel void WaitForProcess() noexcept; public: - bool Lock(PROCESS_HEADER_BLOCK* process); - bool LockOrWait(PROCESS_HEADER_BLOCK* process, TimerInterface* timer); + bool Lock(UserProcess* process); + bool LockOrWait(UserProcess* process, TimerInterface* timer); public: ZKA_COPY_DEFAULT(Semaphore); private: - PROCESS_HEADER_BLOCK_PTR fLockingProcess{nullptr}; + UserProcessPtr fLockingProcess{nullptr}; }; } // namespace Kernel diff --git a/dev/ZKA/KernelKit/ThreadLocalStorage.hxx b/dev/ZKA/KernelKit/ThreadLocalStorage.hxx index 115a4ca1..c7803d69 100644 --- a/dev/ZKA/KernelKit/ThreadLocalStorage.hxx +++ b/dev/ZKA/KernelKit/ThreadLocalStorage.hxx @@ -9,11 +9,11 @@ #include -//! @brief TLS implementation in C++ +///! @brief Thread Local Storage for newoskrnl. -#define kCookieMag0 'H' -#define kCookieMag1 'C' -#define kCookieMag2 'R' +#define kCookieMag0 'Z' +#define kCookieMag1 'K' +#define kCookieMag2 'A' #define kTLSCookieLen (3U) @@ -23,8 +23,8 @@ struct THREAD_INFORMATION_BLOCK; /// Located in GS on AMD64, other architectures have their own stuff. (64x0, 32x0, ARM64) struct PACKED THREAD_INFORMATION_BLOCK final { - Kernel::Char f_Cookie[kTLSCookieLen]{0}; // Thread magic number. - Kernel::VoidPtr f_ThreadRecord{nullptr}; + Kernel::Char f_Cookie[kTLSCookieLen]{0}; //! Thread magic number. + Kernel::VoidPtr f_ThreadRecord{nullptr}; //! Thread information record. }; ///! @brief Cookie Sanity check. @@ -42,7 +42,7 @@ template T* tls_new_class(Args&&... args); /// @brief TLS install TIB and PIB. (syscall) -EXTERN_C void rt_install_tib(THREAD_INFORMATION_BLOCK* TIB, THREAD_INFORMATION_BLOCK* PIB); +EXTERN_C Kernel::Void rt_install_tib(THREAD_INFORMATION_BLOCK* TIB, THREAD_INFORMATION_BLOCK* PIB); /// @brief TLS check (syscall) EXTERN_C Kernel::Bool tls_check_syscall_impl(Kernel::VoidPtr TIB) noexcept; diff --git a/dev/ZKA/KernelKit/ThreadLocalStorage.inl b/dev/ZKA/KernelKit/ThreadLocalStorage.inl index 97480bdd..7a1ef247 100644 --- a/dev/ZKA/KernelKit/ThreadLocalStorage.inl +++ b/dev/ZKA/KernelKit/ThreadLocalStorage.inl @@ -8,7 +8,7 @@ //! @brief Allocate resources from the process's heap storage. #ifndef _INC_PROCESS_SCHEDULER_HXX_ -#include +#include #endif template @@ -16,7 +16,7 @@ inline T* tls_new_ptr(void) noexcept { using namespace Kernel; - auto ref_process = ProcessScheduler::The().CurrentProcess(); + auto ref_process = UserProcessScheduler::The().CurrentProcess(); MUST_PASS(ref_process); T* pointer = (T*)ref_process.Leak().New(sizeof(T)); @@ -32,7 +32,7 @@ inline Kernel::Bool tls_delete_ptr(T* ptr) noexcept using namespace Kernel; - auto ref_process = ProcessScheduler::The().CurrentProcess(); + auto ref_process = UserProcessScheduler::The().CurrentProcess(); MUST_PASS(ref_process); return ref_process.Leak().Delete(ptr, sizeof(T)); diff --git a/dev/ZKA/KernelKit/User.hxx b/dev/ZKA/KernelKit/User.hxx index 39d9f5ba..36353ed0 100644 --- a/dev/ZKA/KernelKit/User.hxx +++ b/dev/ZKA/KernelKit/User.hxx @@ -22,9 +22,6 @@ #define kMaxUserNameLen (255) #define kMaxUserTokenLen (255) -// hash password. -// use this data to then fetch specific data of the user.. - namespace Kernel { class User; @@ -34,7 +31,7 @@ namespace Kernel kRingStdUser = 1, kRingSuperUser = 2, kRingGuestUser = 5, - kRingCount = 5, + kRingCount = 3, }; class User final diff --git a/dev/ZKA/KernelKit/UserProcessScheduler.hxx b/dev/ZKA/KernelKit/UserProcessScheduler.hxx new file mode 100644 index 00000000..f0c19423 --- /dev/null +++ b/dev/ZKA/KernelKit/UserProcessScheduler.hxx @@ -0,0 +1,306 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#ifndef _INC_PROCESS_SCHEDULER_HXX_ +#define _INC_PROCESS_SCHEDULER_HXX_ + +#include +#include +#include +#include + +#define kSchedMinMicroTime (AffinityKind::kStandard) +#define kSchedInvalidPID (-1) +#define cMaxStackSz (4096) /* Max stack sz */ +#define kSchedProcessLimitPerTeam (16U) + +//////////////////////////////////////////////////// + +// LAST REV: Mon Feb 12 13:52:01 CET 2024 + +//////////////////////////////////////////////////// + +namespace Kernel +{ + //! @brief Forward declarations. + struct UserProcess; + + class PEFDLLInterface; + class ProcessTeam; + class UserProcessScheduler; + class ProcessHelper; + + //! @brief UserProcess identifier. + typedef Int64 ProcessID; + + //! @brief UserProcess name length. + inline constexpr SizeT kProcessLen = 256U; + + //! @brief UserProcess status enum. + enum class ProcessStatus : Int32 + { + kStarting, + kRunning, + kKilled, + kFrozen, + kDead + }; + + //! @brief Affinity is the amount of nano-seconds this process is going + //! to run. + enum class AffinityKind : Int32 + { + kRealTime = 0000, + kVeryHigh = 2500, + kHigh = 2000, + kStandard = 1500, + kLowUsage = 1000, + kVeryLowUsage = 5000, + }; + + // operator overloading. + + inline bool operator<(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int < rhs_int; + } + + inline bool operator>(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int > rhs_int; + } + + inline bool operator<=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int <= rhs_int; + } + + inline bool operator>=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int >= rhs_int; + } + + // end of operator overloading. + + enum ProcessSubsystemEnum + { + eProcessSubsystemSecurity, + eProcessSubsystemNative, + eProcessSubsystemInvalid, + eProcessSubsystemCount, + }; + + using ProcessSubsystem = ProcessSubsystemEnum; + using ProcessTime = UInt64; + using PID = Int64; + + // for permission manager, tells where we run the code. + enum class ProcessLevelRing : Int32 + { + kRingStdUser = 1, + kRingSuperUser = 2, + kRingGuestUser = 5, + kRingCount = 5, + }; + + // Helper types. + using ImagePtr = VoidPtr; + using HeapPtrKind = VoidPtr; + + /// @name UserProcess + /// @brief User process block. + /// Holds information about the running process/thread. + struct UserProcess final + { + public: + explicit UserProcess(VoidPtr startImage = nullptr) + : Image(startImage) + { + } + + ~UserProcess() = default; + + ZKA_COPY_DEFAULT(UserProcess) + + public: + void SetEntrypoint(UIntPtr& imageStart) noexcept; + const UInt32& GetExitCode() noexcept; + + public: + Char Name[kProcessLen] = {"PROCESS #0 (TEAM 0)"}; + ProcessSubsystem SubSystem{ProcessSubsystem::eProcessSubsystemInvalid}; + User* Owner{nullptr}; + HAL::StackFramePtr StackFrame{nullptr}; + AffinityKind Affinity{AffinityKind::kStandard}; + ProcessStatus Status{ProcessStatus::kDead}; + UInt8* StackReserve{ nullptr }; + + // Memory, images pointers. + HeapPtrKind HeapCursor{nullptr}; + ImagePtr Image{nullptr}; + HeapPtrKind HeapPtr{nullptr}; + + SizeT StackSize{mib_cast(8)}; + + // shared library handle, reserved for kDLLKind types of executables only. + PEFDLLInterface* DLLPtr{nullptr}; + UserProcess* Parent{nullptr}; + + // Memory usage. + SizeT UsedMemory{0}; + SizeT FreeMemory{0}; + SizeT SizeMemory{gib_cast(4)}; + + enum + { + kExeKind = 1, + kDLLKind = 2, + kKindCount, + }; + + ProcessTime PTime{0}; + PID ProcessId{kSchedInvalidPID}; + Int32 Kind{kExeKind}; + + public: + //! @brief boolean operator, check status. + operator bool() + { + return Status != ProcessStatus::kDead; + } + + ///! @brief Crashes the app, exits with code ~0. + Void Crash(); + + ///! @brief Exits the app. + Void Exit(const Int32& exit_code = 0); + + ///! @brief TLS allocate. + ///! @param sz size of new ptr. + VoidPtr New(const SizeT& sz); + + ///! @brief TLS free. + ///! @param ptr the pointer to free. + ///! @param sz the size of it. + Boolean Delete(VoidPtr ptr, const SizeT& sz); + + ///! @brief Wakes up threads. + Void Wake(const bool wakeup = false); + + // UserProcess getters. + public: + ///! @brief Get the process's name + ///! @example 'C Runtime Library' + const Char* GetProcessName() noexcept; + + //! @brief return local error code of process. + //! @return Int32 local error code. + Int32& GetLocalCode() noexcept; + + const User* GetOwner() noexcept; + const ProcessStatus& GetStatus() noexcept; + const AffinityKind& GetAffinity() noexcept; + + private: + UInt32 fLastExitCode{0}; + Int32 fLocalCode{0}; + + friend UserProcessScheduler; + friend ProcessHelper; + }; + + /// \brief Processs Team (contains multiple processes inside it.) + /// Equivalent to a process batch + class ProcessTeam final + { + public: + explicit ProcessTeam() = default; + ~ProcessTeam() = default; + + ZKA_COPY_DEFAULT(ProcessTeam); + + Array& AsArray(); + Ref& AsRef(); + ProcessID& Id() noexcept; + + public: + Array mProcessList; + Ref mCurrentProcess; + SizeT mProcessAmount{0}; + ProcessID mTeamId{0}; + }; + + using UserProcessPtr = UserProcess*; + + /// @brief UserProcess scheduler class. + /// The main class which you call to schedule processes. + class UserProcessScheduler final + { + public: + explicit UserProcessScheduler() = default; + + ~UserProcessScheduler() = default; + + ZKA_COPY_DEFAULT(UserProcessScheduler) + + operator bool(); + bool operator!(); + + public: + ProcessTeam& CurrentTeam(); + + public: + SizeT Add(UserProcess& processRef); + Bool Remove(ProcessID processSlot); + + public: + Ref& CurrentProcess(); + SizeT Run() noexcept; + + public: + STATIC UserProcessScheduler& The(); + + private: + ProcessTeam mTeam; + }; + + /* + * \brief UserProcess helper class, which contains needed utilities for the scheduler. + */ + + class ProcessHelper final + { + public: + STATIC bool Switch(HAL::StackFramePtr new_stack, const PID& new_pid); + STATIC bool CanBeScheduled(UserProcess& process); + STATIC PID& TheCurrentPID(); + STATIC SizeT StartScheduling(); + }; + + const UInt32& sched_get_exit_code(void) noexcept; +} // namespace Kernel + +#include + +//////////////////////////////////////////////////// + +// END + +//////////////////////////////////////////////////// + +#endif /* ifndef _INC_PROCESS_SCHEDULER_HXX_ */ -- cgit v1.2.3