From 2be7d3bd4605e8f899b3830b22c3697be30db8ec Mon Sep 17 00:00:00 2001 From: Karina Date: Sat, 31 Jan 2026 21:28:02 +0400 Subject: [PATCH] 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 --- kernel/src/OS/Exec/OSLoader.c | 5 +- kernel/src/OS/OSScheduler.c | 33 +++++++++++-- userspace/debug/src/main.c | 90 ++++------------------------------- 3 files changed, 41 insertions(+), 87 deletions(-) diff --git a/kernel/src/OS/Exec/OSLoader.c b/kernel/src/OS/Exec/OSLoader.c index a0bbcff..4d69bfa 100644 --- a/kernel/src/OS/Exec/OSLoader.c +++ b/kernel/src/OS/Exec/OSLoader.c @@ -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; } diff --git a/kernel/src/OS/OSScheduler.c b/kernel/src/OS/OSScheduler.c index b278258..8a49b38 100644 --- a/kernel/src/OS/OSScheduler.c +++ b/kernel/src/OS/OSScheduler.c @@ -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"); } diff --git a/userspace/debug/src/main.c b/userspace/debug/src/main.c index 65383bb..a679cd6 100644 --- a/userspace/debug/src/main.c +++ b/userspace/debug/src/main.c @@ -1,86 +1,14 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 0xKarinyash - #include -#include - -#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 +#include 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); } \ No newline at end of file