diff options
| author | 2014-06-14 12:13:16 -0400 | |
|---|---|---|
| committer | 2014-06-14 12:13:16 -0400 | |
| commit | 004df767953a949817da89bddcd5d1379240f769 (patch) | |
| tree | b2d54928dcbf3cb4dde0cd5d3277afe7999b7bd9 /src/core/hle/kernel/mutex.cpp | |
| parent | GPU debugger: Const correctness and build fix. (diff) | |
| parent | Kernel: Removed unnecessary "#pragma once". (diff) | |
| download | yuzu-004df767953a949817da89bddcd5d1379240f769.tar.gz yuzu-004df767953a949817da89bddcd5d1379240f769.tar.xz yuzu-004df767953a949817da89bddcd5d1379240f769.zip | |
Merge branch 'threading' of https://github.com/bunnei/citra
Conflicts:
src/core/hle/function_wrappers.h
src/core/hle/service/gsp.cpp
Diffstat (limited to 'src/core/hle/kernel/mutex.cpp')
| -rw-r--r-- | src/core/hle/kernel/mutex.cpp | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 019efbc78..1ccf1eb73 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp | |||
| @@ -8,21 +8,51 @@ | |||
| 8 | #include "common/common.h" | 8 | #include "common/common.h" |
| 9 | 9 | ||
| 10 | #include "core/hle/kernel/kernel.h" | 10 | #include "core/hle/kernel/kernel.h" |
| 11 | #include "core/hle/kernel/mutex.h" | ||
| 11 | #include "core/hle/kernel/thread.h" | 12 | #include "core/hle/kernel/thread.h" |
| 12 | 13 | ||
| 13 | namespace Kernel { | 14 | namespace Kernel { |
| 14 | 15 | ||
| 15 | class Mutex : public Object { | 16 | class Mutex : public Object { |
| 16 | public: | 17 | public: |
| 17 | const char* GetTypeName() { return "Mutex"; } | 18 | const char* GetTypeName() const { return "Mutex"; } |
| 19 | const char* GetName() const { return name.c_str(); } | ||
| 18 | 20 | ||
| 19 | static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Mutex; } | 21 | static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Mutex; } |
| 20 | Kernel::HandleType GetHandleType() const { return Kernel::HandleType::Mutex; } | 22 | Kernel::HandleType GetHandleType() const { return Kernel::HandleType::Mutex; } |
| 21 | 23 | ||
| 22 | bool initial_locked; ///< Initial lock state when mutex was created | 24 | bool initial_locked; ///< Initial lock state when mutex was created |
| 23 | bool locked; ///< Current locked state | 25 | bool locked; ///< Current locked state |
| 24 | Handle lock_thread; ///< Handle to thread that currently has mutex | 26 | Handle lock_thread; ///< Handle to thread that currently has mutex |
| 25 | std::vector<Handle> waiting_threads; ///< Threads that are waiting for the mutex | 27 | std::vector<Handle> waiting_threads; ///< Threads that are waiting for the mutex |
| 28 | std::string name; ///< Name of mutex (optional) | ||
| 29 | |||
| 30 | /** | ||
| 31 | * Synchronize kernel object | ||
| 32 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 33 | * @return Result of operation, 0 on success, otherwise error code | ||
| 34 | */ | ||
| 35 | Result SyncRequest(bool* wait) { | ||
| 36 | // TODO(bunnei): ImplementMe | ||
| 37 | locked = true; | ||
| 38 | return 0; | ||
| 39 | } | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Wait for kernel object to synchronize | ||
| 43 | * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||
| 44 | * @return Result of operation, 0 on success, otherwise error code | ||
| 45 | */ | ||
| 46 | Result WaitSynchronization(bool* wait) { | ||
| 47 | // TODO(bunnei): ImplementMe | ||
| 48 | *wait = locked; | ||
| 49 | |||
| 50 | if (locked) { | ||
| 51 | Kernel::WaitCurrentThread(WAITTYPE_MUTEX); | ||
| 52 | } | ||
| 53 | |||
| 54 | return 0; | ||
| 55 | } | ||
| 26 | }; | 56 | }; |
| 27 | 57 | ||
| 28 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 58 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -70,10 +100,10 @@ bool ReleaseMutexForThread(Mutex* mutex, Handle thread) { | |||
| 70 | bool ReleaseMutex(Mutex* mutex) { | 100 | bool ReleaseMutex(Mutex* mutex) { |
| 71 | MutexEraseLock(mutex); | 101 | MutexEraseLock(mutex); |
| 72 | bool woke_threads = false; | 102 | bool woke_threads = false; |
| 73 | auto iter = mutex->waiting_threads.begin(); | ||
| 74 | 103 | ||
| 75 | // Find the next waiting thread for the mutex... | 104 | // Find the next waiting thread for the mutex... |
| 76 | while (!woke_threads && !mutex->waiting_threads.empty()) { | 105 | while (!woke_threads && !mutex->waiting_threads.empty()) { |
| 106 | std::vector<Handle>::iterator iter = mutex->waiting_threads.begin(); | ||
| 77 | woke_threads |= ReleaseMutexForThread(mutex, *iter); | 107 | woke_threads |= ReleaseMutexForThread(mutex, *iter); |
| 78 | mutex->waiting_threads.erase(iter); | 108 | mutex->waiting_threads.erase(iter); |
| 79 | } | 109 | } |
| @@ -91,6 +121,9 @@ bool ReleaseMutex(Mutex* mutex) { | |||
| 91 | */ | 121 | */ |
| 92 | Result ReleaseMutex(Handle handle) { | 122 | Result ReleaseMutex(Handle handle) { |
| 93 | Mutex* mutex = Kernel::g_object_pool.GetFast<Mutex>(handle); | 123 | Mutex* mutex = Kernel::g_object_pool.GetFast<Mutex>(handle); |
| 124 | |||
| 125 | _assert_msg_(KERNEL, (mutex != nullptr), "ReleaseMutex tried to release a nullptr mutex!"); | ||
| 126 | |||
| 94 | if (!ReleaseMutex(mutex)) { | 127 | if (!ReleaseMutex(mutex)) { |
| 95 | return -1; | 128 | return -1; |
| 96 | } | 129 | } |
| @@ -101,12 +134,15 @@ Result ReleaseMutex(Handle handle) { | |||
| 101 | * Creates a mutex | 134 | * Creates a mutex |
| 102 | * @param handle Reference to handle for the newly created mutex | 135 | * @param handle Reference to handle for the newly created mutex |
| 103 | * @param initial_locked Specifies if the mutex should be locked initially | 136 | * @param initial_locked Specifies if the mutex should be locked initially |
| 137 | * @param name Optional name of mutex | ||
| 138 | * @return Pointer to new Mutex object | ||
| 104 | */ | 139 | */ |
| 105 | Mutex* CreateMutex(Handle& handle, bool initial_locked) { | 140 | Mutex* CreateMutex(Handle& handle, bool initial_locked, const std::string& name) { |
| 106 | Mutex* mutex = new Mutex; | 141 | Mutex* mutex = new Mutex; |
| 107 | handle = Kernel::g_object_pool.Create(mutex); | 142 | handle = Kernel::g_object_pool.Create(mutex); |
| 108 | 143 | ||
| 109 | mutex->locked = mutex->initial_locked = initial_locked; | 144 | mutex->locked = mutex->initial_locked = initial_locked; |
| 145 | mutex->name = name; | ||
| 110 | 146 | ||
| 111 | // Acquire mutex with current thread if initialized as locked... | 147 | // Acquire mutex with current thread if initialized as locked... |
| 112 | if (mutex->locked) { | 148 | if (mutex->locked) { |
| @@ -122,10 +158,12 @@ Mutex* CreateMutex(Handle& handle, bool initial_locked) { | |||
| 122 | /** | 158 | /** |
| 123 | * Creates a mutex | 159 | * Creates a mutex |
| 124 | * @param initial_locked Specifies if the mutex should be locked initially | 160 | * @param initial_locked Specifies if the mutex should be locked initially |
| 161 | * @param name Optional name of mutex | ||
| 162 | * @return Handle to newly created object | ||
| 125 | */ | 163 | */ |
| 126 | Handle CreateMutex(bool initial_locked) { | 164 | Handle CreateMutex(bool initial_locked, const std::string& name) { |
| 127 | Handle handle; | 165 | Handle handle; |
| 128 | Mutex* mutex = CreateMutex(handle, initial_locked); | 166 | Mutex* mutex = CreateMutex(handle, initial_locked, name); |
| 129 | return handle; | 167 | return handle; |
| 130 | } | 168 | } |
| 131 | 169 | ||