diff options
Diffstat (limited to 'Private/KernelKit/ProcessScheduler.hpp')
| -rw-r--r-- | Private/KernelKit/ProcessScheduler.hpp | 493 |
1 files changed, 261 insertions, 232 deletions
diff --git a/Private/KernelKit/ProcessScheduler.hpp b/Private/KernelKit/ProcessScheduler.hpp index 3c080b15..882aa7f0 100644 --- a/Private/KernelKit/ProcessScheduler.hpp +++ b/Private/KernelKit/ProcessScheduler.hpp @@ -15,7 +15,7 @@ #include <NewKit/MutableArray.hpp> #define kSchedMinMicroTime AffinityKind::kHartStandard -#define kSchedInvalidPID (-1) +#define kSchedInvalidPID (-1) #define kSchedProcessLimitPerTeam (100U) @@ -25,241 +25,270 @@ //////////////////////////////////////////////////// -namespace NewOS { -class ProcessHeader; -class ProcessTeam; -class ProcessScheduler; - -//! @brief Process identifier. -typedef Int64 ProcessID; - -//! @brief Process name length. -inline constexpr SizeT kProcessLen = 256U; - -//! @brief Forward declaration. -class ProcessHeader; -class ProcessScheduler; -class ProcessHelper; - -//! @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, - kHartStandard = 150, - kLowUsage = 100, - kVeryLowUsage = 50, -}; - -// operator overloading. - -inline bool operator<(AffinityKind lhs, AffinityKind rhs) { - Int32 lhs_int = static_cast<Int>(lhs); - Int32 rhs_int = static_cast<Int>(rhs); - - return lhs_int < rhs_int; -} - -inline bool operator>(AffinityKind lhs, AffinityKind rhs) { - Int32 lhs_int = static_cast<Int>(lhs); - Int32 rhs_int = static_cast<Int>(rhs); - - return lhs_int > rhs_int; -} - -inline bool operator<=(AffinityKind lhs, AffinityKind rhs) { - Int32 lhs_int = static_cast<Int>(lhs); - Int32 rhs_int = static_cast<Int>(rhs); - - return lhs_int <= rhs_int; -} - -inline bool operator>=(AffinityKind lhs, AffinityKind rhs) { - Int32 lhs_int = static_cast<Int>(lhs); - Int32 rhs_int = static_cast<Int>(rhs); - - return lhs_int >= rhs_int; -} - -// end of operator overloading. - -enum ProcessSubsystemEnum { - eProcessSubsystemLogin, - eProcessSubsystemNative, - eProcessSubsystemInvalid, - eProcessSubsystemCount, -}; - -using ProcessSubsystem = ProcessSubsystemEnum; -using ProcessTime = UInt64; -using PID = Int64; - -// for permission manager, tells where we run the code. -enum class ProcessSelector : Int { - kRingUser, /* user ring (or ring 3 in x86) */ - kRingDriver, /* ring 2 in x86, hypervisor privileges in other archs */ - kRingKernel, /* machine privileges */ -}; - -// Helper types. -using ImagePtr = VoidPtr; -using HeapPtr = VoidPtr; - -// @name ProcessHeader -// @brief Process Header (PH) -// Holds information about the running process. -// Thread execution is being abstracted away. -class ProcessHeader final { - public: - explicit ProcessHeader(VoidPtr startImage = nullptr) : Image(startImage) { - MUST_PASS(startImage); - } - - ~ProcessHeader() = default; - - NEWOS_COPY_DEFAULT(ProcessHeader) - - public: - void SetEntrypoint(UIntPtr &imageStart) noexcept; - - public: - Char Name[kProcessLen] = {"NewOS Process"}; - ProcessSubsystem SubSystem{ProcessSubsystem::eProcessSubsystemInvalid}; - ProcessSelector Selector{ProcessSelector::kRingUser}; - HAL::StackFramePtr StackFrame{nullptr}; - AffinityKind Affinity; - ProcessStatus Status; - - // Memory, images. - HeapPtr HeapCursor{nullptr}; - ImagePtr Image{nullptr}; - HeapPtr HeapPtr{nullptr}; - - // memory usage - SizeT UsedMemory{0}; - SizeT FreeMemory{0}; +namespace NewOS +{ + class ProcessHeader; + class ProcessTeam; + class ProcessScheduler; + + //! @brief Process identifier. + typedef Int64 ProcessID; + + //! @brief Process name length. + inline constexpr SizeT kProcessLen = 256U; + + //! @brief Forward declaration. + class ProcessHeader; + class ProcessScheduler; + class ProcessHelper; + + //! @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, + kHartStandard = 150, + kLowUsage = 100, + kVeryLowUsage = 50, + }; + + // operator overloading. + + inline bool operator<(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast<Int>(lhs); + Int32 rhs_int = static_cast<Int>(rhs); + + return lhs_int < rhs_int; + } + + inline bool operator>(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast<Int>(lhs); + Int32 rhs_int = static_cast<Int>(rhs); + + return lhs_int > rhs_int; + } + + inline bool operator<=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast<Int>(lhs); + Int32 rhs_int = static_cast<Int>(rhs); + + return lhs_int <= rhs_int; + } + + inline bool operator>=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast<Int>(lhs); + Int32 rhs_int = static_cast<Int>(rhs); + + return lhs_int >= rhs_int; + } + + // end of operator overloading. + + enum ProcessSubsystemEnum + { + eProcessSubsystemLogin, + eProcessSubsystemNative, + eProcessSubsystemInvalid, + eProcessSubsystemCount, + }; + + using ProcessSubsystem = ProcessSubsystemEnum; + using ProcessTime = UInt64; + using PID = Int64; + + // for permission manager, tells where we run the code. + enum class ProcessSelector : Int + { + kRingUser, /* user ring (or ring 3 in x86) */ + kRingDriver, /* ring 2 in x86, hypervisor privileges in other archs */ + kRingKernel, /* machine privileges */ + }; + + // Helper types. + using ImagePtr = VoidPtr; + using HeapPtr = VoidPtr; + + // @name ProcessHeader + // @brief Process Header (PH) + // Holds information about the running process. + // Thread execution is being abstracted away. + class ProcessHeader final + { + public: + explicit ProcessHeader(VoidPtr startImage = nullptr) + : Image(startImage) + { + MUST_PASS(startImage); + } + + ~ProcessHeader() = default; + + NEWOS_COPY_DEFAULT(ProcessHeader) + + public: + void SetEntrypoint(UIntPtr& imageStart) noexcept; + + public: + Char Name[kProcessLen] = {"NewOS Process"}; + ProcessSubsystem SubSystem{ProcessSubsystem::eProcessSubsystemInvalid}; + ProcessSelector Selector{ProcessSelector::kRingUser}; + HAL::StackFramePtr StackFrame{nullptr}; + AffinityKind Affinity; + ProcessStatus Status; + + // Memory, images. + HeapPtr HeapCursor{nullptr}; + ImagePtr Image{nullptr}; + HeapPtr HeapPtr{nullptr}; + + // memory usage + SizeT UsedMemory{0}; + SizeT FreeMemory{0}; + + enum + { + kUserKind = 3, + kLibKind = 3, + kDriverKind = 0, + kKindCount, + }; + + enum + { + kRingUserKind = 3, + kRingDriverKind = 0, + }; + + ProcessTime PTime; + PID ProcessId{kSchedInvalidPID}; + Int32 Ring{kRingDriverKind}; + Int32 Kind{kUserKind}; + + public: + //! @brief boolean operator, check status. + operator bool() + { + return Status != ProcessStatus::kDead; + } + + //! @brief Crash the app, exits with code ~0. + void Crash(); + + //! @brief Exits app. + void Exit(Int32 exitCode = 0); + + //! @brief TLS Allocate + VoidPtr New(const SizeT& sz); + + //! @brief TLS Free. + Boolean Delete(VoidPtr ptr, const SizeT& sz); + + //! @brief Wakes up threads. + void Wake(const bool wakeup = false); + + // ProcessHeader getters. + public: + //! @brief ProcessHeader name getter, example: "C RunTime" + const Char* GetName(); + + const ProcessSelector& GetSelector(); + const ProcessStatus& GetStatus(); + const AffinityKind& GetAffinity(); + + private: + 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; + + NEWOS_COPY_DEFAULT(ProcessTeam); + + MutableArray<Ref<ProcessHeader>>& AsArray(); + Ref<ProcessHeader>& AsRef(); + + public: + MutableArray<Ref<ProcessHeader>> mProcessList; + Ref<ProcessHeader> mCurrentProcess; + }; + + using ProcessHeaderRef = ProcessHeader*; + + /// @brief ProcessHeader manager class. + /// The main class which you call to schedule an app. + class ProcessScheduler final + { + private: + explicit ProcessScheduler() = default; + + public: + ~ProcessScheduler() = default; + + NEWOS_COPY_DEFAULT(ProcessScheduler) + + operator bool() + { + return mTeam.AsArray().Count() > 0; + } + bool operator!() + { + return mTeam.AsArray().Count() == 0; + } + + ProcessTeam& CurrentTeam() + { + return mTeam; + } + + SizeT Add(Ref<ProcessHeader>& headerRef); + bool Remove(SizeT headerIndex); + + Ref<ProcessHeader>& GetCurrent(); + SizeT Run() noexcept; + + static Ref<ProcessScheduler> Shared(); + + private: + ProcessTeam mTeam; + }; - enum { - kUserKind = 3, - kLibKind = 3, - kDriverKind = 0, - kKindCount, - }; - - enum { - kRingUserKind = 3, - kRingDriverKind = 0, - }; - - ProcessTime PTime; - PID ProcessId{kSchedInvalidPID}; - Int32 Ring{kRingDriverKind}; - Int32 Kind{kUserKind}; - - public: - //! @brief boolean operator, check status. - operator bool() { return Status != ProcessStatus::kDead; } - - //! @brief Crash the app, exits with code ~0. - void Crash(); - - //! @brief Exits app. - void Exit(Int32 exitCode = 0); - - //! @brief TLS Allocate - VoidPtr New(const SizeT &sz); - - //! @brief TLS Free. - Boolean Delete(VoidPtr ptr, const SizeT &sz); - - //! @brief Wakes up threads. - void Wake(const bool wakeup = false); - - // ProcessHeader getters. - public: - //! @brief ProcessHeader name getter, example: "C RunTime" - const Char *GetName(); - - const ProcessSelector &GetSelector(); - const ProcessStatus &GetStatus(); - const AffinityKind &GetAffinity(); - - private: - 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; - - NEWOS_COPY_DEFAULT(ProcessTeam); - - MutableArray<Ref<ProcessHeader>> &AsArray(); - Ref<ProcessHeader> &AsRef(); - - public: - MutableArray<Ref<ProcessHeader>> mProcessList; - Ref<ProcessHeader> mCurrentProcess; -}; - -using ProcessHeaderRef = ProcessHeader *; - -/// @brief ProcessHeader manager class. -/// The main class which you call to schedule an app. -class ProcessScheduler final { - private: - explicit ProcessScheduler() = default; - - public: - ~ProcessScheduler() = default; - - NEWOS_COPY_DEFAULT(ProcessScheduler) - - operator bool() { return mTeam.AsArray().Count() > 0; } - bool operator!() { return mTeam.AsArray().Count() == 0; } - - ProcessTeam &CurrentTeam() { return mTeam; } - - SizeT Add(Ref<ProcessHeader> &headerRef); - bool Remove(SizeT headerIndex); - - Ref<ProcessHeader> &GetCurrent(); - SizeT Run() noexcept; - - static Ref<ProcessScheduler> Shared(); - - private: - ProcessTeam mTeam; -}; - -/* + /* * Just a helper class, which contains some utilities for the scheduler. */ -class ProcessHelper final { - public: - static bool Switch(HAL::StackFrame *newStack, const PID &newPid); - static bool CanBeScheduled(Ref<ProcessHeader> &process); - static PID &GetCurrentPID(); - static bool StartScheduling(); -}; - -const Int32 &rt_get_exit_code() noexcept; -} // namespace NewOS + class ProcessHelper final + { + public: + static bool Switch(HAL::StackFrame* newStack, const PID& newPid); + static bool CanBeScheduled(Ref<ProcessHeader>& process); + static PID& GetCurrentPID(); + static bool StartScheduling(); + }; + + const Int32& rt_get_exit_code() noexcept; +} // namespace NewOS #include <KernelKit/ThreadLocalStorage.hxx> |
