feat: port gcc to MontaukOS
This commit is contained in:
1 parent
324b18edda
commit
8e6b619b02
14 files changed
+493
-19
No files matched your search
@@ -1103,6 +1103,48 @@ namespace Sched {
|
||||
return &processTable[slot];
|
||||
}
|
||||
|
||||
// Serializes stack growth so two threads faulting on the same page do not
|
||||
// both map it (the loser's page would leak: FreeUserHalf only frees pages
|
||||
// still referenced by the page tables).
|
||||
static kcp::Spinlock stackGrowLock;
|
||||
|
||||
bool TryGrowUserStack(uint64_t faultAddr) {
|
||||
constexpr uint64_t growBase = UserStackTop - UserStackMax;
|
||||
constexpr uint64_t eagerBase = UserStackTop - UserStackSize;
|
||||
if (faultAddr < growBase || faultAddr >= eagerBase) return false;
|
||||
|
||||
Process* proc = GetCurrentProcessPtr();
|
||||
if (proc == nullptr) return false;
|
||||
|
||||
uint64_t pageVa = faultAddr & ~0xFFFULL;
|
||||
|
||||
stackGrowLock.Acquire();
|
||||
|
||||
// Another thread may have mapped this page between the fault and here.
|
||||
if (Memory::VMM::Paging::IsUserRangeAccessible(proc->pml4Phys, pageVa, 0x1000, true)) {
|
||||
stackGrowLock.Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
void* page = Memory::g_pfa->AllocateZeroed();
|
||||
if (page == nullptr) {
|
||||
stackGrowLock.Release();
|
||||
Kt::KernelLogStream(Kt::ERROR, "Sched")
|
||||
<< "Out of memory growing user stack for pid " << proc->pid;
|
||||
return false;
|
||||
}
|
||||
uint64_t physAddr = Memory::SubHHDM((uint64_t)page);
|
||||
if (!Memory::VMM::Paging::MapUserIn(proc->pml4Phys, physAddr, pageVa)) {
|
||||
stackGrowLock.Release();
|
||||
Memory::g_pfa->Free(page);
|
||||
return false;
|
||||
}
|
||||
stackGrowLock.Release();
|
||||
|
||||
asm volatile("invlpg (%0)" :: "r"(pageVa) : "memory");
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExitProcess() {
|
||||
auto* cpu = Smp::GetCurrentCpuData();
|
||||
int slot = cpu->currentSlot;
|
||||
|
||||
Reference in new issue
Block a user