diff options
Diffstat (limited to 'src/kernel')
24 files changed, 140 insertions, 87 deletions
diff --git a/src/kernel/FSKit/OpenHeFS.h b/src/kernel/FSKit/OpenHeFS.h index a642c299..1e3c3921 100644 --- a/src/kernel/FSKit/OpenHeFS.h +++ b/src/kernel/FSKit/OpenHeFS.h @@ -8,7 +8,7 @@ #include <CompilerKit/CompilerKit.h> #include <KernelKit/DriveMgr.h> -#include <KernelKit/UserMgr+User.h> +#include <KernelKit/User.h> #include <NeKit/Config.h> #include <NeKit/Crc32.h> #include <NeKit/KString.h> diff --git a/src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cpp b/src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cpp index 92fb064c..118dd98c 100644 --- a/src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cpp +++ b/src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cpp @@ -5,7 +5,7 @@ #include <ArchKit/ArchKit.h> #include <KernelKit/ProcessScheduler.h> -#include <KernelKit/UserMgr+User.h> +#include <KernelKit/User.h> #include <NeKit/Atom.h> #include <NeKit/KString.h> #include <SignalKit/Signals.h> diff --git a/src/kernel/HALKit/AMD64/HalDebugOutput.cpp b/src/kernel/HALKit/AMD64/HalDebugOutput.cpp index a63b3657..dc4b78e7 100644 --- a/src/kernel/HALKit/AMD64/HalDebugOutput.cpp +++ b/src/kernel/HALKit/AMD64/HalDebugOutput.cpp @@ -59,7 +59,7 @@ namespace Detail { TerminalDevice::~TerminalDevice() = default; #ifdef __DEBUG__ -STATIC SizeT kX = kFontSizeX, kY = kFontSizeY; +STATIC SizeT kX = kFontSizeX, kY = kFontSizeY + 70; #endif // __DEBUG__ EXTERN_C void ke_utf_io_write(IDevice<const Utf8Char*>* obj, const Utf8Char* bytes) { @@ -91,7 +91,7 @@ EXTERN_C void ke_utf_io_write(IDevice<const Utf8Char*>* obj, const Utf8Char* byt tmp_str[0] = (bytes[index] > 127) ? '?' : bytes[index]; tmp_str[1] = 0; - cg_render_string(tmp_str, kY, kX, RGB(0x00, 0x00, 0x00)); + cg_render_string(tmp_str, kY, kX, RGB(0xFF, 0xFF, 0xFF)); if (bytes[index] == '\r') { kY += kFontSizeY; @@ -147,7 +147,7 @@ EXTERN_C void ke_io_write(IDevice<const Char*>* obj, const Char* bytes) { tmp_str[0] = bytes[index]; tmp_str[1] = 0; - cg_render_string(tmp_str, kY, kX, RGB(0x00, 0x00, 0x00)); + cg_render_string(tmp_str, kY, kX, RGB(0xFF, 0xFF, 0xFF)); if (bytes[index] == '\r') { kY += kFontSizeY; @@ -161,7 +161,7 @@ EXTERN_C void ke_io_write(IDevice<const Char*>* obj, const Char* bytes) { } if (kY > kHandoverHeader->f_GOP.f_Height) { - kY = kFontSizeY; + kY = kFontSizeY + 70; FBDrawInRegion(cg_get_clear_clr(), FB::CGAccessibilty::Height(), FB::CGAccessibilty::Width(), 0, 0); diff --git a/src/kernel/HALKit/AMD64/HalKernelMain.cpp b/src/kernel/HALKit/AMD64/HalKernelMain.cpp index fabeb077..4c527572 100644 --- a/src/kernel/HALKit/AMD64/HalKernelMain.cpp +++ b/src/kernel/HALKit/AMD64/HalKernelMain.cpp @@ -18,6 +18,9 @@ #include <modules/ACPI/ACPIFactoryInterface.h> #include <modules/CoreGfx/TextGfx.h> +#include <BootKit/Shared/BootImg.rsrc> +#include "NeKit/KernelPanic.h" + #ifndef __NE_MODULAR_KERNEL_COMPONENTS__ EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; @@ -154,6 +157,10 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) { NeFileSystemMgr::Mount(new NeFileSystemMgr()); #endif + cg_init(); + FBDrawBitMapInRegion(kBootLogo, BOOT_LOGO_WIDTH, BOOT_LOGO_HEIGHT, 10, 10); + cg_clear(); + UserProcessScheduler::The().SwitchTeam(kRTUserTeam); PEFLoader ldr("/system/init.out"); @@ -161,7 +168,7 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) { if (ldr.IsLoaded()) rtl_create_user_process(ldr, UserProcess::ExecutableKind::kExecutableKind); else - ke_panic(RUNTIME_CHECK_PROCESS, "RuntimeCheck: Invalid Process Data!"); + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Invalid Init Process."); UserProcessScheduler::The().SwitchTeam(kMidUserTeam); diff --git a/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cpp b/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cpp index 39f12705..1e3adadf 100644 --- a/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cpp +++ b/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cpp @@ -5,7 +5,7 @@ #include <ArchKit/ArchKit.h> #include <KernelKit/ProcessScheduler.h> -#include <KernelKit/UserMgr+User.h> +#include <KernelKit/User.h> #include <NeKit/KString.h> #include <SignalKit/Signals.h> diff --git a/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cpp b/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cpp index 634fc9c4..4581deb0 100644 --- a/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cpp +++ b/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cpp @@ -7,6 +7,7 @@ #include <KernelKit/ProcessScheduler.h> namespace Kernel { + /***********************************************************************************/ /// @brief Unimplemented function (crashes by default) /// @param process The process handle. @@ -26,4 +27,5 @@ EXTERN_C Bool hal_check_task(HAL::StackFramePtr stack_ptr) { return stack_ptr->SP != 0 && stack_ptr->IP != 0; } + } // namespace Kernel diff --git a/src/kernel/KernelKit/BinaryMutex.h b/src/kernel/KernelKit/BinaryMutex.h index 2fb390d3..d97ab854 100644 --- a/src/kernel/KernelKit/BinaryMutex.h +++ b/src/kernel/KernelKit/BinaryMutex.h @@ -8,12 +8,14 @@ #include <CompilerKit/CompilerKit.h> #include <KernelKit/Timer.h> +#include <KernelKit/CoreProcessScheduler.h> #include <NeKit/Config.h> namespace Kernel { class UserProcess; /// @brief Access control class, which locks a task until one is done. +/// Implements priority inheritance to prevent priority inversion. class BinaryMutex final { public: using LockedPtr = UserProcess*; @@ -37,6 +39,7 @@ class BinaryMutex final { private: LockedPtr fLockingProcess{nullptr}; + AffinityKind fOwnerOriginalAffinity{AffinityKind::kInvalid}; // for priority inheritance }; } // namespace Kernel diff --git a/src/kernel/KernelKit/CoreProcessScheduler.h b/src/kernel/KernelKit/CoreProcessScheduler.h index 71a75e1a..2f105036 100644 --- a/src/kernel/KernelKit/CoreProcessScheduler.h +++ b/src/kernel/KernelKit/CoreProcessScheduler.h @@ -146,7 +146,7 @@ enum struct ProcessStatusKind : Int32 { /***********************************************************************************/ enum struct AffinityKind : Int32 { kInvalid = 0, - kRealTime = 100, + kUltraHigh = 100, kVeryHigh = 150, kHigh = 200, kStandard = 1000, diff --git a/src/kernel/KernelKit/DebugOutput.h b/src/kernel/KernelKit/DebugOutput.h index 3695602e..4a705804 100644 --- a/src/kernel/KernelKit/DebugOutput.h +++ b/src/kernel/KernelKit/DebugOutput.h @@ -185,7 +185,7 @@ inline TerminalDevice& operator<<(TerminalDevice& src, const Long& num) { #undef kout #endif // ifdef kout -#define kout TerminalDevice::The() +#define kout TerminalDevice::The() << __FILE__ << ": " #ifdef kendl #undef kendl @@ -197,7 +197,7 @@ inline TerminalDevice& operator<<(TerminalDevice& src, const Long& num) { #undef kout8 #endif // ifdef kout8 -#define kout8 Utf8TerminalDevice::The() +#define kout8 Utf8TerminalDevice::The() << __FILE__ << ": " #ifdef kendl8 #undef kendl8 diff --git a/src/kernel/KernelKit/DriveMgr.h b/src/kernel/KernelKit/DriveMgr.h index 76ee5dcf..8b095f05 100644 --- a/src/kernel/KernelKit/DriveMgr.h +++ b/src/kernel/KernelKit/DriveMgr.h @@ -3,8 +3,8 @@ // Licensed under the Apache License, Version 2.0 (see LICENSE file) // Official repository: https://github.com/ne-foss-org/nekernel -#ifndef INC_DRIVE_MANAGER_H -#define INC_DRIVE_MANAGER_H +#ifndef KERNELKIT_DRIVEMGR_H +#define KERNELKIT_DRIVEMGR_H /// @file DriveMgr.h /// @brief NeKernel's drive manager. @@ -166,4 +166,4 @@ Void io_drv_input(DriveTrait::DrivePacket pckt); Void io_drv_output(DriveTrait::DrivePacket pckt); } // namespace Kernel -#endif /* ifndef INC_DRIVE_MANAGER_H */ +#endif /* ifndef KERNELKIT_DRIVEMGR_H */ diff --git a/src/kernel/KernelKit/FileMgr.h b/src/kernel/KernelKit/FileMgr.h index 87644e68..06af3c2d 100644 --- a/src/kernel/KernelKit/FileMgr.h +++ b/src/kernel/KernelKit/FileMgr.h @@ -3,14 +3,14 @@ // Licensed under the Apache License, Version 2.0 (see LICENSE file) // Official repository: https://github.com/ne-foss-org/nekernel -#ifndef INC_FILEMGR_H -#define INC_FILEMGR_H +#ifndef KERNELKIT_FILEMGR_H +#define KERNELKIT_FILEMGR_H /// @file FileMgr.h /// @brief File Manager Subsystem. /// @author Amlal El Mahrouss (amlal@nekernel.org) -//! Include filesystems that NeKernel supports. +//! Include filesystems that the hybrid kernel supports. #include <FSKit/Ext2+IFS.h> #include <FSKit/NeFS.h> #include <FSKit/OpenHeFS.h> @@ -352,7 +352,7 @@ class FileStream final { /// @brief Leak MIME. /// @return The MIME. - Char* MIME() { return const_cast<Char*>(fMime); } + Char* MIME() { return fMime; } enum { kFileMgrRestrictRead = 100, @@ -364,14 +364,15 @@ class FileStream final { }; private: - NodePtr fFile{nullptr}; - Int32 fFileRestrict{kFileMgrRestrictReadBinary}; - const Char* fMime{kFileMimeGeneric}; + NodePtr fFile{nullptr}; + Int32 fFileRestrict{kFileMgrRestrictReadBinary}; + Char* fMime{const_cast<Char*>(kFileMimeGeneric)}; }; using FileStreamASCII = FileStream<Char>; using FileStreamUTF8 = FileStream<Utf8Char>; -using FileStreamUTF16 = FileStream<WideChar>; +using FileStreamUTF16 = FileStream<Utf16Char>; +using FileStreamWide = FileStream<WideChar>; typedef UInt64 CursorType; @@ -423,9 +424,9 @@ inline FileStream<Encoding, Class>::FileStream(const Encoding* path, const Encod /// @brief destructor of the file stream. template <typename Encoding, typename Class> inline FileStream<Encoding, Class>::~FileStream() { - mm_free_ptr(fFile); + if (fFile) mm_free_ptr(fFile); fFile = nullptr; } } // namespace Kernel -#endif // ifndef INC_FILEMGR_H +#endif // ifndef KERNELKIT_FILEMGR_H diff --git a/src/kernel/KernelKit/HardwareThreadScheduler.h b/src/kernel/KernelKit/HardwareThreadScheduler.h index a9183cd2..43a906d6 100644 --- a/src/kernel/KernelKit/HardwareThreadScheduler.h +++ b/src/kernel/KernelKit/HardwareThreadScheduler.h @@ -12,6 +12,7 @@ /// @note Last Rev Sun 28 Jul CET 2024 /// @note Last Rev Thu, Aug 1, 2024 9:07:38 AM +/// @note Last Rev Sun, March 22, 2026 5:16 PM #if defined(__nekernel_max_cores) /// \note This can be edited at compile-time to specify how many cores can be used by NeKernel. diff --git a/src/kernel/KernelKit/UserMgr+User.h b/src/kernel/KernelKit/User.h index bae51180..bae51180 100644 --- a/src/kernel/KernelKit/UserMgr+User.h +++ b/src/kernel/KernelKit/User.h diff --git a/src/kernel/KernelKit/UserMgr.h b/src/kernel/KernelKit/UserMgr.h index 16ca79b6..7fc2b635 100644 --- a/src/kernel/KernelKit/UserMgr.h +++ b/src/kernel/KernelKit/UserMgr.h @@ -6,6 +6,6 @@ #ifndef KERNELKIT_USERMGR_H #define KERNELKIT_USERMGR_H -#include <KernelKit/UserMgr+User.h> +#include <KernelKit/User.h> #endif
\ No newline at end of file diff --git a/src/kernel/KernelKit/UserProcessScheduler.h b/src/kernel/KernelKit/UserProcessScheduler.h index 5018f1f6..1318c7f6 100644 --- a/src/kernel/KernelKit/UserProcessScheduler.h +++ b/src/kernel/KernelKit/UserProcessScheduler.h @@ -13,7 +13,7 @@ #include <ArchKit/ArchKit.h> #include <KernelKit/CoreProcessScheduler.h> #include <KernelKit/LockDelegate.h> -#include <KernelKit/UserMgr+User.h> +#include <KernelKit/User.h> #include <NeKit/MutableArray.h> //////////////////////////////////////////////////// @@ -83,9 +83,10 @@ class UserProcess final { kExecutableKindCount, }; - ProcessTime PTime{0}; //! @brief Process allocated tine. + ProcessTime PTime{0}; //! @brief Process allocated time. ProcessTime RTime{0}; //! @brief Process run time. - ProcessTime UTime{0}; //! #brief Process used time. + ProcessTime UTime{0}; //! @brief Process used time. + ProcessTime STime{0}; //! @brief Process sleep time (for dynamic priority boost). ProcessID ProcessId{kCPSInvalidPID}; ExecutableKind Kind{ExecutableKind::kExecutableKind}; diff --git a/src/kernel/NeKit/New.h b/src/kernel/NeKit/New.h index 648f4a20..9b601534 100644 --- a/src/kernel/NeKit/New.h +++ b/src/kernel/NeKit/New.h @@ -14,8 +14,8 @@ typedef __SIZE_TYPE__ size_t; void* operator new(size_t); void* operator new[](size_t); -void operator delete(void*); -void operator delete(void*, unsigned long); -void operator delete[](void*); +void operator delete(void*) noexcept; +void operator delete(void*, unsigned long) noexcept; +void operator delete[](void*) noexcept; #endif diff --git a/src/kernel/src/BinaryMutex.cpp b/src/kernel/src/BinaryMutex.cpp index e321ba69..a83f031a 100644 --- a/src/kernel/src/BinaryMutex.cpp +++ b/src/kernel/src/BinaryMutex.cpp @@ -7,18 +7,19 @@ #include <KernelKit/ProcessScheduler.h> namespace Kernel { -/***********************************************************************************/ -/// @brief Unlocks the binary mutex. -/***********************************************************************************/ Bool BinaryMutex::Unlock() { - if (fLockingProcess->Status == ProcessStatusKind::kRunning) { - fLockingProcess = nullptr; + if (!fLockingProcess) + return No; - return Yes; + // restore original priority if we boosted the owner + if (fOwnerOriginalAffinity != AffinityKind::kInvalid) { + fLockingProcess->Affinity = fOwnerOriginalAffinity; + fOwnerOriginalAffinity = AffinityKind::kInvalid; } - return No; + fLockingProcess = nullptr; + return Yes; } /***********************************************************************************/ @@ -26,9 +27,20 @@ Bool BinaryMutex::Unlock() { /***********************************************************************************/ Bool BinaryMutex::Lock(BinaryMutex::LockedPtr process) { - if (!process || this->IsLocked()) return No; + if (!process) return No; + + // if already locked, implement priority inheritance + if (this->IsLocked() && fLockingProcess) { + // boost owner to waiter's priority if waiter is higher priority (lower value = higher priority) + if (process->Affinity < fLockingProcess->Affinity) { + fOwnerOriginalAffinity = fLockingProcess->Affinity; + fLockingProcess->Affinity = process->Affinity; + } + return No; // lock not acquired, but owner boosted + } this->fLockingProcess = process; + fOwnerOriginalAffinity = AffinityKind::kInvalid; return Yes; } @@ -42,12 +54,17 @@ Bool BinaryMutex::IsLocked() const { } /***********************************************************************************/ -/// @brief Try lock or wait. +/// @brief Try lock, waiting until timeout if already locked. /***********************************************************************************/ Bool BinaryMutex::LockAndWait(BinaryMutex::LockedPtr process, ITimer* timer) { - if (timer == nullptr) return No; + if (timer == nullptr || !process) return No; + + // try to acquire lock immediately + if (this->Lock(process)) + return Yes; + // wait and retry timer->Wait(); return this->Lock(process); } diff --git a/src/kernel/src/FS/NeFS+FileSystemParser.cpp b/src/kernel/src/FS/NeFS+FileSystemParser.cpp index 42fb36a8..36b63ec7 100644 --- a/src/kernel/src/FS/NeFS+FileSystemParser.cpp +++ b/src/kernel/src/FS/NeFS+FileSystemParser.cpp @@ -12,7 +12,7 @@ #include <KernelKit/IFS.h> #include <KernelKit/KPC.h> #include <KernelKit/ProcessScheduler.h> -#include <KernelKit/UserMgr+User.h> +#include <KernelKit/User.h> #include <NeKit/Crc32.h> #include <NeKit/KString.h> #include <NeKit/KernelPanic.h> diff --git a/src/kernel/src/FS/OpenHeFS+FileMgr.cpp b/src/kernel/src/FS/OpenHeFS+FileMgr.cpp index a0a649eb..773ed5da 100644 --- a/src/kernel/src/FS/OpenHeFS+FileMgr.cpp +++ b/src/kernel/src/FS/OpenHeFS+FileMgr.cpp @@ -221,10 +221,6 @@ _Output VoidPtr HeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _ Void HeFileSystemMgr::Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size) { NE_UNUSED(node); - // NE_UNUSED(flags); - // NE_UNUSED(size); - // NE_UNUSED(name); - // NE_UNUSED(data); if (!flags) return; if (!size) return; @@ -260,6 +256,7 @@ _Output VoidPtr HeFileSystemMgr::Read(_Input const Char* name, _Input NodePtr no _Output Bool HeFileSystemMgr::Seek(NodePtr node, SizeT off) { if (this->Tell(node) == kFileMgrNPos) return false; + kout << "The Method is not implemented in the Hybrid kernel.\r"; return off > 0; } @@ -269,7 +266,7 @@ _Output Bool HeFileSystemMgr::Seek(NodePtr node, SizeT off) { _Output SizeT HeFileSystemMgr::Tell(NodePtr node) { if (!node) return kFileMgrNPos; SizeT pos = 0ULL; - + kout << "The Method is not implemented in the Hybrid kernel.\r"; return pos; } diff --git a/src/kernel/src/FS/OpenHeFS+FileSystemParser.cpp b/src/kernel/src/FS/OpenHeFS+FileSystemParser.cpp index b923d13f..6f980730 100644 --- a/src/kernel/src/FS/OpenHeFS+FileSystemParser.cpp +++ b/src/kernel/src/FS/OpenHeFS+FileSystemParser.cpp @@ -10,7 +10,7 @@ #include <FirmwareKit/GPT.h> #include <KernelKit/KPC.h> #include <KernelKit/ProcessScheduler.h> -#include <KernelKit/UserMgr+User.h> +#include <KernelKit/User.h> #include <NeKit/Crc32.h> #include <NeKit/KString.h> #include <NeKit/KernelPanic.h> diff --git a/src/kernel/src/New+Delete.cpp b/src/kernel/src/New+Delete.cpp index 9ec34c6f..6e4dd79a 100644 --- a/src/kernel/src/New+Delete.cpp +++ b/src/kernel/src/New+Delete.cpp @@ -18,19 +18,19 @@ void* operator new(size_t sz) { return Kernel::mm_alloc_ptr(sz, true, false); } -void operator delete[](void* ptr) { +void operator delete[](void* ptr) noexcept { if (ptr == nullptr) return; Kernel::mm_free_ptr(ptr); } -void operator delete(void* ptr) { +void operator delete(void* ptr) noexcept { if (ptr == nullptr) return; Kernel::mm_free_ptr(ptr); } -void operator delete(void* ptr, size_t sz) { +void operator delete(void* ptr, size_t sz) noexcept { if (ptr == nullptr) return; NE_UNUSED(sz); @@ -38,7 +38,7 @@ void operator delete(void* ptr, size_t sz) { Kernel::mm_free_ptr(ptr); } -void operator delete[](void* ptr, size_t sz) { +void operator delete[](void* ptr, size_t sz) noexcept { if (ptr == nullptr) return; NE_UNUSED(sz); diff --git a/src/kernel/src/PageMgr.cpp b/src/kernel/src/PageMgr.cpp index 7aac7d42..f0a8b346 100644 --- a/src/kernel/src/PageMgr.cpp +++ b/src/kernel/src/PageMgr.cpp @@ -13,6 +13,7 @@ #endif // ifdef __NE_AMD64__ || defined(__NE_ARM64__) namespace Kernel { + PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, UIntPtr VirtAddr) : fRw(Rw), fUser(User), @@ -91,4 +92,5 @@ Void PTEWrapper::NoExecute(const bool enable) { Bool PTEWrapper::NoExecute() { return fExecDisable; } + } // namespace Kernel diff --git a/src/kernel/src/User.cpp b/src/kernel/src/User.cpp index 2e626b03..3f5bb66a 100644 --- a/src/kernel/src/User.cpp +++ b/src/kernel/src/User.cpp @@ -7,12 +7,12 @@ #include <KernelKit/HeapMgr.h> #include <KernelKit/KPC.h> #include <KernelKit/ThreadLocalStorage.h> -#include <KernelKit/UserMgr+User.h> +#include <KernelKit/User.h> #include <NeKit/KString.h> #include <NeKit/KernelPanic.h> #include <NeKit/Utils.h> -/// @file UserMgr+User.cpp +/// @file User.cpp /// @brief Multi-user support. namespace Kernel { diff --git a/src/kernel/src/UserProcessScheduler.cpp b/src/kernel/src/UserProcessScheduler.cpp index 4b8d788b..a4b328ac 100644 --- a/src/kernel/src/UserProcessScheduler.cpp +++ b/src/kernel/src/UserProcessScheduler.cpp @@ -12,6 +12,7 @@ #include <NeKit/KString.h> #include <NeKit/Utils.h> #include <SignalKit/Signals.h> +#include "KernelKit/CoreProcessScheduler.h" ///! BUG COUNT: 0 @@ -405,6 +406,7 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im process.PTime = 0; process.UTime = 0; process.RTime = 0; + process.STime = 0; if (!process.FileTree) { process.FileTree = new ProcessFileTree<VoidPtr>(); @@ -474,47 +476,67 @@ Bool UserProcessScheduler::HasMP() { /***********************************************************************************/ SizeT UserProcessScheduler::Run() { - if (mTeam.mProcessCur < 1) { - return 0UL; - } + STATIC SizeT process_index{}; //! we store this guy to tell the scheduler how many + //! things we have scheduled. - SizeT process_index = 0UL; //! we store this guy to tell the scheduler how many - //! things we have scheduled. + UserProcessTeam& team = mTeam; + SizeT limit = team.AsArray().Capacity(); - for (; process_index < mTeam.AsArray().Capacity(); ++process_index) { - auto& process = mTeam.AsArray()[process_index]; + if (team.mProcessCur < 1) { + return {}; + } - //! Check if the process needs to be run. - if (UserProcessHelper::CanBeScheduled(process)) { - kout << process.Name << " will be scheduled to run...\r"; + if (process_index > limit) + process_index = 0UL; + else + ++process_index; - //! Increase the usage time of the process. - if (process.UTime < process.PTime) { - ++process.UTime; - } + auto& process = team.AsArray()[process_index]; - this->TheCurrentProcess() = process; + //! Check if the process needs to be run. + if (UserProcessHelper::CanBeScheduled(process)) { + kout << process.Name << " will be scheduled to run...\r"; - if (UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { - process.PTime = static_cast<Int32>(process.Affinity); + //! Increase the usage time of the process. + if (process.UTime < process.PTime) { + ++process.UTime; + } - // We add a bigger cooldown according to the RTime and affinity here. - if (process.PTime < process.RTime && AffinityKind::kRealTime != process.Affinity) { - if (process.RTime < (Int32) AffinityKind::kVeryHigh) - process.RTime += (Int32) AffinityKind::kLowUsage; - else if (process.RTime < (Int32) AffinityKind::kHigh) - process.RTime += (Int32) AffinityKind::kStandard; - else if (process.RTime < (Int32) AffinityKind::kStandard) - process.RTime += (Int32) AffinityKind::kHigh; + //! boost priority for processes that slept (interactive boost) + if (process.STime > 0) { + // the longer it slept, the bigger the boost (capped at kVeryHigh level) + ProcessTime boost = process.STime / 10; + if (boost > (Int32)AffinityKind::kHigh) + boost = (Int32)AffinityKind::kHigh; + process.PTime += boost; + process.STime = 0; // reset sleep counter after boost + } - process.PTime -= process.RTime; - process.RTime = 0UL; - } + this->TheCurrentProcess() = process; + + if (UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { + // We add a bigger cooldown according to the RTime and affinity here. + if (process.PTime < process.RTime && AffinityKind::kUltraHigh != process.Affinity) { + if (process.RTime < (Int32) AffinityKind::kVeryHigh) + process.RTime += (Int32) AffinityKind::kLowUsage; + else if (process.RTime < (Int32) AffinityKind::kHigh) + process.RTime += (Int32) AffinityKind::kStandard; + else if (process.RTime < (Int32) AffinityKind::kStandard) + process.RTime += (Int32) AffinityKind::kHigh; + + process.PTime -= process.RTime; + process.RTime = 0UL; + } else if (AffinityKind::kUltraHigh != process.Affinity) { + process.PTime += (Int32)AffinityKind::kUltraHigh; } - } else { - ++process.RTime; - --process.PTime; } + } else { + //! track sleep time for processes that are blocked/waiting + if (process.Status == ProcessStatusKind::kFrozen) { + ++process.STime; + } + ++process.RTime; + --process.PTime; } return process_index; @@ -562,7 +584,7 @@ ErrorOr<ProcessID> UserProcessHelper::TheCurrentPID() { /// @retval true can be schedulded. /// @retval false cannot be schedulded. Bool UserProcessHelper::CanBeScheduled(const UserProcess& process) { - if (process.Affinity == AffinityKind::kRealTime) return Yes; + if (process.Affinity == AffinityKind::kUltraHigh) return Yes; if (process.Status != ProcessStatusKind::kRunning) return No; if (process.Affinity == AffinityKind::kInvalid) return No; @@ -594,7 +616,7 @@ SizeT UserProcessHelper::StartScheduling() { Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, ProcessID new_pid) { (Void)(kout << "IP: " << hex_number(frame_ptr->IP) << kendl); - for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { + for (SizeT index{}; index < HardwareThreadScheduler::The().Capacity(); ++index) { if (!HardwareThreadScheduler::The()[index].Leak()) continue; if (HardwareThreadScheduler::The()[index].Leak()->Kind() == ThreadKind::kAPInvalid || |
