refactor syscall ABI and FAT32 driver to use request structs and string views natively, enforce handle access rights on object lookup, add scheduler statistics tracking, fix KiSchedule to prevent 50% idle throttling on CPU-bound threads, better document x64 initial user stack alignment, fix process teardown to properly signal exit events and manage thread counts, optimize doom file I/O with a custom handle struct to internally track position and size, add SubsystemData to TEB for generic thread-local state, apply PAGE_NX to non-executable PE sections in the loader, update native apps, tests, and shells to match new APIs, update kernel32 directory retrieval.

This commit is contained in:
maksw committed 2026-05-26 14:46:49 +02:00
1 parent 603fbdfab1
commit e1248f4afe
43 files changed
+2892 -1857

No files matched your search

+31
View File
@@ -20,10 +20,18 @@ static THREAD* gIdleThread;
static THREAD* gOutgoingThread;
static uint32_t gAgingCounter = 0;
static volatile long gReschedulePending = 0;
static KE_SCHED_STATS gSchedStats;
THREAD* KeGetCurrentThread(void) { return gCurrentThread; }
void KeSetCurrentThread(THREAD* t) { gCurrentThread = t; }
void KeGetSchedulerStats(KE_SCHED_STATS* out) {
if (!out) return;
uintptr_t flags = KeAcquireSpinlock(&gSchedLock);
*out = gSchedStats;
KeReleaseSpinlock(&gSchedLock, flags);
}
static void KiIdleLoop(void) {
while (true) { __halt(); }
}
@@ -121,6 +129,14 @@ void KeUnreadyThread(THREAD* thread) {
KeReleaseSpinlock(&gSchedLock, flags);
}
static int KiAnyRunnableLocked(void) {
for (int p = 0; p < PriorityCount; p++) {
if (!LIST_IS_EMPTY(&gRunQueue[p]))
return 1;
}
return 0;
}
static THREAD* KiPickNext(void) {
for (int p = PriorityCount - 1; p >= 0; p--) {
if (!LIST_IS_EMPTY(&gRunQueue[p])) {
@@ -149,7 +165,18 @@ static void KiSchedule(void) {
uintptr_t flags = KeAcquireSpinlock(&gSchedLock);
cur->SchedLockFlags = flags;
// The currently running thread is not present in a run queue. If it is
// still runnable and nobody else is ready, keep executing it. Otherwise a
// lone CPU-bound thread gets alternated with the idle thread on every timer
// tick, effectively turning a periodic preemption check into a 50% throttle.
if (cur != gIdleThread && cur->State == ThreadRunning && !KiAnyRunnableLocked()) {
gSchedStats.KeepCurrentDecisions++;
KeReleaseSpinlock(&gSchedLock, flags);
return;
}
THREAD* next = KiPickNext();
if (next == gIdleThread) gSchedStats.IdleSelections++;
if (next == cur) {
// Only re-queue if still running normally; a ThreadWaiting/ThreadDead
// caller has already placed SchedulerLink elsewhere (or is discarding
@@ -174,6 +201,7 @@ static void KiSchedule(void) {
}
gOutgoingThread = cur;
gSchedStats.ContextSwitches++;
KeSwitchContext(cur, next);
KeSchedulerPostSwitch();
}
@@ -190,12 +218,14 @@ void KeSchedulerTick(void) {
uintptr_t flags = KeAcquireSpinlock(&gSchedLock);
cur->SchedLockFlags = flags; // Issue 5 fix
gSchedStats.Ticks++;
cur->QuantaConsumed++;
if (cur != gIdleThread && cur->QuantaConsumed >= DEMOTION_QUANTA) {
cur->QuantaConsumed = 0;
if (cur->Priority > PriorityLow) {
cur->Priority = (THREAD_PRIORITY)(cur->Priority - 1);
gSchedStats.Demotions++;
}
}
@@ -208,6 +238,7 @@ void KeSchedulerTick(void) {
LIST_ENTRY* node = ListPopHead(&gRunQueue[p]);
THREAD* t = CONTAINING_RECORD(node, THREAD, SchedulerLink);
t->Priority = PriorityHigh;
gSchedStats.AgingPromotions++;
ListInsertTail(&gRunQueue[PriorityHigh], &t->SchedulerLink);
}
}