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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user