From 9f119b51048deb6676372fc70bd6fb80cdfc6d89 Mon Sep 17 00:00:00 2001 From: nakst <> Date: Mon, 8 Nov 2021 20:51:57 +0000 Subject: [PATCH] introduce allProcessesMutex --- kernel/memory.cpp | 4 ++-- kernel/scheduler.cpp | 23 ++++++++++--------- kernel/syscall.cpp | 53 +++++++++++++++----------------------------- 3 files changed, 32 insertions(+), 48 deletions(-) diff --git a/kernel/memory.cpp b/kernel/memory.cpp index 4fb3728..b343296 100644 --- a/kernel/memory.cpp +++ b/kernel/memory.cpp @@ -1664,7 +1664,7 @@ void MMBalanceThread() { // Find a process to balance. - KSpinlockAcquire(&scheduler.lock); + KMutexAcquire(&scheduler.allProcessesMutex); Process *process = nullptr; @@ -1683,7 +1683,7 @@ void MMBalanceThread() { } } - KSpinlockRelease(&scheduler.lock); + KMutexRelease(&scheduler.allProcessesMutex); // For every memory region... diff --git a/kernel/scheduler.cpp b/kernel/scheduler.cpp index 6327564..1ecab44 100644 --- a/kernel/scheduler.cpp +++ b/kernel/scheduler.cpp @@ -235,6 +235,7 @@ struct Scheduler { KSpinlock lock; // The general lock. TODO Break this up! KMutex allThreadsMutex; // For accessing the allThreads list. + KMutex allProcessesMutex; // For accessing the allProcesses list. KSpinlock activeTimersSpinlock; // For accessing the activeTimers lists. KEvent killedEvent; // Set during shutdown when all processes have been terminated. @@ -878,9 +879,9 @@ bool Process::StartWithNode(KNode *node) { // Add the process to the list of all processes. - KSpinlockAcquire(&scheduler.lock); + KMutexAcquire(&scheduler.allProcessesMutex); scheduler.allProcesses.InsertEnd(&allItem); - KSpinlockRelease(&scheduler.lock); + KMutexRelease(&scheduler.allProcessesMutex); // Spawn the kernel thread to load the executable. @@ -1001,7 +1002,7 @@ void Scheduler::RemoveProcess(Process *process) { if (started) { // Make sure that the process cannot be opened. - KSpinlockAcquire(&lock); + KMutexAcquire(&allProcessesMutex); allProcesses.Remove(&process->allItem); @@ -1014,7 +1015,7 @@ void Scheduler::RemoveProcess(Process *process) { pmm.balanceResumePosition = 0; } - KSpinlockRelease(&lock); + KMutexRelease(&allProcessesMutex); // At this point, no pointers to the process (should) remain (I think). @@ -1352,7 +1353,7 @@ void Scheduler::Shutdown() { KernelLog(LOG_INFO, "Scheduler", "killing all processes", "Scheduler::Destroy - Killing all processes....\n"); while (true) { - KSpinlockAcquire(&lock); + KMutexAcquire(&allProcessesMutex); Process *process = allProcesses.firstItem->thisItem; while (process && (process->preventNewThreads || process == kernelProcess)) { @@ -1360,7 +1361,7 @@ void Scheduler::Shutdown() { process = item ? item->thisItem : nullptr; } - KSpinlockRelease(&lock); + KMutexRelease(&allProcessesMutex); if (!process) break; TerminateProcess(process, -1); @@ -1370,9 +1371,9 @@ void Scheduler::Shutdown() { } Process *Scheduler::OpenProcess(uint64_t id) { - KSpinlockAcquire(&scheduler.lock); - + KMutexAcquire(&allProcessesMutex); LinkedItem *item = scheduler.allProcesses.firstItem; + Process *result = nullptr; while (item) { Process *process = item->thisItem; @@ -1381,15 +1382,15 @@ Process *Scheduler::OpenProcess(uint64_t id) { && process->handles /* if the process has no handles, it's about to be removed */ && process->type != PROCESS_KERNEL /* the kernel process cannot be opened */) { OpenHandleToObject(process, KERNEL_OBJECT_PROCESS, ES_FLAGS_DEFAULT); + result = item->thisItem; break; } item = item->nextItem; } - KSpinlockRelease(&scheduler.lock); - - return item ? item->thisItem : nullptr; + KMutexRelease(&allProcessesMutex); + return result; } bool KThreadCreate(const char *cName, void (*startAddress)(uintptr_t), uintptr_t argument) { diff --git a/kernel/syscall.cpp b/kernel/syscall.cpp index b7330b2..0c0de58 100644 --- a/kernel/syscall.cpp +++ b/kernel/syscall.cpp @@ -1249,54 +1249,37 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_SYSTEM_TAKE_SNAPSHOT) { switch (type) { case ES_SYSTEM_SNAPSHOT_PROCESSES: { - KSpinlockAcquire(&scheduler.lock); - size_t count = scheduler.allProcesses.count + 8; - bufferSize = sizeof(EsSnapshotProcesses) + sizeof(EsSnapshotProcessesItem) * count; - KSpinlockRelease(&scheduler.lock); - + KMutexAcquire(&scheduler.allProcessesMutex); + + bufferSize = sizeof(EsSnapshotProcesses) + sizeof(EsSnapshotProcessesItem) * scheduler.allProcesses.count; buffer = EsHeapAllocate(bufferSize, true, K_FIXED); if (!buffer) { + KMutexRelease(&scheduler.allProcessesMutex); SYSCALL_RETURN(ES_ERROR_INSUFFICIENT_RESOURCES, false); } - EsMemoryZero(buffer, bufferSize); - - KSpinlockAcquire(&scheduler.lock); - - if (scheduler.allProcesses.count < count) { - count = scheduler.allProcesses.count; - } - EsSnapshotProcesses *snapshot = (EsSnapshotProcesses *) buffer; - LinkedItem *item = scheduler.allProcesses.firstItem; uintptr_t index = 0; - while (item && index < count) { + while (item) { Process *process = item->thisItem; - - { - snapshot->processes[index].pid = process->id; - snapshot->processes[index].memoryUsage = process->vmm->commit * K_PAGE_SIZE; - snapshot->processes[index].cpuTimeSlices = process->cpuTimeSlices; - snapshot->processes[index].idleTimeSlices = process->idleTimeSlices; - snapshot->processes[index].handleCount = process->handleTable.handleCount; - snapshot->processes[index].threadCount = process->threads.count; - snapshot->processes[index].isKernel = process->type == PROCESS_KERNEL; - - snapshot->processes[index].nameBytes = EsCStringLength(process->cExecutableName); - EsMemoryCopy(snapshot->processes[index].name, process->cExecutableName, snapshot->processes[index].nameBytes); - - index++; - } - - item = item->nextItem; + snapshot->processes[index].pid = process->id; + snapshot->processes[index].memoryUsage = process->vmm->commit * K_PAGE_SIZE; + snapshot->processes[index].cpuTimeSlices = process->cpuTimeSlices; + snapshot->processes[index].idleTimeSlices = process->idleTimeSlices; + snapshot->processes[index].handleCount = process->handleTable.handleCount; + snapshot->processes[index].threadCount = process->threads.count; + snapshot->processes[index].isKernel = process->type == PROCESS_KERNEL; + snapshot->processes[index].nameBytes = EsCStringLength(process->cExecutableName); + EsMemoryCopy(snapshot->processes[index].name, process->cExecutableName, snapshot->processes[index].nameBytes); + item = item->nextItem, index++; } - snapshot->count = index; - bufferSize = sizeof(EsSnapshotProcesses) + sizeof(EsSnapshotProcessesItem) * index; - KSpinlockRelease(&scheduler.lock); + EsAssert(index == scheduler.allProcesses.count); + snapshot->count = scheduler.allProcesses.count; + KMutexRelease(&scheduler.allProcessesMutex); } break; default: {