fix(scheduler): garbage collector now wakes up on process terminate
fix(scheduler/spawn): now its doesnt OSPanic's when VMHeapAllocate returned nullptr for stackBaseAddress. It wakes up GC, tries again and if it failed return nullptr
This commit is contained in:
@@ -63,7 +63,10 @@ Int32 OSLoaderProcessSpawn(const char* executablePath, const char* processName)
|
||||
|
||||
VMVirtualMemorySetupUserStack((UInt64*)newProcess->physicalPML4);
|
||||
|
||||
OSSchedulerSpawn((void(*)())entryPoint, newProcess, true, kOSUserStackTop);
|
||||
if (!OSSchedulerSpawn((void(*)())entryPoint, newProcess, true, kOSUserStackTop)) {
|
||||
VMHeapFree(newProcess);
|
||||
return -5;
|
||||
}
|
||||
|
||||
return newProcess->processId;
|
||||
}
|
||||
|
||||
@@ -19,14 +19,15 @@ extern UInt64 gVMKernelPML4Physical;
|
||||
static OSProcess sOSSchedulerKernelProcess;
|
||||
static OSSpinlock sOSSchedulerLock;
|
||||
|
||||
static OSTask* sOSSchedulerGarbageCollectorTask = nullptr;
|
||||
|
||||
void idle_task() {
|
||||
while (1) {
|
||||
__asm__ volatile ("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OSSchedulerGarbadgeCollector() {
|
||||
void OSSchedulerGarbageCollector() {
|
||||
OSTask* self = gOSSchedulerCurrentTask;
|
||||
|
||||
while (true) {
|
||||
@@ -58,6 +59,18 @@ void OSSchedulerGarbadgeCollector() {
|
||||
}
|
||||
}
|
||||
|
||||
static void sOSSchedulerPostGarbageCollectorSignal() {
|
||||
if (!sOSSchedulerGarbageCollectorTask) return;
|
||||
|
||||
OSSpinlockState state;
|
||||
OSSpinlockLockIRQ(&sOSSchedulerLock, &state);
|
||||
|
||||
sOSSchedulerGarbageCollectorTask->taskState = kOSProcessStateRunning;
|
||||
sOSSchedulerGarbageCollectorTask->sleepTicks = 0;
|
||||
|
||||
OSSpinlockUnlockIRQ(&sOSSchedulerLock, &state);
|
||||
}
|
||||
|
||||
void OSSchedulerInitialize() {
|
||||
sOSSchedulerKernelProcess.processId = 0;
|
||||
sOSSchedulerKernelProcess.state = kOSProcessStateRunning;
|
||||
@@ -78,7 +91,7 @@ void OSSchedulerInitialize() {
|
||||
|
||||
gOSSchedulerCurrentTask = kernelTask;
|
||||
OSSchedulerSpawn(idle_task, &sOSSchedulerKernelProcess, false, 0);
|
||||
OSSchedulerSpawn(OSSchedulerGarbadgeCollector, &sOSSchedulerKernelProcess, false, 0);
|
||||
sOSSchedulerGarbageCollectorTask = OSSchedulerSpawn(OSSchedulerGarbageCollector, &sOSSchedulerKernelProcess, false, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -89,7 +102,15 @@ OSTask* OSSchedulerSpawn(void(*entry)(), OSProcess* owner, Boolean isUser, UInt6
|
||||
|
||||
UInt64 stackSize = 16384;
|
||||
UInt8* stackBaseAddress = (UInt8*)VMHeapAllocate(stackSize);
|
||||
if (!stackBaseAddress) OSPanic("OOM for task stack");
|
||||
if (!stackBaseAddress) {
|
||||
sOSSchedulerPostGarbageCollectorSignal();
|
||||
OSSchedulerYield(0);
|
||||
stackBaseAddress = (UInt8*)VMHeapAllocate(stackSize);
|
||||
if (!stackBaseAddress) {
|
||||
VMHeapFree(task);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
UInt64* rsp = (UInt64*)(stackBaseAddress + stackSize);
|
||||
|
||||
UInt64 cs = isUser ? 0x23 : 0x08;
|
||||
@@ -188,16 +209,18 @@ void OSSchedulerWakeup(UInt32 processID) {
|
||||
OSSpinlockUnlockIRQ(&sOSSchedulerLock, &state);
|
||||
}
|
||||
|
||||
|
||||
void OSSchedulerTerminate() {
|
||||
UInt32 processID = gOSSchedulerCurrentTask->id;
|
||||
gOSSchedulerCurrentTask->taskState = kOSProcessStateDead;
|
||||
|
||||
OSSchedulerWakeup(processID);
|
||||
sOSSchedulerPostGarbageCollectorSignal();
|
||||
__asm__ volatile("int $32");
|
||||
}
|
||||
|
||||
void OSSchedulerYield(UInt64 ticks) {
|
||||
gOSSchedulerCurrentTask->sleepTicks = ticks;
|
||||
gOSSchedulerCurrentTask->taskState = kOSProcessStateSleeping;
|
||||
__asm__ volatile("hlt");
|
||||
__asm__ volatile("int $32");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user