introduce allProcessesMutex

This commit is contained in:
nakst 2021-11-08 20:51:57 +00:00
parent fb14dd87e0
commit 9f119b5104
3 changed files with 32 additions and 48 deletions

View File

@ -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...

View File

@ -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<Process> *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) {

View File

@ -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<Process> *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: {