mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-09 07:35:41 +12:00
Merge pull request #169 from wheremyfoodat/mutex-free
[Kernel] ExitThread should release held mutexes
This commit is contained in:
commit
814fa8023e
3 changed files with 25 additions and 0 deletions
|
@ -34,6 +34,7 @@ class Kernel {
|
||||||
|
|
||||||
std::vector<KernelObject> objects;
|
std::vector<KernelObject> objects;
|
||||||
std::vector<Handle> portHandles;
|
std::vector<Handle> portHandles;
|
||||||
|
std::vector<Handle> mutexHandles;
|
||||||
|
|
||||||
// Thread indices, sorted by priority
|
// Thread indices, sorted by priority
|
||||||
std::vector<int> threadIndices;
|
std::vector<int> threadIndices;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
Kernel::Kernel(CPU& cpu, Memory& mem, GPU& gpu)
|
Kernel::Kernel(CPU& cpu, Memory& mem, GPU& gpu)
|
||||||
: cpu(cpu), regs(cpu.regs()), mem(mem), handleCounter(0), serviceManager(regs, mem, gpu, currentProcess, *this) {
|
: cpu(cpu), regs(cpu.regs()), mem(mem), handleCounter(0), serviceManager(regs, mem, gpu, currentProcess, *this) {
|
||||||
objects.reserve(512); // Make room for a few objects to avoid further memory allocs later
|
objects.reserve(512); // Make room for a few objects to avoid further memory allocs later
|
||||||
|
mutexHandles.reserve(8);
|
||||||
portHandles.reserve(32);
|
portHandles.reserve(32);
|
||||||
threadIndices.reserve(appResourceLimits.maxThreads);
|
threadIndices.reserve(appResourceLimits.maxThreads);
|
||||||
|
|
||||||
|
@ -139,6 +140,7 @@ void Kernel::reset() {
|
||||||
deleteObjectData(object);
|
deleteObjectData(object);
|
||||||
}
|
}
|
||||||
objects.clear();
|
objects.clear();
|
||||||
|
mutexHandles.clear();
|
||||||
portHandles.clear();
|
portHandles.clear();
|
||||||
threadIndices.clear();
|
threadIndices.clear();
|
||||||
serviceManager.reset();
|
serviceManager.reset();
|
||||||
|
|
|
@ -168,6 +168,11 @@ Handle Kernel::makeMutex(bool locked) {
|
||||||
moo->ownerThread = currentThreadIndex;
|
moo->ownerThread = currentThreadIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Push the new mutex to our list of mutex handles
|
||||||
|
// We need a list of mutex handles so that when a thread is killed, we can look which mutexes from this list the thread owns and free them
|
||||||
|
// Alternatively this could be a per-thread list, but I don't want to push_back and remove on every mutex lock and release
|
||||||
|
// Since some mutexes like the APT service mutex are locked and unlocked constantly, while ExitThread is a relatively "rare" SVC
|
||||||
|
mutexHandles.push_back(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,6 +471,23 @@ void Kernel::setThreadPriority() {
|
||||||
void Kernel::exitThread() {
|
void Kernel::exitThread() {
|
||||||
logSVC("ExitThread\n");
|
logSVC("ExitThread\n");
|
||||||
|
|
||||||
|
// Find which mutexes this thread owns, release them
|
||||||
|
for (auto handle : mutexHandles) {
|
||||||
|
KernelObject* object = getObject(handle, KernelObjectType::Mutex);
|
||||||
|
|
||||||
|
// Make sure that the handle actually matches to a mutex, and if our exiting thread owns the mutex, release it
|
||||||
|
if (object != nullptr) {
|
||||||
|
Mutex* moo = object->getData<Mutex>();
|
||||||
|
|
||||||
|
if (moo->locked && moo->ownerThread == currentThreadIndex) {
|
||||||
|
// Release the mutex by setting lock count to 1 and releasing it once. We set lock count to 1 since it's a recursive mutex
|
||||||
|
// Therefore if its lock count was > 1, simply calling releaseMutex would not fully release it
|
||||||
|
moo->lockCount = 1;
|
||||||
|
releaseMutex(moo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove the index of this thread from the thread indices vector
|
// Remove the index of this thread from the thread indices vector
|
||||||
for (int i = 0; i < threadIndices.size(); i++) {
|
for (int i = 0; i < threadIndices.size(); i++) {
|
||||||
if (threadIndices[i] == currentThreadIndex)
|
if (threadIndices[i] == currentThreadIndex)
|
||||||
|
|
Loading…
Add table
Reference in a new issue