From 7f2715d06ce10fc2c432e3ab4a4f56e28ac433eb Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Thu, 20 Apr 2023 22:24:36 +0300 Subject: [PATCH] [Kernel] Fix release mutex --- include/kernel/kernel.hpp | 5 +++-- src/core/kernel/kernel.cpp | 4 ++-- src/core/kernel/threads.cpp | 27 ++++++++++++++++++++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index 3333923d..85adf952 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -73,6 +73,7 @@ private: void rescheduleThreads(); bool canThreadRun(const Thread& t); bool shouldWaitOnObject(KernelObject* object); + void releaseMutex(Mutex* moo); std::optional getPortHandle(const char* name); void deleteObjectData(KernelObject& object); @@ -106,7 +107,6 @@ private: void createAddressArbiter(); void createEvent(); void createMemoryBlock(); - void createMutex(); void createThread(); void controlMemory(); void duplicateHandle(); @@ -121,11 +121,12 @@ private: void getSystemTick(); void getThreadID(); void getThreadPriority(); - void releaseMutex(); void sendSyncRequest(); void setThreadPriority(); void signalEvent(); void svcCloseHandle(); + void svcCreateMutex(); + void svcReleaseMutex(); void svcSleepThread(); void connectToPort(); void outputDebugString(); diff --git a/src/core/kernel/kernel.cpp b/src/core/kernel/kernel.cpp index 1a5184f3..93b16b4a 100644 --- a/src/core/kernel/kernel.cpp +++ b/src/core/kernel/kernel.cpp @@ -33,8 +33,8 @@ void Kernel::serviceSVC(u32 svc) { case 0x0A: svcSleepThread(); break; case 0x0B: getThreadPriority(); break; case 0x0C: setThreadPriority(); break; - case 0x13: createMutex(); break; - case 0x14: releaseMutex(); break; + case 0x13: svcCreateMutex(); break; + case 0x14: svcReleaseMutex(); break; case 0x17: createEvent(); break; case 0x18: signalEvent(); break; case 0x19: clearEvent(); break; diff --git a/src/core/kernel/threads.cpp b/src/core/kernel/threads.cpp index 59b3df77..b66fb902 100644 --- a/src/core/kernel/threads.cpp +++ b/src/core/kernel/threads.cpp @@ -171,6 +171,13 @@ Handle Kernel::makeMutex(bool locked) { return ret; } +void Kernel::releaseMutex(Mutex* moo) { + moo->locked = false; + if (moo->waitlist != 0) { + Helpers::panic("Mutex got freed while it's got more threads waiting for it. Must make a new thread claim it."); + } +} + Handle Kernel::makeSemaphore(u32 initialCount, u32 maximumCount) { Handle ret = makeObject(KernelObjectType::Semaphore); objects[ret].data = new Semaphore(initialCount, maximumCount); @@ -335,7 +342,7 @@ void Kernel::exitThread() { switchToNextThread(); } -void Kernel::createMutex() { +void Kernel::svcCreateMutex() { bool locked = regs[1] != 0; logSVC("CreateMutex (locked = %s)\n", locked ? "yes" : "no"); @@ -343,10 +350,24 @@ void Kernel::createMutex() { regs[1] = makeMutex(locked); } -void Kernel::releaseMutex() { +void Kernel::svcReleaseMutex() { const Handle handle = regs[0]; - logSVC("ReleaseMutex (handle = %x) (STUBBED)\n", handle); + + const auto object = getObject(handle, KernelObjectType::Mutex); + if (object == nullptr) [[unlikely]] { + Helpers::panic("Tried to release non-existent mutex"); + regs[0] = SVCResult::BadHandle; + return; + } + + Mutex* moo = object->getData(); + // A thread can't release a mutex it does not own + if (!moo->locked || moo->ownerThread != currentThreadIndex) { + Helpers::panic("[ReleaseMutex] Tried to release mutex that does not belong to thread"); + } + + releaseMutex(moo); regs[0] = SVCResult::Success; }