summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-05-19 10:24:52 +0200
committerAmlal El Mahrouss <amlal@nekernel.org>2025-05-19 10:24:52 +0200
commita9653add416fbddc1969a75adb733bc9e9c675d6 (patch)
treec03a8acfd7e1f3e4ffe1407d9acd4e1d52de76b4
parentce71265ae5bd333c309dff8c2d46e4d52dd78066 (diff)
feat(kernel, sched): Architectural improvements, and cleaned up
the codebase from previous implementations that didn't work/scale well. Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
-rw-r--r--dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc42
-rw-r--r--dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc10
-rw-r--r--dev/kernel/HALKit/AMD64/HalKernelMain.cc7
-rw-r--r--dev/kernel/HALKit/AMD64/HalKernelPanic.cc7
-rw-r--r--dev/kernel/HALKit/ARM64/ApplicationProcessor.h2
-rw-r--r--dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc32
-rw-r--r--dev/kernel/HALKit/ARM64/HalKernelMain.cc55
-rw-r--r--dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc54
-rw-r--r--dev/kernel/KernelKit/MemoryMgr.h5
-rw-r--r--dev/kernel/KernelKit/Timer.h12
-rw-r--r--dev/kernel/NewKit/Array.h5
-rw-r--r--dev/kernel/src/HardwareThreadScheduler.cc15
-rw-r--r--dev/kernel/src/MemoryMgr.cc15
-rw-r--r--dev/kernel/src/UserProcessScheduler.cc58
14 files changed, 137 insertions, 182 deletions
diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
index b12dc7fe..78db9b16 100644
--- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
+++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
@@ -51,8 +51,7 @@ struct HAL_HARDWARE_THREAD;
struct HAL_HARDWARE_THREAD final {
HAL::StackFramePtr mFramePtr;
- ProcessID mProcessID{0};
- UInt8 mCoreID{0};
+ ProcessID mThreadID{0};
};
STATIC HAL_APIC_MADT* kMADTBlock = nullptr;
@@ -100,18 +99,24 @@ Void hal_send_ipi_msg(UInt32 target, UInt32 apic_id, UInt8 vector) {
STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}};
-EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid) {
- const auto process_index = pid % kSchedProcessLimitPerTeam;
+EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 thrdid) {
+ const auto process_index = thrdid % kSchedProcessLimitPerTeam;
return kHWThread[process_index].mFramePtr;
}
-EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) {
- if (pid > kSMPCount) return NO;
+EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) {
+ if (thrdid > kSMPCount) return NO;
if (mp_is_smp()) {
- kHWThread[pid].mFramePtr = stack_frame;
- kHWThread[pid].mProcessID = pid;
+ kHWThread[thrdid].mFramePtr = stack_frame;
+ kHWThread[thrdid].mThreadID = thrdid;
+
+ STATIC HardwareTimer timer{rtl_milliseconds(1000)};
+
+ timer.Wait();
+
+ HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO);
return YES;
}
@@ -151,7 +156,14 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept {
PowerFactoryInterface hw_and_pow_int{vendor_ptr};
- kRawMADT = hw_and_pow_int.Find(APIC_MAG).Leak().Leak();
+ auto pwr = hw_and_pow_int.Find(APIC_MAG);
+
+ if (pwr.HasError()) {
+ kSMPAware = NO;
+ return;
+ }
+
+ kRawMADT = pwr.Leak().Leak();
kMADTBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT);
kSMPAware = NO;
@@ -181,11 +193,6 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept {
controller.Write(LAPIC_REG_TIMER_LVT, 32 | (1 << 17));
controller.Write(LAPIC_REG_TIMER_INITCNT, 1000000);
- UInt8* trampoline_phys = (UInt8*) 0x7c00;
-
- *trampoline_phys = 0xcd;
- *(trampoline_phys + 1) = 0x00;
-
volatile UInt8* entry_ptr = reinterpret_cast<volatile UInt8*>(kMADTBlock->List);
volatile UInt8* end_ptr = ((UInt8*) kMADTBlock) + kMADTBlock->Length;
@@ -203,14 +210,15 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept {
kAPICLocales[kSMPCount] = entry_struct->ProcessorID;
++kSMPCount;
- kout << "LAPIC type, also is on...\r";
+ kout << "Kind: LAPIC: ON\r";
+ // 0x7c00, as recommended by the Intel SDM.
hal_send_ipi_msg(kApicBaseAddress, entry_struct->ProcessorID, 0x7c);
} else {
- kout << "LAPIC type, also is not on...\r";
+ kout << "Kind: LAPIC: OFF\r";
}
} else {
- kout << "Unknown APIC type...\r";
+ kout << "Kind: UNKNOWN: ?\r";
}
entry_ptr += length;
diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
index eac6c389..51fc4f0e 100644
--- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
+++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
@@ -54,8 +54,6 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) {
Kernel::kout << "Kernel: SIGKILL status.\r";
process.Leak().Crash();
-
- dbg_break_point();
}
/// @brief Handle page fault.
@@ -82,8 +80,6 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) {
process.Leak().Signal.Status = process.Leak().Status;
process.Leak().Crash();
-
- dbg_break_point();
}
/// @brief Handle scheduler interrupt.
@@ -125,8 +121,6 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) {
Kernel::kout << "Kernel: SIGKILL status.\r";
process.Leak().Crash();
-
- dbg_break_point();
}
/// @brief Handle any generic fault.
@@ -155,8 +149,6 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) {
Kernel::kout << "Kernel: SIGKILL status.\r";
process.Leak().Crash();
-
- dbg_break_point();
}
EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) {
@@ -216,8 +208,6 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) {
Kernel::kout << "Kernel: SIGKILL status.\r";
process.Leak().Crash();
-
- dbg_break_point();
}
/// @brief Enter syscall from assembly.
diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc
index 6020da3b..4de43f27 100644
--- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc
+++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc
@@ -108,6 +108,13 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept {
for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) {
HardwareThreadScheduler::The()[index].Leak()->Kind() = ThreadKind::kAPStandard;
+ HardwareThreadScheduler::The()[index].Leak()->Busy(NO);
+ }
+
+ for (SizeT index = 0UL; index < UserProcessScheduler::The().TheCurrentTeam().AsArray().Count();
+ ++index) {
+ UserProcessScheduler::The().TheCurrentTeam().AsArray()[index].Status =
+ ProcessStatusKind::kInvalid;
}
rtl_create_user_process(sched_idle_task, "MgmtSrv"); //! Mgmt command server.
diff --git a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc b/dev/kernel/HALKit/AMD64/HalKernelPanic.cc
index 7ec235bd..76b92574 100644
--- a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc
+++ b/dev/kernel/HALKit/AMD64/HalKernelPanic.cc
@@ -31,6 +31,7 @@ class RecoveryFactory final {
/***********************************************************************************/
Void ke_panic(const Kernel::Int32& id, const Char* message) {
(Void)(kout << "*** STOP ***\r");
+
(Void)(kout << "Kernel_Panic_MSG: " << message << kendl);
(Void)(kout << "Kernel_Panic_ID: " << hex_number(id) << kendl);
(Void)(kout << "Kernel_Panic_CR2: " << hex_number((UIntPtr) hal_read_cr2()) << kendl);
@@ -46,8 +47,10 @@ Void RecoveryFactory::Recover() noexcept {
void ke_runtime_check(bool expr, const Char* file, const Char* line) {
if (!expr) {
- (Void)(kout << "Kernel_Panic_File: " << file << kendl);
- (Void)(kout << "Kernel_Panic_Line: " << line << kendl);
+ (Void)(kout << "*** CHECK ***\r");
+
+ (Void)(kout << "Kernel_Panic_FILE: " << file << kendl);
+ (Void)(kout << "Kernel_Panic_LINE: " << line << kendl);
ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed
}
diff --git a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h
index 75f4eb07..06a8e2a8 100644
--- a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h
+++ b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h
@@ -15,5 +15,5 @@
/************************************************** */
namespace Kernel {
-BOOL mp_initialize_gic(Kernel::Void);
+Void mp_init_cores(Void) noexcept;
} \ No newline at end of file
diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc
index a89702ea..d37a3e54 100644
--- a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc
+++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc
@@ -7,7 +7,9 @@
#include <HALKit/ARM64/ApplicationProcessor.h>
#include <HALKit/ARM64/Processor.h>
#include <KernelKit/DebugOutput.h>
+#include <KernelKit/HardwareThreadScheduler.h>
#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/Timer.h>
#define GICD_BASE 0x08000000 // Distributor base address
#define GICC_BASE 0x08010000 // CPU interface base address
@@ -29,11 +31,12 @@
// ================================================================= //
namespace Kernel {
-struct PROCESS_CONTROL_BLOCK final {
+struct HAL_HARDWARE_THREAD final {
HAL::StackFramePtr mFrame;
+ ProcessID mThreadID{0};
};
-STATIC PROCESS_CONTROL_BLOCK kProcessBlocks[kSchedProcessLimitPerTeam] = {0};
+STATIC HAL_HARDWARE_THREAD kHWThread[kMaxAPInsideSched] = {{nullptr}};
namespace Detail {
STATIC BOOL kGICEnabled = NO;
@@ -86,7 +89,7 @@ namespace Detail {
const UInt16 kInterruptScheduler = 0x20;
- (Void)(kout << "Handling interrupt for AP: " << interrupt << kendl);
+ (Void)(kout << "SMP: AP: " << hex_number(interrupt) << kendl);
switch (interrupt) {
case kInterruptScheduler: {
@@ -108,23 +111,32 @@ namespace Detail {
}
} // namespace Detail
-EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID pid) {
- return kProcessBlocks[pid % kSchedProcessLimitPerTeam].mFrame;
+EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID thrdid) {
+ return kHWThread[thrdid].mFrame;
}
-EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) {
- MUST_PASS(stack_frame);
+EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) {
+ MUST_PASS(Detail::kGICEnabled);
- const auto process_index = pid % kSchedProcessLimitPerTeam;
+ if (!stack_frame) return NO;
+ if (thrdid > kMaxAPInsideSched) return NO;
- kProcessBlocks[process_index].mFrame = stack_frame;
+ const auto process_index = thrdid;
+
+ kHWThread[process_index].mFrame = stack_frame;
+ kHWThread[process_index].mThreadID = thrdid;
+
+ STATIC HardwareTimer timer{rtl_milliseconds(1000)};
+ timer.Wait();
+
+ HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO);
return YES;
}
/// @internal
/// @brief Initialize the Global Interrupt Controller.
-BOOL mp_initialize_gic(Void) {
+Void mp_init_cores(Void) noexcept {
if (!Detail::kGICEnabled) {
Detail::kGICEnabled = YES;
Detail::mp_setup_gic_el0();
diff --git a/dev/kernel/HALKit/ARM64/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc
index bf5849ef..c92b12cd 100644
--- a/dev/kernel/HALKit/ARM64/HalKernelMain.cc
+++ b/dev/kernel/HALKit/ARM64/HalKernelMain.cc
@@ -7,9 +7,11 @@
#include <ArchKit/ArchKit.h>
#include <CFKit/Property.h>
#include <FirmwareKit/Handover.h>
+#include <HALKit/ARM64/ApplicationProcessor.h>
#include <HALKit/ARM64/Processor.h>
#include <KernelKit/CodeMgr.h>
#include <KernelKit/FileMgr.h>
+#include <KernelKit/HardwareThreadScheduler.h>
#include <KernelKit/MemoryMgr.h>
#include <KernelKit/PEFCodeMgr.h>
#include <KernelKit/ProcessScheduler.h>
@@ -18,9 +20,10 @@
#include <modules/ACPI/ACPIFactoryInterface.h>
#include <modules/CoreGfx/CoreGfx.h>
-#include <HALKit/ARM64/ApplicationProcessor.h>
-
+#ifndef __NE_MODULAR_KERNEL_COMPONENTS__
EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
+ using namespace Kernel;
+
/************************************************** */
/* INITIALIZE AND VALIDATE HEADER. */
/************************************************** */
@@ -32,6 +35,15 @@ EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
return;
}
+ FB::fb_clear_video();
+
+#ifdef __NE_ARM64_EFI__
+ fw_init_efi((EfiSystemTable*) handover_hdr->f_FirmwareCustomTables[1]);
+
+ Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey,
+ handover_hdr->f_HardwareTables.f_ImageHandle);
+#endif
+
/************************************** */
/* INITIALIZE BIT MAP. */
/************************************** */
@@ -42,31 +54,24 @@ EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
/// @note do initialize the interrupts after it.
- Kernel::mp_initialize_gic();
-
- /// after the scheduler runs, we must look over teams, every 5000s in order to schedule every
- /// process according to their affinity fairly.
-
- auto constexpr kSchedTeamSwitchMS = 5U; /// @brief Team switch time in milliseconds.
-
- Kernel::HardwareTimer timer(rtl_milliseconds(kSchedTeamSwitchMS));
-
- STATIC Kernel::Array<UserProcessTeam, kSchedTeamCount> kTeams;
-
- SizeT team_index = 0U;
+ for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) {
+ HardwareThreadScheduler::The()[index].Leak()->Kind() = ThreadKind::kAPStandard;
+ HardwareThreadScheduler::The()[index].Leak()->Busy(NO);
+ }
- /// @brief This just loops over the teams and switches between them.
- /// @details Not even round-robin, just a simple loop in this boot core we're at.
- while (YES) {
- if (team_index > (kSchedTeamCount - 1)) {
- team_index = 0U;
- }
+ for (SizeT index = 0UL; index < UserProcessScheduler::The().TheCurrentTeam().AsArray().Count();
+ ++index) {
+ UserProcessScheduler::The().TheCurrentTeam().AsArray()[index].Status =
+ ProcessStatusKind::kInvalid;
+ }
- while (!UserProcessScheduler::The().SwitchTeam(kTeams[team_index]))
- ;
+ rtl_create_user_process(sched_idle_task, "MgmtSrv"); //! Mgmt command server.
+ rtl_create_user_process(sched_idle_task, "LaunchSrv"); //! launchd
+ rtl_create_user_process(sched_idle_task, "SecSrv"); //! Login Server
- timer.Wait();
+ Kernel::mp_init_cores();
- ++team_index;
- }
+ while (YES)
+ ;
}
+#endif \ No newline at end of file
diff --git a/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc b/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc
index e0b67489..faad6778 100644
--- a/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc
+++ b/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc
@@ -13,65 +13,15 @@
namespace Kernel::HAL {
typedef UInt32 PageTableIndex;
-/// \brief Page store type.
-struct NE_PAGE_STORE final {
- struct {
- PDE* fPde{nullptr};
- PTE* fPte{nullptr};
- VoidPtr fVAddr{nullptr};
- } fInternalStore;
-
- Bool fStoreOp{No}; // Store operation in progress.
-
- static NE_PAGE_STORE& The() {
- static NE_PAGE_STORE the;
- return the;
- }
-};
-
-/// \brief Retrieve the page status of a PTE.
-STATIC Void mmi_page_status(PTE* pte) {
- NE_UNUSED(pte);
-}
-
-STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry);
-
/// @brief Maps or allocates a page from virtual_address.
/// @param virtual_address a valid virtual address.
/// @param phys_addr point to physical address.
/// @param flags the flags to put on the page.
/// @return Status code of page manipulation process.
EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags) {
- if (!virtual_address || !flags) return kErrorSuccess;
-
- NE_PAGE_STORE& page_store = NE_PAGE_STORE::The();
-
- while (page_store.fStoreOp)
- ;
-
- page_store.fStoreOp = Yes;
-
- if (page_store.fInternalStore.fVAddr == virtual_address) {
- page_store.fStoreOp = No;
- return mmi_map_page_table_entry(page_store.fInternalStore.fVAddr, flags,
- page_store.fInternalStore.fPte);
- }
-
- return kErrorSuccess;
-}
-
-/// @brief Maps flags for a specific pte.
-/// @internal Internal function.
-STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry) {
- NE_PAGE_STORE& page_store = NE_PAGE_STORE::The();
-
- // Update internal store, and tlbi the virtual address.
-
- page_store.fInternalStore.fPde = nullptr;
- page_store.fInternalStore.fPte = pt_entry;
- page_store.fInternalStore.fVAddr = virtual_address;
+ if (!virtual_address || !flags) return kErrorInvalidData;
- page_store.fStoreOp = No;
+ NE_UNUSED(physical_address);
return kErrorSuccess;
}
diff --git a/dev/kernel/KernelKit/MemoryMgr.h b/dev/kernel/KernelKit/MemoryMgr.h
index d84dc9a4..bf389955 100644
--- a/dev/kernel/KernelKit/MemoryMgr.h
+++ b/dev/kernel/KernelKit/MemoryMgr.h
@@ -21,11 +21,6 @@ namespace Kernel {
/// @return a status code regarding the deallocation.
Int32 mm_delete_ptr(VoidPtr heap_ptr);
-/// @brief Declare a new size for heap_ptr.
-/// @param heap_ptr the pointer.
-/// @return unsupported always returns nullptr.
-VoidPtr mm_realloc_ptr(VoidPtr heap_ptr, SizeT new_sz);
-
/// @brief Check if pointer is a valid Kernel pointer.
/// @param heap_ptr the pointer
/// @return if it exists it returns true.
diff --git a/dev/kernel/KernelKit/Timer.h b/dev/kernel/KernelKit/Timer.h
index d6cfee39..2d040535 100644
--- a/dev/kernel/KernelKit/Timer.h
+++ b/dev/kernel/KernelKit/Timer.h
@@ -60,16 +60,16 @@ class HardwareTimer final : public TimerInterface {
Int64 fWaitFor{0};
};
-inline Int64 rtl_microseconds(Int64 time) {
- if (time < 0) return 0;
+inline UInt64 rtl_microseconds(UInt64 time) {
+ if (time < 1) return 0;
// TODO: nanoseconds maybe?
- return kTimeUnit * time;
+ return time / kTimeUnit;
}
-inline Int64 rtl_milliseconds(Int64 time) {
- if (time < 0) return 0;
+inline UInt64 rtl_milliseconds(UInt64 time) {
+ if (time < 1) return 0;
- return kTimeUnit * kTimeUnit * time;
+ return time;
}
} // namespace Kernel
diff --git a/dev/kernel/NewKit/Array.h b/dev/kernel/NewKit/Array.h
index 767d8678..2b6d31f3 100644
--- a/dev/kernel/NewKit/Array.h
+++ b/dev/kernel/NewKit/Array.h
@@ -26,7 +26,10 @@ class Array final {
SizeT Capacity() { return N; }
- SizeT Count() { return N; }
+ SizeT Count() {
+ const static SizeT kArrCnt = N;
+ return kArrCnt; // avoid constexpr error.
+ }
const T* CData() { return fArray; }
diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc
index 09c1c7d8..b801632c 100644
--- a/dev/kernel/src/HardwareThreadScheduler.cc
+++ b/dev/kernel/src/HardwareThreadScheduler.cc
@@ -57,19 +57,6 @@ ThreadKind& HardwareThread::Kind() noexcept {
//! @return whether the thread is busy or not.
/***********************************************************************************/
Bool HardwareThread::IsBusy() noexcept {
- STATIC Int64 busy_timer = 0U;
- constexpr Int64 kTimeoutMax =
- 0x1000000; // an arbitrary value used to tell if the timeout hasn't been reached yet.
-
- if (fBusy && (busy_timer > kTimeoutMax)) {
- busy_timer = 0U;
- fBusy = No;
-
- return No;
- }
-
- ++busy_timer;
-
return fBusy;
}
@@ -105,8 +92,6 @@ Void HardwareThread::Wake(const bool wakeup) noexcept {
/// @retval false stack is invalid, previous code is running.
/***********************************************************************************/
Bool HardwareThread::Switch(HAL::StackFramePtr frame) {
- if (this->IsBusy()) return NO;
-
this->fStack = frame;
Bool ret = mp_register_process(fStack, this->fPID);
diff --git a/dev/kernel/src/MemoryMgr.cc b/dev/kernel/src/MemoryMgr.cc
index f8aa14cf..efb9a35f 100644
--- a/dev/kernel/src/MemoryMgr.cc
+++ b/dev/kernel/src/MemoryMgr.cc
@@ -93,21 +93,6 @@ namespace Detail {
STATIC PageMgr kPageMgr;
-/// @brief Declare a new size for ptr_ptr.
-/// @param ptr_ptr the pointer.
-/// @return Newly allocated heap header.
-_Output auto mm_realloc_ptr(VoidPtr ptr_ptr, SizeT new_sz) -> VoidPtr {
- if (Detail::mm_check_ptr_address(ptr_ptr) == No) return nullptr;
-
- if (!ptr_ptr || new_sz < 1) return nullptr;
-
- kout << "MemoryMgr: This function is not implemented by the kernel yet.\r";
-
- ke_panic(RUNTIME_CHECK_INVALID);
-
- return nullptr;
-}
-
/// @brief Allocate chunk of memory.
/// @param sz Size of pointer
/// @param wr Read Write bit.
diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc
index 393f1419..0de38532 100644
--- a/dev/kernel/src/UserProcessScheduler.cc
+++ b/dev/kernel/src/UserProcessScheduler.cc
@@ -492,28 +492,24 @@ SizeT UserProcessScheduler::Run() noexcept {
//! Check if the process needs to be run.
if (UserProcessHelper::CanBeScheduled(process)) {
- kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled...\r";
-
- process.PTime = static_cast<Int32>(process.Affinity);
-
- if (process.PTime < process.RTime && AffinityKind::kRealTime != process.Affinity) {
- if (process.RTime < (Int32) AffinityKind::kVeryHigh)
- process.RTime = (Int32) AffinityKind::kLowUsage / 2;
- else if (process.RTime < (Int32) AffinityKind::kHigh)
- process.RTime = (Int32) AffinityKind::kStandard / 3;
- else if (process.RTime < (Int32) AffinityKind::kStandard)
- process.RTime = (Int32) AffinityKind::kHigh / 4;
-
- process.PTime -= process.RTime;
- process.RTime = 0UL;
- }
-
- if (!UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) {
- continue;
+ kout << process.Name << " will be scheduled...\r";
+
+ if (UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) {
+ process.PTime = static_cast<Int32>(process.Affinity);
+
+ if (process.PTime < process.RTime && AffinityKind::kRealTime != process.Affinity) {
+ if (process.RTime < (Int32) AffinityKind::kVeryHigh)
+ process.RTime = (Int32) AffinityKind::kLowUsage / 2;
+ else if (process.RTime < (Int32) AffinityKind::kHigh)
+ process.RTime = (Int32) AffinityKind::kStandard / 3;
+ else if (process.RTime < (Int32) AffinityKind::kStandard)
+ process.RTime = (Int32) AffinityKind::kHigh / 4;
+
+ process.PTime -= process.RTime;
+ process.RTime = 0UL;
+ }
}
} else {
- kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled later...\r";
-
++process.RTime;
--process.PTime;
}
@@ -607,13 +603,19 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) {
(Void)(kout << "AP_" << hex_number(index) << kendl);
+ if (HardwareThreadScheduler::The()[index].Leak()->IsBusy()) {
+ (Void)(kout << "AP_" << hex_number(index));
+ kout << " is busy\r";
+ continue;
+ }
+
////////////////////////////////////////////////////////////
/// Prepare task switch. ///
////////////////////////////////////////////////////////////
HardwareThreadScheduler::The()[index].Leak()->Busy(YES);
+
Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr);
- HardwareThreadScheduler::The()[index].Leak()->Busy(NO);
////////////////////////////////////////////////////////////
/// Rollback on fail. ///
@@ -642,13 +644,23 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) {
/// @brief this checks if any process is on the team.
////////////////////////////////////////////////////////////
UserProcessScheduler::operator bool() {
- return mTeam.AsArray().Count() > 0;
+ for (auto process_index = 0UL; process_index < mTeam.AsArray().Count(); ++process_index) {
+ auto& process = mTeam.AsArray()[process_index];
+ if (UserProcessHelper::CanBeScheduled(process)) return true;
+ }
+
+ return false;
}
////////////////////////////////////////////////////////////
/// @brief this checks if no process is on the team.
////////////////////////////////////////////////////////////
Bool UserProcessScheduler::operator!() {
- return mTeam.AsArray().Count() == 0;
+ for (auto process_index = 0UL; process_index < mTeam.AsArray().Count(); ++process_index) {
+ auto& process = mTeam.AsArray()[process_index];
+ if (UserProcessHelper::CanBeScheduled(process)) return false;
+ }
+
+ return true;
}
} // namespace Kernel