diff options
| author | 2015-02-02 13:04:04 -0500 | |
|---|---|---|
| committer | 2015-02-02 13:04:04 -0500 | |
| commit | 7f730ed158bc9bba064100b9644b318134ef0bb3 (patch) | |
| tree | c4181a69ff882e1af1b7d65bf3596a6cb3dd88b9 /src/core/hle/kernel/mutex.cpp | |
| parent | Merge pull request #517 from bunnei/blend-factors (diff) | |
| parent | Kernel: Stop creating useless Handles during object creation (diff) | |
| download | yuzu-7f730ed158bc9bba064100b9644b318134ef0bb3.tar.gz yuzu-7f730ed158bc9bba064100b9644b318134ef0bb3.tar.xz yuzu-7f730ed158bc9bba064100b9644b318134ef0bb3.zip | |
Merge pull request #523 from yuriks/kernel-lifetime5
Kernel Lifetime Reform Pt. 5: The Reckoning
Diffstat (limited to 'src/core/hle/kernel/mutex.cpp')
| -rw-r--r-- | src/core/hle/kernel/mutex.cpp | 41 |
1 files changed, 14 insertions, 27 deletions
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index acf484659..9f7166ca4 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | #include <map> | 5 | #include <map> |
| 6 | #include <vector> | 6 | #include <vector> |
| 7 | 7 | ||
| 8 | #include <boost/range/algorithm_ext/erase.hpp> | ||
| 9 | |||
| 8 | #include "common/common.h" | 10 | #include "common/common.h" |
| 9 | 11 | ||
| 10 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/kernel.h" |
| @@ -13,9 +15,6 @@ | |||
| 13 | 15 | ||
| 14 | namespace Kernel { | 16 | namespace Kernel { |
| 15 | 17 | ||
| 16 | typedef std::multimap<SharedPtr<Thread>, SharedPtr<Mutex>> MutexMap; | ||
| 17 | static MutexMap g_mutex_held_locks; | ||
| 18 | |||
| 19 | /** | 18 | /** |
| 20 | * Resumes a thread waiting for the specified mutex | 19 | * Resumes a thread waiting for the specified mutex |
| 21 | * @param mutex The mutex that some thread is waiting on | 20 | * @param mutex The mutex that some thread is waiting on |
| @@ -33,21 +32,17 @@ static void ResumeWaitingThread(Mutex* mutex) { | |||
| 33 | } | 32 | } |
| 34 | 33 | ||
| 35 | void ReleaseThreadMutexes(Thread* thread) { | 34 | void ReleaseThreadMutexes(Thread* thread) { |
| 36 | auto locked_range = g_mutex_held_locks.equal_range(thread); | 35 | for (auto& mtx : thread->held_mutexes) { |
| 37 | 36 | ResumeWaitingThread(mtx.get()); | |
| 38 | // Release every mutex that the thread holds, and resume execution on the waiting threads | ||
| 39 | for (auto iter = locked_range.first; iter != locked_range.second; ++iter) { | ||
| 40 | ResumeWaitingThread(iter->second.get()); | ||
| 41 | } | 37 | } |
| 42 | 38 | thread->held_mutexes.clear(); | |
| 43 | // Erase all the locks that this thread holds | ||
| 44 | g_mutex_held_locks.erase(thread); | ||
| 45 | } | 39 | } |
| 46 | 40 | ||
| 47 | ResultVal<SharedPtr<Mutex>> Mutex::Create(bool initial_locked, std::string name) { | 41 | Mutex::Mutex() {} |
| 42 | Mutex::~Mutex() {} | ||
| 43 | |||
| 44 | SharedPtr<Mutex> Mutex::Create(bool initial_locked, std::string name) { | ||
| 48 | SharedPtr<Mutex> mutex(new Mutex); | 45 | SharedPtr<Mutex> mutex(new Mutex); |
| 49 | // TOOD(yuriks): Don't create Handle (see Thread::Create()) | ||
| 50 | CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(mutex)); | ||
| 51 | 46 | ||
| 52 | mutex->initial_locked = initial_locked; | 47 | mutex->initial_locked = initial_locked; |
| 53 | mutex->locked = false; | 48 | mutex->locked = false; |
| @@ -58,7 +53,7 @@ ResultVal<SharedPtr<Mutex>> Mutex::Create(bool initial_locked, std::string name) | |||
| 58 | if (initial_locked) | 53 | if (initial_locked) |
| 59 | mutex->Acquire(); | 54 | mutex->Acquire(); |
| 60 | 55 | ||
| 61 | return MakeResult<SharedPtr<Mutex>>(mutex); | 56 | return mutex; |
| 62 | } | 57 | } |
| 63 | 58 | ||
| 64 | bool Mutex::ShouldWait() { | 59 | bool Mutex::ShouldWait() { |
| @@ -69,30 +64,22 @@ void Mutex::Acquire() { | |||
| 69 | Acquire(GetCurrentThread()); | 64 | Acquire(GetCurrentThread()); |
| 70 | } | 65 | } |
| 71 | 66 | ||
| 72 | void Mutex::Acquire(Thread* thread) { | 67 | void Mutex::Acquire(SharedPtr<Thread> thread) { |
| 73 | _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); | 68 | _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); |
| 74 | if (locked) | 69 | if (locked) |
| 75 | return; | 70 | return; |
| 76 | 71 | ||
| 77 | locked = true; | 72 | locked = true; |
| 78 | 73 | ||
| 79 | g_mutex_held_locks.insert(std::make_pair(thread, this)); | 74 | thread->held_mutexes.insert(this); |
| 80 | holding_thread = thread; | 75 | holding_thread = std::move(thread); |
| 81 | } | 76 | } |
| 82 | 77 | ||
| 83 | void Mutex::Release() { | 78 | void Mutex::Release() { |
| 84 | if (!locked) | 79 | if (!locked) |
| 85 | return; | 80 | return; |
| 86 | 81 | ||
| 87 | auto locked_range = g_mutex_held_locks.equal_range(holding_thread); | 82 | holding_thread->held_mutexes.erase(this); |
| 88 | |||
| 89 | for (MutexMap::iterator iter = locked_range.first; iter != locked_range.second; ++iter) { | ||
| 90 | if (iter->second == this) { | ||
| 91 | g_mutex_held_locks.erase(iter); | ||
| 92 | break; | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | ResumeWaitingThread(this); | 83 | ResumeWaitingThread(this); |
| 97 | } | 84 | } |
| 98 | 85 | ||