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

+29 -10
View File
@@ -23,6 +23,7 @@ static volatile uint32_t* gLapic = NULL;
static uint32_t gApicTicksPerUs = 0;
static uint32_t gApicTicksPerQuantum = 0;
static uint64_t gHpetTicksPerUs = 0;
static uint64_t gHpetHz = 0;
static volatile uint64_t* gHpet = NULL;
#define LAPIC_REG(off) (*(volatile uint32_t *)((uint8_t *)gLapic + (off)))
@@ -39,11 +40,28 @@ static void TimerIsr(void) {
}
static uint64_t QueryTicks(void) {
uint64_t baseTicks = gTicks; // The 10ms "coarse" ticks
// The LAPIC timer counts DOWN.
// Ticks elapsed = (Initial Value) - (Current Value)
uint32_t current = LAPIC_REG(LAPIC_TIMER_CUR);
// Prefer HPET when present: it is already a monotonically increasing main
// counter and avoids races between the LAPIC periodic tick and the current
// countdown register.
if (gHpet && gHpetHz) {
uint64_t counter = gHpet[30]; // offset 0xF0: main counter
uint64_t seconds = counter / gHpetHz;
uint64_t rem = counter % gHpetHz;
return seconds * 1000000ull + (rem * 1000000ull) / gHpetHz;
}
// Fallback: combine the coarse periodic tick with the current LAPIC
// countdown. Read the coarse tick twice so an interrupt between gTicks and
// LAPIC_TIMER_CUR cannot make time jump backwards by almost one quantum.
uint64_t baseTicks1;
uint64_t baseTicks2;
uint32_t current;
do {
baseTicks1 = gTicks;
current = LAPIC_REG(LAPIC_TIMER_CUR);
baseTicks2 = gTicks;
} while (baseTicks1 != baseTicks2);
uint32_t initial = gApicTicksPerQuantum;
uint32_t elapsedApicTicks = 0;
@@ -51,11 +69,11 @@ static uint64_t QueryTicks(void) {
elapsedApicTicks = initial - current;
}
// Convert base 10ms ticks to microseconds + the remainder
// gTicks * 10,000 (ms to us) + (elapsed / ticks_per_us)
uint64_t totalUs = (baseTicks * QUANTUM_MS * 1000) + (elapsedApicTicks / gApicTicksPerUs);
return totalUs;
uint64_t subQuantumUs = 0;
if (gApicTicksPerUs)
subQuantumUs = elapsedApicTicks / gApicTicksPerUs;
return (baseTicks1 * QUANTUM_MS * 1000ull) + subQuantumUs;
}
static void Stall(uint32_t us) {
@@ -181,6 +199,7 @@ KSTATUS HalTimerInitialize(uintptr_t lapicPhys, uintptr_t hpetPhys, HAL_TIMER *o
if (hpetPhys) {
gHpet = (volatile uint64_t*)gApi.PhysToVirt(hpetPhys);
uint64_t hpetHz = HpetInit(hpetPhys);
gHpetHz = hpetHz;
gHpetTicksPerUs = hpetHz / 1000000;
}