Created
January 11, 2015 23:31
-
-
Save Subv/adb040176a9fcc82f52b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/externals/boost b/externals/boost | |
--- a/externals/boost | |
+++ b/externals/boost | |
@@ -1 +1 @@ | |
-Subproject commit a1afc91d3aaa3da06bdbc13c78613e1466653405 | |
+Subproject commit a1afc91d3aaa3da06bdbc13c78613e1466653405-dirty | |
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp | |
index 271190d..7a2971a 100644 | |
--- a/src/core/hle/kernel/event.cpp | |
+++ b/src/core/hle/kernel/event.cpp | |
@@ -90,7 +90,7 @@ ResultCode SignalEvent(const Handle handle) { | |
for (size_t i = 0; i < evt->waiting_threads.size(); ++i) { | |
Thread* thread = Kernel::g_handle_table.Get<Thread>(evt->waiting_threads[i]).get(); | |
if (thread != nullptr) | |
- thread->ResumeFromWait(); | |
+ thread->ResumeFromWait(evt->GetHandle()); | |
// If any thread is signalled awake by this event, assume the event was "caught" and reset | |
// the event. This will result in the next thread waiting on the event to block. Otherwise, | |
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp | |
index 853a5dd..e7aeaaf 100644 | |
--- a/src/core/hle/kernel/mutex.cpp | |
+++ b/src/core/hle/kernel/mutex.cpp | |
@@ -54,7 +54,7 @@ bool ReleaseMutexForThread(Mutex* mutex, Handle thread_handle) { | |
return false; | |
} | |
- thread->ResumeFromWait(); | |
+ thread->ResumeFromWait(mutex->GetHandle()); | |
return true; | |
} | |
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp | |
index 88ec9a1..6151d6f 100644 | |
--- a/src/core/hle/kernel/semaphore.cpp | |
+++ b/src/core/hle/kernel/semaphore.cpp | |
@@ -86,7 +86,7 @@ ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { | |
while (!semaphore->waiting_threads.empty() && semaphore->IsAvailable()) { | |
Thread* thread = Kernel::g_handle_table.Get<Thread>(semaphore->waiting_threads.front()).get(); | |
if (thread != nullptr) | |
- thread->ResumeFromWait(); | |
+ thread->ResumeFromWait(semaphore->GetHandle()); | |
semaphore->waiting_threads.pop(); | |
--semaphore->available_count; | |
} | |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp | |
index bc86a7c..989f555 100644 | |
--- a/src/core/hle/kernel/thread.cpp | |
+++ b/src/core/hle/kernel/thread.cpp | |
@@ -112,7 +112,7 @@ void Thread::Stop(const char* reason) { | |
status = THREADSTATUS_DORMANT; | |
for (auto& waiting_thread : waiting_threads) { | |
if (CheckWaitType(waiting_thread.get(), WAITTYPE_THREADEND, this)) | |
- waiting_thread->ResumeFromWait(); | |
+ waiting_thread->ResumeFromWait(GetHandle()); | |
} | |
waiting_threads.clear(); | |
@@ -158,7 +158,7 @@ Thread* ArbitrateHighestPriorityThread(Object* arbiter, u32 address) { | |
// If a thread was arbitrated, resume it | |
if (nullptr != highest_priority_thread) { | |
- highest_priority_thread->ResumeFromWait(); | |
+ highest_priority_thread->ResumeFromWait(arbiter->GetHandle()); | |
} | |
return highest_priority_thread; | |
@@ -170,7 +170,7 @@ void ArbitrateAllThreads(Object* arbiter, u32 address) { | |
// Iterate through threads, find highest priority thread that is waiting to be arbitrated... | |
for (auto& thread : thread_list) { | |
if (CheckWaitType(thread.get(), WAITTYPE_ARB, arbiter, address)) | |
- thread->ResumeFromWait(); | |
+ thread->ResumeFromWait(arbiter->GetHandle()); | |
} | |
} | |
@@ -247,7 +247,7 @@ static void ThreadWakeupCallback(u64 parameter, int cycles_late) { | |
return; | |
} | |
- thread->ResumeFromWait(); | |
+ thread->ResumeFromWait(INVALID_HANDLE); | |
} | |
@@ -262,10 +262,25 @@ void WakeThreadAfterDelay(Thread* thread, s64 nanoseconds) { | |
} | |
/// Resumes a thread from waiting by marking it as "ready" | |
-void Thread::ResumeFromWait() { | |
+void Thread::ResumeFromWait(Handle trigger) { | |
// Cancel any outstanding wakeup events | |
CoreTiming::UnscheduleEvent(ThreadWakeupEventType, GetHandle()); | |
+ if (trigger != INVALID_HANDLE && waiting_n_sync == true && waiting_n_handles != nullptr) { | |
+ int i; | |
+ for (i = 0; i < waiting_handles_num; ++i) { | |
+ if (waiting_n_handles[i] == trigger) { | |
+ break; | |
+ } | |
+ } | |
+ | |
+ context.cpu_registers[1] = i; | |
+ HLE::Reschedule(__func__); | |
+ } | |
+ | |
+ waiting_n_sync = false; | |
+ waiting_n_handles = nullptr; | |
+ waiting_handles_num = 0; | |
status &= ~THREADSTATUS_WAIT; | |
wait_object = nullptr; | |
wait_type = WAITTYPE_NONE; | |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h | |
index 284dec4..01e3608 100644 | |
--- a/src/core/hle/kernel/thread.h | |
+++ b/src/core/hle/kernel/thread.h | |
@@ -79,7 +79,7 @@ public: | |
void Stop(const char* reason); | |
/// Resumes a thread from waiting by marking it as "ready". | |
- void ResumeFromWait(); | |
+ void ResumeFromWait(Handle trigger); | |
Core::ThreadContext context; | |
@@ -106,6 +106,10 @@ public: | |
/// Whether this thread is intended to never actually be executed, i.e. always idle | |
bool idle = false; | |
+ bool waiting_n_sync = false; | |
+ Handle* waiting_n_handles = nullptr; | |
+ int waiting_handles_num = 0; | |
+ | |
private: | |
Thread() = default; | |
}; | |
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp | |
index 3b0452d..70010ee 100644 | |
--- a/src/core/hle/kernel/timer.cpp | |
+++ b/src/core/hle/kernel/timer.cpp | |
@@ -94,7 +94,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { | |
// Resume all waiting threads | |
for (Handle thread_handle : timer->waiting_threads) { | |
if (SharedPtr<Thread> thread = Kernel::g_handle_table.Get<Thread>(thread_handle)) | |
- thread->ResumeFromWait(); | |
+ thread->ResumeFromWait(timer->GetHandle()); | |
} | |
timer->waiting_threads.clear(); | |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp | |
index d3b4483..9e660de 100644 | |
--- a/src/core/hle/svc.cpp | |
+++ b/src/core/hle/svc.cpp | |
@@ -177,6 +177,10 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, | |
return RESULT_SUCCESS.raw; | |
} | |
+ Kernel::GetCurrentThread()->waiting_n_sync = true; | |
+ Kernel::GetCurrentThread()->waiting_n_handles = handles; | |
+ Kernel::GetCurrentThread()->waiting_handles_num = handle_count; | |
+ | |
// Check for next thread to schedule | |
HLE::Reschedule(__func__); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment