diff options
| author | 2015-01-18 13:56:40 -0500 | |
|---|---|---|
| committer | 2015-01-21 20:47:45 -0500 | |
| commit | 254e4ebd58a31e8462b70799f95f096d0d0038f2 (patch) | |
| tree | e8e475ec7af1ba2df06b7f44298408f51a89a116 /src/core/hle/kernel | |
| parent | Kernel: Get rid of WaitTypes and simplify lots of code, removing hacks. (diff) | |
| download | yuzu-254e4ebd58a31e8462b70799f95f096d0d0038f2.tar.gz yuzu-254e4ebd58a31e8462b70799f95f096d0d0038f2.tar.xz yuzu-254e4ebd58a31e8462b70799f95f096d0d0038f2.zip | |
AddressArbiter: Changed to Kernel::Object, big cleanup, removed code that made no sense.
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 42 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 17 |
4 files changed, 42 insertions, 35 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 520601455..9e855b0bf 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | namespace Kernel { | 16 | namespace Kernel { |
| 17 | 17 | ||
| 18 | class AddressArbiter : public WaitObject { | 18 | class AddressArbiter : public Object { |
| 19 | public: | 19 | public: |
| 20 | std::string GetTypeName() const override { return "Arbiter"; } | 20 | std::string GetTypeName() const override { return "Arbiter"; } |
| 21 | std::string GetName() const override { return name; } | 21 | std::string GetName() const override { return name; } |
| @@ -30,7 +30,7 @@ public: | |||
| 30 | 30 | ||
| 31 | /// Arbitrate an address | 31 | /// Arbitrate an address |
| 32 | ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value, u64 nanoseconds) { | 32 | ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value, u64 nanoseconds) { |
| 33 | WaitObject* object = static_cast<WaitObject*>(Kernel::g_handle_table.GetGeneric(handle).get()); | 33 | AddressArbiter* object = Kernel::g_handle_table.Get<AddressArbiter>(handle).get(); |
| 34 | 34 | ||
| 35 | if (object == nullptr) | 35 | if (object == nullptr) |
| 36 | return InvalidHandle(ErrorModule::Kernel); | 36 | return InvalidHandle(ErrorModule::Kernel); |
| @@ -41,24 +41,24 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3 | |||
| 41 | case ArbitrationType::Signal: | 41 | case ArbitrationType::Signal: |
| 42 | // Negative value means resume all threads | 42 | // Negative value means resume all threads |
| 43 | if (value < 0) { | 43 | if (value < 0) { |
| 44 | ArbitrateAllThreads(object, address); | 44 | ArbitrateAllThreads(address); |
| 45 | } else { | 45 | } else { |
| 46 | // Resume first N threads | 46 | // Resume first N threads |
| 47 | for(int i = 0; i < value; i++) | 47 | for(int i = 0; i < value; i++) |
| 48 | ArbitrateHighestPriorityThread(object, address); | 48 | ArbitrateHighestPriorityThread(address); |
| 49 | } | 49 | } |
| 50 | break; | 50 | break; |
| 51 | 51 | ||
| 52 | // Wait current thread (acquire the arbiter)... | 52 | // Wait current thread (acquire the arbiter)... |
| 53 | case ArbitrationType::WaitIfLessThan: | 53 | case ArbitrationType::WaitIfLessThan: |
| 54 | if ((s32)Memory::Read32(address) <= value) { | 54 | if ((s32)Memory::Read32(address) <= value) { |
| 55 | Kernel::WaitCurrentThread_ArbitrateAddress(object, address); | 55 | Kernel::WaitCurrentThread_ArbitrateAddress(address); |
| 56 | HLE::Reschedule(__func__); | 56 | HLE::Reschedule(__func__); |
| 57 | } | 57 | } |
| 58 | break; | 58 | break; |
| 59 | case ArbitrationType::WaitIfLessThanWithTimeout: | 59 | case ArbitrationType::WaitIfLessThanWithTimeout: |
| 60 | if ((s32)Memory::Read32(address) <= value) { | 60 | if ((s32)Memory::Read32(address) <= value) { |
| 61 | Kernel::WaitCurrentThread_ArbitrateAddress(object, address); | 61 | Kernel::WaitCurrentThread_ArbitrateAddress(address); |
| 62 | Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds); | 62 | Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds); |
| 63 | HLE::Reschedule(__func__); | 63 | HLE::Reschedule(__func__); |
| 64 | } | 64 | } |
| @@ -68,7 +68,7 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3 | |||
| 68 | s32 memory_value = Memory::Read32(address) - 1; | 68 | s32 memory_value = Memory::Read32(address) - 1; |
| 69 | Memory::Write32(address, memory_value); | 69 | Memory::Write32(address, memory_value); |
| 70 | if (memory_value <= value) { | 70 | if (memory_value <= value) { |
| 71 | Kernel::WaitCurrentThread_ArbitrateAddress(object, address); | 71 | Kernel::WaitCurrentThread_ArbitrateAddress(address); |
| 72 | HLE::Reschedule(__func__); | 72 | HLE::Reschedule(__func__); |
| 73 | } | 73 | } |
| 74 | break; | 74 | break; |
| @@ -78,7 +78,7 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3 | |||
| 78 | s32 memory_value = Memory::Read32(address) - 1; | 78 | s32 memory_value = Memory::Read32(address) - 1; |
| 79 | Memory::Write32(address, memory_value); | 79 | Memory::Write32(address, memory_value); |
| 80 | if (memory_value <= value) { | 80 | if (memory_value <= value) { |
| 81 | Kernel::WaitCurrentThread_ArbitrateAddress(object, address); | 81 | Kernel::WaitCurrentThread_ArbitrateAddress(address); |
| 82 | Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds); | 82 | Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds); |
| 83 | HLE::Reschedule(__func__); | 83 | HLE::Reschedule(__func__); |
| 84 | } | 84 | } |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 57e0e8df7..b3ca78ed6 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -36,7 +36,7 @@ Thread* WaitObject::ReleaseNextThread() { | |||
| 36 | 36 | ||
| 37 | auto next_thread = waiting_threads.front(); | 37 | auto next_thread = waiting_threads.front(); |
| 38 | 38 | ||
| 39 | next_thread->ReleaseFromWait(this); | 39 | next_thread->ReleaseWaitObject(this); |
| 40 | waiting_threads.erase(waiting_threads.begin()); | 40 | waiting_threads.erase(waiting_threads.begin()); |
| 41 | 41 | ||
| 42 | return next_thread.get(); | 42 | return next_thread.get(); |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 601e0eb20..16865ccc4 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -83,8 +83,8 @@ static void ChangeReadyState(Thread* t, bool ready) { | |||
| 83 | } | 83 | } |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | /// Check if a thread is blocking on a the specified object | 86 | /// Check if a thread is waiting on a the specified wait object |
| 87 | static bool CheckWaitType(const Thread* thread, Object* wait_object) { | 87 | static bool CheckWait_WaitObject(const Thread* thread, WaitObject* wait_object) { |
| 88 | for (auto itr = thread->wait_objects.begin(); itr != thread->wait_objects.end(); ++itr) { | 88 | for (auto itr = thread->wait_objects.begin(); itr != thread->wait_objects.end(); ++itr) { |
| 89 | if (*itr == wait_object) | 89 | if (*itr == wait_object) |
| 90 | return (thread->IsWaiting()); | 90 | return (thread->IsWaiting()); |
| @@ -92,9 +92,9 @@ static bool CheckWaitType(const Thread* thread, Object* wait_object) { | |||
| 92 | return false; | 92 | return false; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | /// Check if a thread is blocking on a the specified object and an address | 95 | /// Check if the specified thread is waiting on the specified address to be arbitrated |
| 96 | static bool CheckWaitType(const Thread* thread, Object* wait_object, VAddr wait_address) { | 96 | static bool CheckWait_AddressArbiter(const Thread* thread, VAddr wait_address) { |
| 97 | return CheckWaitType(thread, wait_object) && (wait_address == thread->wait_address); | 97 | return thread->IsWaiting() && thread->wait_objects.empty() && wait_address == thread->wait_address; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | /// Stops the current thread | 100 | /// Stops the current thread |
| @@ -121,17 +121,17 @@ static void ChangeThreadState(Thread* t, ThreadStatus new_status) { | |||
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | /// Arbitrate the highest priority thread that is waiting | 123 | /// Arbitrate the highest priority thread that is waiting |
| 124 | Thread* ArbitrateHighestPriorityThread(WaitObject* arbiter, u32 address) { | 124 | Thread* ArbitrateHighestPriorityThread(u32 address) { |
| 125 | Thread* highest_priority_thread = nullptr; | 125 | Thread* highest_priority_thread = nullptr; |
| 126 | s32 priority = THREADPRIO_LOWEST; | 126 | s32 priority = THREADPRIO_LOWEST; |
| 127 | 127 | ||
| 128 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... | 128 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... |
| 129 | for (auto& thread : thread_list) { | 129 | for (auto& thread : thread_list) { |
| 130 | if (!CheckWaitType(thread.get(), arbiter, address)) | 130 | if (!CheckWait_AddressArbiter(thread.get(), address)) |
| 131 | continue; | 131 | continue; |
| 132 | 132 | ||
| 133 | if (thread == nullptr) | 133 | if (thread == nullptr) |
| 134 | continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up. | 134 | continue; |
| 135 | 135 | ||
| 136 | if(thread->current_priority <= priority) { | 136 | if(thread->current_priority <= priority) { |
| 137 | highest_priority_thread = thread.get(); | 137 | highest_priority_thread = thread.get(); |
| @@ -141,19 +141,19 @@ Thread* ArbitrateHighestPriorityThread(WaitObject* arbiter, u32 address) { | |||
| 141 | 141 | ||
| 142 | // If a thread was arbitrated, resume it | 142 | // If a thread was arbitrated, resume it |
| 143 | if (nullptr != highest_priority_thread) { | 143 | if (nullptr != highest_priority_thread) { |
| 144 | highest_priority_thread->ReleaseFromWait(arbiter); | 144 | highest_priority_thread->ResumeFromWait(); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | return highest_priority_thread; | 147 | return highest_priority_thread; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | /// Arbitrate all threads currently waiting | 150 | /// Arbitrate all threads currently waiting |
| 151 | void ArbitrateAllThreads(WaitObject* arbiter, u32 address) { | 151 | void ArbitrateAllThreads(u32 address) { |
| 152 | 152 | ||
| 153 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... | 153 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... |
| 154 | for (auto& thread : thread_list) { | 154 | for (auto& thread : thread_list) { |
| 155 | if (CheckWaitType(thread.get(), arbiter, address)) | 155 | if (CheckWait_AddressArbiter(thread.get(), address)) |
| 156 | thread->ReleaseFromWait(arbiter); | 156 | thread->ResumeFromWait(); |
| 157 | } | 157 | } |
| 158 | } | 158 | } |
| 159 | 159 | ||
| @@ -202,21 +202,28 @@ static Thread* NextThread() { | |||
| 202 | return next; | 202 | return next; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | void WaitCurrentThread() { | 205 | void WaitCurrentThread_Sleep() { |
| 206 | Thread* thread = GetCurrentThread(); | 206 | Thread* thread = GetCurrentThread(); |
| 207 | thread->wait_all = false; | ||
| 208 | thread->wait_address = 0; | ||
| 209 | thread->wait_objects.clear(); | ||
| 207 | ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); | 210 | ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); |
| 208 | } | 211 | } |
| 209 | 212 | ||
| 210 | void WaitCurrentThread_WaitSynchronization(WaitObject* wait_object, bool wait_all) { | 213 | void WaitCurrentThread_WaitSynchronization(WaitObject* wait_object, bool wait_all) { |
| 211 | Thread* thread = GetCurrentThread(); | 214 | Thread* thread = GetCurrentThread(); |
| 212 | thread->wait_all = wait_all; | 215 | thread->wait_all = wait_all; |
| 216 | thread->wait_address = 0; | ||
| 213 | thread->wait_objects.push_back(wait_object); | 217 | thread->wait_objects.push_back(wait_object); |
| 214 | ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); | 218 | ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); |
| 215 | } | 219 | } |
| 216 | 220 | ||
| 217 | void WaitCurrentThread_ArbitrateAddress(WaitObject* wait_object, VAddr wait_address) { | 221 | void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) { |
| 218 | WaitCurrentThread_WaitSynchronization(wait_object); | 222 | Thread* thread = GetCurrentThread(); |
| 219 | GetCurrentThread()->wait_address = wait_address; | 223 | thread->wait_all = false; |
| 224 | thread->wait_address = wait_address; | ||
| 225 | thread->wait_objects.clear(); | ||
| 226 | ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); | ||
| 220 | } | 227 | } |
| 221 | 228 | ||
| 222 | /// Event type for the thread wake up event | 229 | /// Event type for the thread wake up event |
| @@ -248,7 +255,7 @@ void WakeThreadAfterDelay(Thread* thread, s64 nanoseconds) { | |||
| 248 | CoreTiming::ScheduleEvent(usToCycles(microseconds), ThreadWakeupEventType, thread->GetHandle()); | 255 | CoreTiming::ScheduleEvent(usToCycles(microseconds), ThreadWakeupEventType, thread->GetHandle()); |
| 249 | } | 256 | } |
| 250 | 257 | ||
| 251 | void Thread::ReleaseFromWait(WaitObject* wait_object) { | 258 | void Thread::ReleaseWaitObject(WaitObject* wait_object) { |
| 252 | if (wait_objects.empty()) { | 259 | if (wait_objects.empty()) { |
| 253 | LOG_CRITICAL(Kernel, "thread is not waiting on any objects!"); | 260 | LOG_CRITICAL(Kernel, "thread is not waiting on any objects!"); |
| 254 | return; | 261 | return; |
| @@ -298,6 +305,7 @@ void Thread::ResumeFromWait() { | |||
| 298 | 305 | ||
| 299 | wait_objects.clear(); | 306 | wait_objects.clear(); |
| 300 | wait_all = false; | 307 | wait_all = false; |
| 308 | wait_address = 0; | ||
| 301 | 309 | ||
| 302 | if (!(status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { | 310 | if (!(status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { |
| 303 | ChangeReadyState(this, true); | 311 | ChangeReadyState(this, true); |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index cb48fcadc..9907aa6e1 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -69,10 +69,10 @@ public: | |||
| 69 | void Stop(const char* reason); | 69 | void Stop(const char* reason); |
| 70 | 70 | ||
| 71 | /** | 71 | /** |
| 72 | * Release an object from the thread's wait list | 72 | * Release an acquired wait object |
| 73 | * @param wait_object WaitObject to release from the thread's wait list | 73 | * @param wait_object WaitObject to release |
| 74 | */ | 74 | */ |
| 75 | void ReleaseFromWait(WaitObject* wait_object); | 75 | void ReleaseWaitObject(WaitObject* wait_object); |
| 76 | 76 | ||
| 77 | /// Resumes a thread from waiting by marking it as "ready" | 77 | /// Resumes a thread from waiting by marking it as "ready" |
| 78 | void ResumeFromWait(); | 78 | void ResumeFromWait(); |
| @@ -120,16 +120,16 @@ SharedPtr<Thread> SetupMainThread(s32 priority, u32 stack_size); | |||
| 120 | void Reschedule(); | 120 | void Reschedule(); |
| 121 | 121 | ||
| 122 | /// Arbitrate the highest priority thread that is waiting | 122 | /// Arbitrate the highest priority thread that is waiting |
| 123 | Thread* ArbitrateHighestPriorityThread(WaitObject* arbiter, u32 address); | 123 | Thread* ArbitrateHighestPriorityThread(u32 address); |
| 124 | 124 | ||
| 125 | /// Arbitrate all threads currently waiting... | 125 | /// Arbitrate all threads currently waiting... |
| 126 | void ArbitrateAllThreads(WaitObject* arbiter, u32 address); | 126 | void ArbitrateAllThreads(u32 address); |
| 127 | 127 | ||
| 128 | /// Gets the current thread | 128 | /// Gets the current thread |
| 129 | Thread* GetCurrentThread(); | 129 | Thread* GetCurrentThread(); |
| 130 | 130 | ||
| 131 | /// Waits the current thread | 131 | /// Waits the current thread on a sleep |
| 132 | void WaitCurrentThread(); | 132 | void WaitCurrentThread_Sleep(); |
| 133 | 133 | ||
| 134 | /** | 134 | /** |
| 135 | * Waits the current thread from a WaitSynchronization call | 135 | * Waits the current thread from a WaitSynchronization call |
| @@ -140,10 +140,9 @@ void WaitCurrentThread_WaitSynchronization(WaitObject* wait_object, bool wait_al | |||
| 140 | 140 | ||
| 141 | /** | 141 | /** |
| 142 | * Waits the current thread from an ArbitrateAddress call | 142 | * Waits the current thread from an ArbitrateAddress call |
| 143 | * @param wait_object Kernel object that we are waiting on | ||
| 144 | * @param wait_address Arbitration address used to resume from wait | 143 | * @param wait_address Arbitration address used to resume from wait |
| 145 | */ | 144 | */ |
| 146 | void WaitCurrentThread_ArbitrateAddress(WaitObject* wait_object, VAddr wait_address); | 145 | void WaitCurrentThread_ArbitrateAddress(VAddr wait_address); |
| 147 | 146 | ||
| 148 | /** | 147 | /** |
| 149 | * Schedules an event to wake up the specified thread after the specified delay. | 148 | * Schedules an event to wake up the specified thread after the specified delay. |