summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorSubv <subv2112@gmail.com>2017-01-04 16:53:01 +0100
committerSubv <subv2112@gmail.com>2017-01-05 15:40:14 +0100
commitfd95b6ee2606da4cd47c5f2916ad3b4f86c0e0f4 (patch)
tree5a3d1487e24f089b68358ddd8984c12e65623055 /src/core/hle/kernel
parentKernel: Use different thread statuses when a thread calls WaitSynchronization1 and WaitSynchronizationN with wait_all = true. (diff)
downloadyuzu-fd95b6ee2606da4cd47c5f2916ad3b4f86c0e0f4.tar
yuzu-fd95b6ee2606da4cd47c5f2916ad3b4f86c0e0f4.tar.gz
yuzu-fd95b6ee2606da4cd47c5f2916ad3b4f86c0e0f4.tar.bz2
yuzu-fd95b6ee2606da4cd47c5f2916ad3b4f86c0e0f4.tar.lz
yuzu-fd95b6ee2606da4cd47c5f2916ad3b4f86c0e0f4.tar.xz
yuzu-fd95b6ee2606da4cd47c5f2916ad3b4f86c0e0f4.tar.zst
yuzu-fd95b6ee2606da4cd47c5f2916ad3b4f86c0e0f4.zip
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/kernel.cpp8
-rw-r--r--src/core/hle/kernel/thread.cpp5
-rw-r--r--src/core/hle/kernel/thread.h16
3 files changed, 19 insertions, 10 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 6f61d526a..955f50a9b 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -55,10 +55,16 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
if (ShouldWait(thread.get()))
continue;
- bool ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(),
+ // A thread is ready to run if it's either in THREADSTATUS_WAIT_SYNCH_ANY or
+ // in THREADSTATUS_WAIT_SYNCH_ALL and the rest of the objects it is waiting on are ready.
+ bool ready_to_run = true;
+ if (thread->status == THREADSTATUS_WAIT_SYNCH_ALL) {
+ ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(),
[&thread](const SharedPtr<WaitObject>& object) {
return object->ShouldWait(thread.get());
});
+ }
+
if (ready_to_run) {
candidate = thread.get();
candidate_priority = thread->current_priority;
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index aa99d18c7..568cef5b9 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -579,6 +579,11 @@ void Thread::SetWaitSynchronizationOutput(s32 output) {
context.cpu_registers[1] = output;
}
+s32 Thread::GetWaitObjectIndex(WaitObject* object) const {
+ auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object);
+ return std::distance(match, wait_objects.rend()) - 1;
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
void ThreadingInit() {
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 6cd8c20e2..af72b76ea 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -135,13 +135,14 @@ public:
/**
* Retrieves the index that this particular object occupies in the list of objects
- * that the thread passed to WaitSynchronizationN.
+ * that the thread passed to WaitSynchronizationN, starting the search from the last element.
* It is used to set the output value of WaitSynchronizationN when the thread is awakened.
+ * When a thread wakes up due to an object signal, the kernel will use the index of the last
+ * matching object in the wait objects list in case of having multiple instances of the same
+ * object in the list.
* @param object Object to query the index of.
*/
- s32 GetWaitObjectIndex(const WaitObject* object) const {
- return wait_objects_index.at(object->GetObjectId());
- }
+ s32 GetWaitObjectIndex(WaitObject* object) const;
/**
* Stops a thread, invalidating it from further use
@@ -190,13 +191,10 @@ public:
SharedPtr<Process> owner_process; ///< Process that owns this thread
- /// Objects that the thread is waiting on.
- /// This is only populated when the thread should wait for all the objects to become ready.
+ /// Objects that the thread is waiting on, in the same order as they were
+ // passed to WaitSynchronization1/N.
std::vector<SharedPtr<WaitObject>> wait_objects;
- /// Mapping of Object ids to their position in the last waitlist that this object waited on.
- boost::container::flat_map<int, s32> wait_objects_index;
-
VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address
/// True if the WaitSynchronizationN output parameter should be set on thread wakeup.