diff options
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 19 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/synchronization.cpp | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 35 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 16 |
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 | ||
| 349 | static ResultCode SendSyncRequest32(Core::System& system, Handle handle) { | 348 | static 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} {} | |||
| 47 | Thread::~Thread() = default; | 47 | Thread::~Thread() = default; |
| 48 | 48 | ||
| 49 | void Thread::Stop() { | 49 | void 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 | ||
| 65 | void Thread::WakeAfterDelay(s64 nanoseconds) { | 67 | void 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 { | |||
| 398 | bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | 398 | bool 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 | ||
| 405 | bool Thread::InvokeHLECallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | 405 | bool 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 | ||
| 411 | void Thread::SetActivity(ThreadActivity value) { | 410 | void 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; |