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:
Karina
2026-01-31 21:28:02 +04:00
parent 02dc35f0df
commit 2be7d3bd46
3 changed files with 41 additions and 87 deletions
+4 -1
View File
@@ -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;
}
+28 -5
View File
@@ -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");
}
+9 -81
View File
@@ -1,86 +1,14 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <stdio.h>
#include <malloc.h>
#define VECTOR_BUFFER_SIZE 8
typedef struct {
Int32* data;
UInt64 size;
UInt64 capacity;
} Vector;
void vector_init(Vector* vec) {
vec->data = nullptr;
vec->size = 0;
vec->capacity = 0;
}
UInt8 vector_append(Vector* vec, const Int32 num) {
if (vec->size >= vec->capacity) {
UInt64 new_cap = (vec->capacity == 0) ? VECTOR_BUFFER_SIZE : vec->capacity * 2;
Int32* new_data = realloc(vec->data, new_cap * sizeof(Int32));
if (!new_data) return 2; // Out of memory
vec->data = new_data;
vec->capacity = new_cap;
}
vec->data[vec->size] = num;
vec->size++;
return 0;
}
void vector_reset(Vector* vec) {
vec->size = 0;
}
UInt8 vector_reserve(Vector* vec, UInt64 new_cap) {
if (new_cap <= vec->capacity) return 0;
Int32* new_data = realloc(vec->data, new_cap * sizeof(Int32));
if (!new_data) return 2;
vec->data = new_data;
vec->capacity = new_cap;
return 0;
}
void vector_free(Vector* vec) {
free(vec->data);
vec->data = nullptr;
vec->size = vec->capacity = 0;
}
void render_list(Vector* numbers) {
printf("\nNumbers [%d/%d]: [", numbers->size, numbers->capacity);
if (numbers->size == 0) printf("]");
for (UInt64 i = 0; i < numbers->size; i++) {
printf("%d", numbers->data[i]);
if (i + 1 >= numbers->size) {
printf("]");
break;
}
printf(", ");
}
}
#include <process.h>
#include <types.h>
int main() {
UInt64* bad_ptr = (UInt64*)0xDEADBEEF; *bad_ptr = 666;
Vector nums;
vector_init(&nums);
printf("Heap test\n");
printf("press any key to add 1 number press 'q' to exit\n");
char c = 'd';
UInt64 i = 0;
while (c != 'q') {
render_list(&nums);
vector_append(&nums, i);
i++;
c = getchar();
for (int i = 0; i < 100; i++) {
UInt64 pid = spawn("/System/CoreServices/debug");
if (pid < 0) {
printf("[PIDSPAMMER] Error %d\n", pid);
} else {
printf("[PIDSPAMMER] %d spawned\n", pid);
}
}
vector_free(&nums);
}