summaryrefslogtreecommitdiffhomepage
path: root/dev
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-04-24 15:52:36 +0200
committerAmlal El Mahrouss <amlal@nekernel.org>2025-04-24 15:52:36 +0200
commit7faa5e2fcf41c4fbb2241b605e8f2a11738fc4d9 (patch)
tree4395820c8cab023c8e794e44e93eabefc26ac9b6 /dev
parentde88c44c68f3941e003ddaf13042875370f10978 (diff)
dev, kernel: scheduler, timer: hw timer and scheduler improvements.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev')
-rw-r--r--dev/boot/BootKit/Qr.h4
-rw-r--r--dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc23
-rw-r--r--dev/kernel/HALKit/AMD64/HalDebugOutput.cc5
-rw-r--r--dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc4
-rw-r--r--dev/kernel/HALKit/AMD64/HalKernelMain.cc25
-rw-r--r--dev/kernel/HALKit/AMD64/HalTimerAMD64.cc47
-rw-r--r--dev/kernel/KernelKit/Timer.h10
-rw-r--r--dev/kernel/KernelKit/UserProcessScheduler.h2
-rw-r--r--dev/kernel/src/BinaryMutex.cc2
-rw-r--r--dev/kernel/src/UserProcessScheduler.cc11
10 files changed, 72 insertions, 61 deletions
diff --git a/dev/boot/BootKit/Qr.h b/dev/boot/BootKit/Qr.h
index 231fcee7..1bf9fa3d 100644
--- a/dev/boot/BootKit/Qr.h
+++ b/dev/boot/BootKit/Qr.h
@@ -957,8 +957,8 @@ namespace qr
NE_COPY_DEFAULT(QrDelegate)
/// @brief Draw method delegate.
- template <int V>
- bool draw(Qr<V>& subject, int x, int y) noexcept
+ template <Int32 V>
+ bool draw(Qr<V>& subject, Int32 x, Int32 y) noexcept
{
return subject.draw(x, y);
}
diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
index 3b98e9e8..1f865057 100644
--- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
+++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
@@ -219,17 +219,9 @@ namespace Kernel::HAL
kApicBaseAddress = kMADTBlock->Address;
- constexpr auto kMemoryAPStart = 0x7C000;
- Char* ptr_ap_code = reinterpret_cast<Char*>(kMemoryAPStart);
-
- mm_map_page(ptr_ap_code, ptr_ap_code, kMMFlagsWr | kMMFlagsPCD);
-
- SizeT hal_ap_blob_len = hal_ap_blob_end - hal_ap_blob_start;
-
- rt_copy_memory((Char*)hal_ap_blob_start, ptr_ap_code, hal_ap_blob_len);
-
while (Yes)
{
+ /// @note Anything bigger than x2APIC type doesn't exist.
if (kMADTBlock->List[index].Type > 9 ||
kSMPCount > kSchedProcessLimitPerTeam)
break;
@@ -243,17 +235,6 @@ namespace Kernel::HAL
kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].LAPIC.ProcessorID;
(void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl);
- // I'll just make the AP start from scratch here.
-
- hal_send_start_ipi(kApicBaseAddress, kAPICLocales[kSMPCount]);
-
- HardwareTimer timer(Kernel::rtl_ms(10));
- timer.Wait();
-
- /// TODO: HAL helper to create an address.
-
- hal_send_sipi(kApicBaseAddress, kAPICLocales[kSMPCount], (UInt8)(((UIntPtr)ptr_ap_code) >> 12));
-
++kSMPCount;
break;
}
@@ -264,7 +245,7 @@ namespace Kernel::HAL
++index;
}
- (void)(kout << "SMP: number of APs: " << number(kSMPCount) << kendl);
+ (void)(kout << "SMP: Number of APs: " << number(kSMPCount) << kendl);
// Kernel is now SMP aware.
// That means that the scheduler is now available (on MP Kernels)
diff --git a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc
index b69614fd..84c8c348 100644
--- a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc
+++ b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc
@@ -121,6 +121,11 @@ namespace Kernel
x += kFontSizeX;
+ if (x > kHandoverHeader->f_GOP.f_Width)
+ {
+ x = kFontSizeX;
+ }
+
if (y > kHandoverHeader->f_GOP.f_Height)
{
y = kFontSizeY;
diff --git a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc
index c0c7dfcf..f205e766 100644
--- a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc
+++ b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc
@@ -107,10 +107,10 @@ namespace Kernel::HAL
idt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) *
(kKernelIdtSize);
- hal_load_idt(idt);
-
Detail::hal_enable_pit(kPITTickForScheduler);
+ hal_load_idt(idt);
+
rt_sti();
}
diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc
index d59e9e86..0c680f97 100644
--- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc
+++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc
@@ -19,8 +19,6 @@
EXTERN_C Kernel::VoidPtr kInterruptVectorTable[];
-STATIC Kernel::Array<UserProcessTeam, kSchedTeamCount> kTeams;
-
STATIC Kernel::Void hal_pre_init_scheduler() noexcept
{
for (Kernel::SizeT i = 0U; i < Kernel::UserProcessScheduler::The().CurrentTeam().AsArray().Count(); ++i)
@@ -98,11 +96,13 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept
idt_loader.Load(idt_reg);
- /// after the scheduler runs, we must look over teams, every 200ms in order to schedule every process according to their affinity fairly.
+ /// 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.
- auto constexpr kSchedTeamSwitchMS = 200U; /// @brief Team switch time in milliseconds.
+ Kernel::HardwareTimer timer(rtl_milliseconds(kSchedTeamSwitchMS));
- Kernel::HardwareTimer timer(rtl_ms(kSchedTeamSwitchMS));
+ STATIC Kernel::Array<UserProcessTeam, kSchedTeamCount> kTeams;
SizeT team_index = 0U;
@@ -110,15 +110,16 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept
/// @details Not even round-robin, just a simple loop in this boot core we're at.
while (YES)
{
- timer.Wait();
-
- UserProcessScheduler::The().SwitchTeam(kTeams[team_index]);
-
- ++team_index;
-
- if (team_index > kSchedTeamCount)
+ if (team_index > (kSchedTeamCount - 1))
{
team_index = 0U;
}
+
+ while (!UserProcessScheduler::The().SwitchTeam(kTeams[team_index]))
+ ;
+
+ timer.Wait();
+
+ ++team_index;
}
}
diff --git a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc b/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc
index 72de8eb0..ade41d2f 100644
--- a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc
+++ b/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc
@@ -17,10 +17,10 @@
// timer slot 0
-#define cHPETCounterRegValue (0x00)
-#define cHPETConfigRegValue (0x20)
-#define cHPETCompRegValue (0x24)
-#define cHPETInterruptRegValue (0x2C)
+#define kHPETCounterRegValue (0x00)
+#define kHPETConfigRegValue (0x20)
+#define kHPETCompRegValue (0x24)
+#define kHPETInterruptRegValue (0x2C)
///! BUGS: 0
///! @file HalTimer.cc
@@ -53,7 +53,19 @@ HardwareTimer::HardwareTimer(UInt64 ms)
auto hpet = (Detail::HPET_BLOCK*)power.Find("HPET").Leak().Leak();
MUST_PASS(hpet);
- fDigitalTimer = (UIntPtr*)hpet->address.Address;
+ fDigitalTimer = (UInt8*)hpet->address.Address;
+
+ if (hpet->page_protection)
+ {
+ HAL::mm_map_page((VoidPtr)fDigitalTimer, (VoidPtr)fDigitalTimer, HAL::kMMFlagsWr | HAL::kMMFlagsPCD | HAL::kMMFlagsPwt);
+ }
+
+ // if not enabled yet.
+ if (!(*((volatile UInt64*)((UInt8*)fDigitalTimer + kHPETConfigRegValue)) & (1 << 0)))
+ {
+ *((volatile UInt64*)((UInt8*)fDigitalTimer + kHPETConfigRegValue)) = *((volatile UInt64*)((UInt8*)fDigitalTimer + kHPETConfigRegValue)) | (1 << 0); // enable timer
+ *((volatile UInt64*)((UInt8*)fDigitalTimer + kHPETConfigRegValue)) = *((volatile UInt64*)((UInt8*)fDigitalTimer + kHPETConfigRegValue)) | (1 << 3); // one shot conf
+ }
}
HardwareTimer::~HardwareTimer()
@@ -62,25 +74,28 @@ HardwareTimer::~HardwareTimer()
fWaitFor = 0;
}
+/***********************************************************************************/
+/// @brief Wait for the timer to stop spinning.
+/***********************************************************************************/
+
BOOL HardwareTimer::Wait() noexcept
{
if (fWaitFor < 1)
return NO;
- // if not enabled yet.
- if (!(*(fDigitalTimer + cHPETConfigRegValue) & (1 << 0)))
- {
- *(fDigitalTimer + cHPETConfigRegValue) |= (1 << 0); // enable it
- *(fDigitalTimer + cHPETConfigRegValue) |= (1 << 3); // one shot conf
- }
+ UInt64 hpet_cap = *((volatile UInt64*)(fDigitalTimer + kHPETCounterRegValue));
+ UInt64 femtoseconds_per_tick = (hpet_cap >> 32);
+
+ if (femtoseconds_per_tick == 0)
+ return NO;
- UInt64 ticks = fWaitFor / ((*(fDigitalTimer) >> 32) & __UINT32_MAX__);
- UInt64 prev = *(fDigitalTimer + cHPETCounterRegValue);
+ volatile UInt64* timer = (volatile UInt64*)(fDigitalTimer + kHPETCounterRegValue);
- prev += ticks;
+ UInt64 now = *timer;
+ UInt64 prev = now + (fWaitFor / femtoseconds_per_tick);
- while (*(fDigitalTimer + cHPETCounterRegValue) < (ticks))
- ;
+ while (*timer < (prev))
+ asm volatile("pause");
return YES;
}
diff --git a/dev/kernel/KernelKit/Timer.h b/dev/kernel/KernelKit/Timer.h
index b6d23e6b..1d12876b 100644
--- a/dev/kernel/KernelKit/Timer.h
+++ b/dev/kernel/KernelKit/Timer.h
@@ -60,24 +60,24 @@ namespace Kernel
BOOL Wait() noexcept override;
private:
- UIntPtr* fDigitalTimer{nullptr};
+ volatile UInt8* fDigitalTimer{nullptr};
Int64 fWaitFor{0};
};
- inline Int64 rtl_ms(Int64 time)
+ inline Int64 rtl_microseconds(Int64 time)
{
if (time < 0)
return 0;
// TODO: nanoseconds maybe?
- return kTimeUnit * kTimeUnit * time;
+ return kTimeUnit * time;
}
- inline Int64 rtl_seconds(Int64 time)
+ inline Int64 rtl_milliseconds(Int64 time)
{
if (time < 0)
return 0;
- return kTimeUnit * rtl_ms(time);
+ return kTimeUnit * kTimeUnit * time;
}
} // namespace Kernel
diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h
index 53ee3476..ec16a0e2 100644
--- a/dev/kernel/KernelKit/UserProcessScheduler.h
+++ b/dev/kernel/KernelKit/UserProcessScheduler.h
@@ -20,7 +20,7 @@
#define kSchedMinMicroTime (AffinityKind::kStandard)
#define kSchedInvalidPID (-1)
#define kSchedProcessLimitPerTeam (32U)
-#define kSchedTeamCount (512U)
+#define kSchedTeamCount (256U)
#define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */
#define kSchedMaxStackSz mib_cast(8) /* maximum stack size */
diff --git a/dev/kernel/src/BinaryMutex.cc b/dev/kernel/src/BinaryMutex.cc
index c149b362..f9faadd2 100644
--- a/dev/kernel/src/BinaryMutex.cc
+++ b/dev/kernel/src/BinaryMutex.cc
@@ -67,7 +67,7 @@ namespace Kernel
/***********************************************************************************/
BOOL BinaryMutex::WaitForProcess(const Int16& sec) noexcept
{
- HardwareTimer hw_timer(rtl_seconds(sec));
+ HardwareTimer hw_timer(rtl_milliseconds(sec));
hw_timer.Wait();
return !this->IsLocked();
diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc
index 8df98f87..7aded611 100644
--- a/dev/kernel/src/UserProcessScheduler.cc
+++ b/dev/kernel/src/UserProcessScheduler.cc
@@ -31,8 +31,10 @@ namespace Kernel
STATIC UInt32 kLastExitCode = 0U;
+ STATIC BOOL kCurrentlySwitching = No;
+
/***********************************************************************************/
- /// @brief External reference of the thread scheduler.
+ /// @brief Scheduler itself.
/***********************************************************************************/
STATIC UserProcessScheduler kScheduler;
@@ -470,6 +472,8 @@ namespace Kernel
return 0UL;
}
+ kCurrentlySwitching = Yes;
+
for (; process_index < mTeam.AsArray().Capacity(); ++process_index)
{
auto& process = mTeam.AsArray()[process_index];
@@ -502,6 +506,8 @@ namespace Kernel
}
}
+ kCurrentlySwitching = No;
+
return process_index;
}
@@ -524,6 +530,9 @@ namespace Kernel
if (team.AsArray().Count() < 1)
return No;
+ if (kCurrentlySwitching)
+ return No;
+
kScheduler.mTeam = team;
return Yes;