summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp19
-rw-r--r--src/core/hle/kernel/svc.cpp5
-rw-r--r--src/core/hle/kernel/synchronization.cpp1
-rw-r--r--src/core/hle/kernel/thread.cpp35
-rw-r--r--src/core/hle/kernel/thread.h16
5 files changed, 39 insertions, 37 deletions
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 955d5fe1c..e74d91670 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -21,8 +21,8 @@
21#include "core/hle/kernel/object.h" 21#include "core/hle/kernel/object.h"
22#include "core/hle/kernel/process.h" 22#include "core/hle/kernel/process.h"
23#include "core/hle/kernel/readable_event.h" 23#include "core/hle/kernel/readable_event.h"
24#include "core/hle/kernel/server_session.h"
25#include "core/hle/kernel/scheduler.h" 24#include "core/hle/kernel/scheduler.h"
25#include "core/hle/kernel/server_session.h"
26#include "core/hle/kernel/thread.h" 26#include "core/hle/kernel/thread.h"
27#include "core/hle/kernel/time_manager.h" 27#include "core/hle/kernel/time_manager.h"
28#include "core/hle/kernel/writable_event.h" 28#include "core/hle/kernel/writable_event.h"
@@ -49,14 +49,6 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
49 const std::string& reason, u64 timeout, WakeupCallback&& callback, 49 const std::string& reason, u64 timeout, WakeupCallback&& callback,
50 std::shared_ptr<WritableEvent> writable_event) { 50 std::shared_ptr<WritableEvent> writable_event) {
51 // Put the client thread to sleep until the wait event is signaled or the timeout expires. 51 // Put the client thread to sleep until the wait event is signaled or the timeout expires.
52 thread->SetHLECallback(
53 [context = *this, callback](ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
54 std::shared_ptr<SynchronizationObject> object,
55 std::size_t index) mutable -> bool {
56 callback(thread, context, reason);
57 context.WriteToOutgoingCommandBuffer(*thread);
58 return true;
59 });
60 52
61 if (!writable_event) { 53 if (!writable_event) {
62 // Create event if not provided 54 // Create event if not provided
@@ -67,6 +59,15 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
67 { 59 {
68 Handle event_handle = InvalidHandle; 60 Handle event_handle = InvalidHandle;
69 SchedulerLockAndSleep lock(kernel, event_handle, thread.get(), timeout); 61 SchedulerLockAndSleep lock(kernel, event_handle, thread.get(), timeout);
62 thread->SetHLECallback(
63 [context = *this, callback](std::shared_ptr<Thread> thread) mutable -> bool {
64 ThreadWakeupReason reason = thread->GetSignalingResult() == RESULT_TIMEOUT
65 ? ThreadWakeupReason::Timeout
66 : ThreadWakeupReason::Signal;
67 callback(thread, context, reason);
68 context.WriteToOutgoingCommandBuffer(*thread);
69 return true;
70 });
70 const auto readable_event{writable_event->GetReadableEvent()}; 71 const auto readable_event{writable_event->GetReadableEvent()};
71 writable_event->Clear(); 72 writable_event->Clear();
72 thread->SetStatus(ThreadStatus::WaitHLEEvent); 73 thread->SetStatus(ThreadStatus::WaitHLEEvent);
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 4c1040a3b..9f46a1758 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -333,17 +333,16 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
333 thread->SetStatus(ThreadStatus::WaitIPC); 333 thread->SetStatus(ThreadStatus::WaitIPC);
334 session->SendSyncRequest(SharedFrom(thread), system.Memory()); 334 session->SendSyncRequest(SharedFrom(thread), system.Memory());
335 } 335 }
336 ResultCode result = thread->GetSignalingResult();
337 if (thread->HasHLECallback()) { 336 if (thread->HasHLECallback()) {
338 Handle event_handle = thread->GetHLETimeEvent(); 337 Handle event_handle = thread->GetHLETimeEvent();
339 if (event_handle != InvalidHandle) { 338 if (event_handle != InvalidHandle) {
340 auto& time_manager = system.Kernel().TimeManager(); 339 auto& time_manager = system.Kernel().TimeManager();
341 time_manager.UnscheduleTimeEvent(event_handle); 340 time_manager.UnscheduleTimeEvent(event_handle);
342 } 341 }
343 thread->InvokeHLECallback(ThreadWakeupReason::Timeout, SharedFrom(thread), nullptr, 0); 342 thread->InvokeHLECallback(SharedFrom(thread));
344 } 343 }
345 344
346 return result; 345 return RESULT_SUCCESS;
347} 346}
348 347
349static ResultCode SendSyncRequest32(Core::System& system, Handle handle) { 348static ResultCode SendSyncRequest32(Core::System& system, Handle handle) {
diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp
index c60c5bb42..4ee7ad93c 100644
--- a/src/core/hle/kernel/synchronization.cpp
+++ b/src/core/hle/kernel/synchronization.cpp
@@ -28,6 +28,7 @@ void Synchronization::SignalObject(SynchronizationObject& obj) const {
28 time_manager.CancelTimeEvent(thread.get()); 28 time_manager.CancelTimeEvent(thread.get());
29 } 29 }
30 } 30 }
31 obj.ClearWaitingThreads();
31 } 32 }
32} 33}
33 34
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index a645ee3a2..16babe71a 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -47,19 +47,21 @@ Thread::Thread(KernelCore& kernel) : SynchronizationObject{kernel} {}
47Thread::~Thread() = default; 47Thread::~Thread() = default;
48 48
49void Thread::Stop() { 49void Thread::Stop() {
50 SchedulerLock lock(kernel); 50 {
51 // Cancel any outstanding wakeup events for this thread 51 SchedulerLock lock(kernel);
52 Signal(); 52 // Cancel any outstanding wakeup events for this thread
53 Core::System::GetInstance().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), 53 Signal();
54 global_handle); 54 Core::System::GetInstance().CoreTiming().UnscheduleEvent(
55 kernel.GlobalHandleTable().Close(global_handle); 55 kernel.ThreadWakeupCallbackEventType(), global_handle);
56 global_handle = 0; 56 kernel.GlobalHandleTable().Close(global_handle);
57 SetStatus(ThreadStatus::Dead); 57 SetStatus(ThreadStatus::Dead);
58 58
59 owner_process->UnregisterThread(this); 59 owner_process->UnregisterThread(this);
60 60
61 // Mark the TLS slot in the thread's page as free. 61 // Mark the TLS slot in the thread's page as free.
62 owner_process->FreeTLSRegion(tls_address); 62 owner_process->FreeTLSRegion(tls_address);
63 }
64 global_handle = 0;
63} 65}
64 66
65void Thread::WakeAfterDelay(s64 nanoseconds) { 67void Thread::WakeAfterDelay(s64 nanoseconds) {
@@ -112,8 +114,6 @@ void Thread::ResumeFromWait() {
112 return; 114 return;
113 } 115 }
114 116
115 hle_callback = nullptr;
116
117 if (activity == ThreadActivity::Paused) { 117 if (activity == ThreadActivity::Paused) {
118 SetStatus(ThreadStatus::Paused); 118 SetStatus(ThreadStatus::Paused);
119 return; 119 return;
@@ -398,14 +398,13 @@ bool Thread::AllSynchronizationObjectsReady() const {
398bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, 398bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
399 std::shared_ptr<SynchronizationObject> object, 399 std::shared_ptr<SynchronizationObject> object,
400 std::size_t index) { 400 std::size_t index) {
401 ASSERT(hle_callback); 401 ASSERT(wakeup_callback);
402 return hle_callback(reason, std::move(thread), std::move(object), index); 402 return wakeup_callback(reason, std::move(thread), std::move(object), index);
403} 403}
404 404
405bool Thread::InvokeHLECallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, 405bool Thread::InvokeHLECallback(std::shared_ptr<Thread> thread) {
406 std::shared_ptr<SynchronizationObject> object, std::size_t index) {
407 ASSERT(hle_callback); 406 ASSERT(hle_callback);
408 return hle_callback(reason, std::move(thread), std::move(object), index); 407 return hle_callback(std::move(thread));
409} 408}
410 409
411void Thread::SetActivity(ThreadActivity value) { 410void Thread::SetActivity(ThreadActivity value) {
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 04496f96e..c4c9d69ec 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -448,7 +448,7 @@ public:
448 } 448 }
449 449
450 bool HasWakeupCallback() const { 450 bool HasWakeupCallback() const {
451 return hle_callback != nullptr; 451 return wakeup_callback != nullptr;
452 } 452 }
453 453
454 bool HasHLECallback() const { 454 bool HasHLECallback() const {
@@ -456,10 +456,10 @@ public:
456 } 456 }
457 457
458 void SetWakeupCallback(WakeupCallback callback) { 458 void SetWakeupCallback(WakeupCallback callback) {
459 hle_callback = std::move(callback); 459 wakeup_callback = std::move(callback);
460 } 460 }
461 461
462 void SetHLECallback(WakeupCallback callback) { 462 void SetHLECallback(HLECallback callback) {
463 hle_callback = std::move(callback); 463 hle_callback = std::move(callback);
464 } 464 }
465 465
@@ -487,8 +487,7 @@ public:
487 */ 487 */
488 bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, 488 bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
489 std::shared_ptr<SynchronizationObject> object, std::size_t index); 489 std::shared_ptr<SynchronizationObject> object, std::size_t index);
490 bool InvokeHLECallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, 490 bool InvokeHLECallback(std::shared_ptr<Thread> thread);
491 std::shared_ptr<SynchronizationObject> object, std::size_t index);
492 491
493 u32 GetIdealCore() const { 492 u32 GetIdealCore() const {
494 return ideal_core; 493 return ideal_core;
@@ -622,8 +621,11 @@ private:
622 621
623 /// Callback that will be invoked when the thread is resumed from a waiting state. If the thread 622 /// Callback that will be invoked when the thread is resumed from a waiting state. If the thread
624 /// was waiting via WaitSynchronization then the object will be the last object that became 623 /// was waiting via WaitSynchronization then the object will be the last object that became
625 /// available. In case of a timeout, the object will be nullptr. 624 /// available. In case of a timeout, the object will be nullptr. DEPRECATED
626 WakeupCallback hle_callback; 625 WakeupCallback wakeup_callback;
626
627 /// Callback for HLE Events
628 HLECallback hle_callback;
627 Handle hle_time_event; 629 Handle hle_time_event;
628 630
629 Scheduler* scheduler = nullptr; 631 Scheduler* scheduler = nullptr;