summaryrefslogtreecommitdiffhomepage
path: root/Private/KernelKit/ProcessScheduler.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'Private/KernelKit/ProcessScheduler.hpp')
-rw-r--r--Private/KernelKit/ProcessScheduler.hpp493
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>