diff options
| author | 2020-02-25 19:43:28 -0400 | |
|---|---|---|
| committer | 2020-06-27 11:35:14 -0400 | |
| commit | 15a79eb0d7abe752a9a55d0cfa7ea220e17318b7 (patch) | |
| tree | 863357ab4be1ff9a72804c40455d6a4c4c493acd /src | |
| parent | SVC: Correct ArbitrateUnlock (diff) | |
| download | yuzu-15a79eb0d7abe752a9a55d0cfa7ea220e17318b7.tar.gz yuzu-15a79eb0d7abe752a9a55d0cfa7ea220e17318b7.tar.xz yuzu-15a79eb0d7abe752a9a55d0cfa7ea220e17318b7.zip | |
SVC: Correct SendSyncRequest.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/cpu_manager.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 24 | ||||
| -rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/kernel/scheduler.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.cpp | 15 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 21 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 14 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 82 |
8 files changed, 116 insertions, 54 deletions
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 9b9337131..6032cb0bf 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -81,8 +81,7 @@ void CpuManager::RunGuestThread() { | |||
| 81 | while (true) { | 81 | while (true) { |
| 82 | auto& physical_core = kernel.CurrentPhysicalCore(); | 82 | auto& physical_core = kernel.CurrentPhysicalCore(); |
| 83 | if (!physical_core.IsInterrupted()) { | 83 | if (!physical_core.IsInterrupted()) { |
| 84 | physical_core.Idle(); | 84 | physical_core.Run(); |
| 85 | // physical_core.Run(); | ||
| 86 | } | 85 | } |
| 87 | auto& scheduler = physical_core.Scheduler(); | 86 | auto& scheduler = physical_core.Scheduler(); |
| 88 | scheduler.TryDoContextSwitch(); | 87 | scheduler.TryDoContextSwitch(); |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 0d01a7047..955d5fe1c 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 15 | #include "common/logging/log.h" | 15 | #include "common/logging/log.h" |
| 16 | #include "core/hle/ipc_helpers.h" | 16 | #include "core/hle/ipc_helpers.h" |
| 17 | #include "core/hle/kernel/errors.h" | ||
| 17 | #include "core/hle/kernel/handle_table.h" | 18 | #include "core/hle/kernel/handle_table.h" |
| 18 | #include "core/hle/kernel/hle_ipc.h" | 19 | #include "core/hle/kernel/hle_ipc.h" |
| 19 | #include "core/hle/kernel/kernel.h" | 20 | #include "core/hle/kernel/kernel.h" |
| @@ -21,7 +22,9 @@ | |||
| 21 | #include "core/hle/kernel/process.h" | 22 | #include "core/hle/kernel/process.h" |
| 22 | #include "core/hle/kernel/readable_event.h" | 23 | #include "core/hle/kernel/readable_event.h" |
| 23 | #include "core/hle/kernel/server_session.h" | 24 | #include "core/hle/kernel/server_session.h" |
| 25 | #include "core/hle/kernel/scheduler.h" | ||
| 24 | #include "core/hle/kernel/thread.h" | 26 | #include "core/hle/kernel/thread.h" |
| 27 | #include "core/hle/kernel/time_manager.h" | ||
| 25 | #include "core/hle/kernel/writable_event.h" | 28 | #include "core/hle/kernel/writable_event.h" |
| 26 | #include "core/memory.h" | 29 | #include "core/memory.h" |
| 27 | 30 | ||
| @@ -46,11 +49,10 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread( | |||
| 46 | const std::string& reason, u64 timeout, WakeupCallback&& callback, | 49 | const std::string& reason, u64 timeout, WakeupCallback&& callback, |
| 47 | std::shared_ptr<WritableEvent> writable_event) { | 50 | std::shared_ptr<WritableEvent> writable_event) { |
| 48 | // 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. |
| 49 | thread->SetWakeupCallback( | 52 | thread->SetHLECallback( |
| 50 | [context = *this, callback](ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | 53 | [context = *this, callback](ThreadWakeupReason reason, std::shared_ptr<Thread> thread, |
| 51 | std::shared_ptr<SynchronizationObject> object, | 54 | std::shared_ptr<SynchronizationObject> object, |
| 52 | std::size_t index) mutable -> bool { | 55 | std::size_t index) mutable -> bool { |
| 53 | ASSERT(thread->GetStatus() == ThreadStatus::WaitHLEEvent); | ||
| 54 | callback(thread, context, reason); | 56 | callback(thread, context, reason); |
| 55 | context.WriteToOutgoingCommandBuffer(*thread); | 57 | context.WriteToOutgoingCommandBuffer(*thread); |
| 56 | return true; | 58 | return true; |
| @@ -62,14 +64,16 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread( | |||
| 62 | writable_event = pair.writable; | 64 | writable_event = pair.writable; |
| 63 | } | 65 | } |
| 64 | 66 | ||
| 65 | const auto readable_event{writable_event->GetReadableEvent()}; | 67 | { |
| 66 | writable_event->Clear(); | 68 | Handle event_handle = InvalidHandle; |
| 67 | thread->SetStatus(ThreadStatus::WaitHLEEvent); | 69 | SchedulerLockAndSleep lock(kernel, event_handle, thread.get(), timeout); |
| 68 | thread->SetSynchronizationObjects({readable_event}); | 70 | const auto readable_event{writable_event->GetReadableEvent()}; |
| 69 | readable_event->AddWaitingThread(thread); | 71 | writable_event->Clear(); |
| 70 | 72 | thread->SetStatus(ThreadStatus::WaitHLEEvent); | |
| 71 | if (timeout > 0) { | 73 | thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT); |
| 72 | thread->WakeAfterDelay(timeout); | 74 | readable_event->AddWaitingThread(thread); |
| 75 | lock.Release(); | ||
| 76 | thread->SetHLETimeEvent(event_handle); | ||
| 73 | } | 77 | } |
| 74 | 78 | ||
| 75 | is_thread_waiting = true; | 79 | is_thread_waiting = true; |
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 5166020a0..0e85ee69e 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp | |||
| @@ -715,4 +715,13 @@ SchedulerLockAndSleep::~SchedulerLockAndSleep() { | |||
| 715 | time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); | 715 | time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); |
| 716 | } | 716 | } |
| 717 | 717 | ||
| 718 | void SchedulerLockAndSleep::Release() { | ||
| 719 | if (sleep_cancelled) { | ||
| 720 | return; | ||
| 721 | } | ||
| 722 | auto& time_manager = kernel.TimeManager(); | ||
| 723 | time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); | ||
| 724 | sleep_cancelled = true; | ||
| 725 | } | ||
| 726 | |||
| 718 | } // namespace Kernel | 727 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index 16655b03f..f5f64338f 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h | |||
| @@ -279,6 +279,8 @@ public: | |||
| 279 | sleep_cancelled = true; | 279 | sleep_cancelled = true; |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | void Release(); | ||
| 283 | |||
| 282 | private: | 284 | private: |
| 283 | Handle& event_handle; | 285 | Handle& event_handle; |
| 284 | Thread* time_task; | 286 | Thread* time_task; |
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 25438b86b..05516a453 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include "core/hle/kernel/process.h" | 19 | #include "core/hle/kernel/process.h" |
| 20 | #include "core/hle/kernel/server_session.h" | 20 | #include "core/hle/kernel/server_session.h" |
| 21 | #include "core/hle/kernel/session.h" | 21 | #include "core/hle/kernel/session.h" |
| 22 | #include "core/hle/kernel/scheduler.h" | ||
| 22 | #include "core/hle/kernel/thread.h" | 23 | #include "core/hle/kernel/thread.h" |
| 23 | #include "core/memory.h" | 24 | #include "core/memory.h" |
| 24 | 25 | ||
| @@ -168,9 +169,12 @@ ResultCode ServerSession::CompleteSyncRequest() { | |||
| 168 | } | 169 | } |
| 169 | 170 | ||
| 170 | // Some service requests require the thread to block | 171 | // Some service requests require the thread to block |
| 171 | if (!context.IsThreadWaiting()) { | 172 | { |
| 172 | context.GetThread().ResumeFromWait(); | 173 | SchedulerLock lock(kernel); |
| 173 | context.GetThread().SetWaitSynchronizationResult(result); | 174 | if (!context.IsThreadWaiting()) { |
| 175 | context.GetThread().ResumeFromWait(); | ||
| 176 | context.GetThread().SetSynchronizationResults(nullptr, result); | ||
| 177 | } | ||
| 174 | } | 178 | } |
| 175 | 179 | ||
| 176 | request_queue.Pop(); | 180 | request_queue.Pop(); |
| @@ -180,8 +184,9 @@ ResultCode ServerSession::CompleteSyncRequest() { | |||
| 180 | 184 | ||
| 181 | ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread, | 185 | ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread, |
| 182 | Core::Memory::Memory& memory) { | 186 | Core::Memory::Memory& memory) { |
| 183 | Core::System::GetInstance().CoreTiming().ScheduleEvent(20000, request_event, {}); | 187 | ResultCode result = QueueSyncRequest(std::move(thread), memory); |
| 184 | return QueueSyncRequest(std::move(thread), memory); | 188 | Core::System::GetInstance().CoreTiming().ScheduleEvent(0, request_event, {}); |
| 189 | return result; | ||
| 185 | } | 190 | } |
| 186 | 191 | ||
| 187 | } // namespace Kernel | 192 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 0d905c0ca..768d72b92 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include "core/hle/kernel/svc_wrap.h" | 38 | #include "core/hle/kernel/svc_wrap.h" |
| 39 | #include "core/hle/kernel/synchronization.h" | 39 | #include "core/hle/kernel/synchronization.h" |
| 40 | #include "core/hle/kernel/thread.h" | 40 | #include "core/hle/kernel/thread.h" |
| 41 | #include "core/hle/kernel/time_manager.h" | ||
| 41 | #include "core/hle/kernel/transfer_memory.h" | 42 | #include "core/hle/kernel/transfer_memory.h" |
| 42 | #include "core/hle/kernel/writable_event.h" | 43 | #include "core/hle/kernel/writable_event.h" |
| 43 | #include "core/hle/lock.h" | 44 | #include "core/hle/lock.h" |
| @@ -318,11 +319,23 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | |||
| 318 | LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); | 319 | LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); |
| 319 | 320 | ||
| 320 | auto thread = system.CurrentScheduler().GetCurrentThread(); | 321 | auto thread = system.CurrentScheduler().GetCurrentThread(); |
| 321 | thread->InvalidateWakeupCallback(); | 322 | { |
| 322 | thread->SetStatus(ThreadStatus::WaitIPC); | 323 | SchedulerLock lock(system.Kernel()); |
| 323 | system.PrepareReschedule(thread->GetProcessorID()); | 324 | thread->InvalidateHLECallback(); |
| 325 | thread->SetStatus(ThreadStatus::WaitIPC); | ||
| 326 | session->SendSyncRequest(SharedFrom(thread), system.Memory()); | ||
| 327 | } | ||
| 328 | ResultCode result = thread->GetSignalingResult(); | ||
| 329 | if (thread->HasHLECallback()) { | ||
| 330 | Handle event_handle = thread->GetHLETimeEvent(); | ||
| 331 | if (event_handle != InvalidHandle) { | ||
| 332 | auto& time_manager = system.Kernel().TimeManager(); | ||
| 333 | time_manager.UnscheduleTimeEvent(event_handle); | ||
| 334 | } | ||
| 335 | thread->InvokeHLECallback(ThreadWakeupReason::Timeout, SharedFrom(thread), nullptr, 0); | ||
| 336 | } | ||
| 324 | 337 | ||
| 325 | return session->SendSyncRequest(SharedFrom(thread), system.Memory()); | 338 | return result; |
| 326 | } | 339 | } |
| 327 | 340 | ||
| 328 | static ResultCode SendSyncRequest32(Core::System& system, Handle handle) { | 341 | static ResultCode SendSyncRequest32(Core::System& system, Handle handle) { |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index f100ffc70..fb97535a3 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -96,7 +96,7 @@ void Thread::ResumeFromWait() { | |||
| 96 | case ThreadStatus::Ready: | 96 | case ThreadStatus::Ready: |
| 97 | // The thread's wakeup callback must have already been cleared when the thread was first | 97 | // The thread's wakeup callback must have already been cleared when the thread was first |
| 98 | // awoken. | 98 | // awoken. |
| 99 | ASSERT(wakeup_callback == nullptr); | 99 | ASSERT(hle_callback == nullptr); |
| 100 | // If the thread is waiting on multiple wait objects, it might be awoken more than once | 100 | // If the thread is waiting on multiple wait objects, it might be awoken more than once |
| 101 | // before actually resuming. We can ignore subsequent wakeups if the thread status has | 101 | // before actually resuming. We can ignore subsequent wakeups if the thread status has |
| 102 | // already been set to ThreadStatus::Ready. | 102 | // already been set to ThreadStatus::Ready. |
| @@ -112,7 +112,7 @@ void Thread::ResumeFromWait() { | |||
| 112 | return; | 112 | return; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | wakeup_callback = nullptr; | 115 | hle_callback = nullptr; |
| 116 | 116 | ||
| 117 | if (activity == ThreadActivity::Paused) { | 117 | if (activity == ThreadActivity::Paused) { |
| 118 | SetStatus(ThreadStatus::Paused); | 118 | SetStatus(ThreadStatus::Paused); |
| @@ -398,8 +398,14 @@ 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(wakeup_callback); | 401 | ASSERT(hle_callback); |
| 402 | return wakeup_callback(reason, std::move(thread), std::move(object), index); | 402 | return hle_callback(reason, std::move(thread), std::move(object), index); |
| 403 | } | ||
| 404 | |||
| 405 | bool Thread::InvokeHLECallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | ||
| 406 | std::shared_ptr<SynchronizationObject> object, std::size_t index) { | ||
| 407 | ASSERT(hle_callback); | ||
| 408 | return hle_callback(reason, std::move(thread), std::move(object), index); | ||
| 403 | } | 409 | } |
| 404 | 410 | ||
| 405 | void Thread::SetActivity(ThreadActivity value) { | 411 | void Thread::SetActivity(ThreadActivity value) { |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index a8ae1a66f..04496f96e 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -31,12 +31,12 @@ class Process; | |||
| 31 | class Scheduler; | 31 | class Scheduler; |
| 32 | 32 | ||
| 33 | enum ThreadPriority : u32 { | 33 | enum ThreadPriority : u32 { |
| 34 | THREADPRIO_HIGHEST = 0, ///< Highest thread priority | 34 | THREADPRIO_HIGHEST = 0, ///< Highest thread priority |
| 35 | THREADPRIO_MAX_CORE_MIGRATION = 2, ///< Highest priority for a core migration | 35 | THREADPRIO_MAX_CORE_MIGRATION = 2, ///< Highest priority for a core migration |
| 36 | THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps | 36 | THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps |
| 37 | THREADPRIO_DEFAULT = 44, ///< Default thread priority for userland apps | 37 | THREADPRIO_DEFAULT = 44, ///< Default thread priority for userland apps |
| 38 | THREADPRIO_LOWEST = 63, ///< Lowest thread priority | 38 | THREADPRIO_LOWEST = 63, ///< Lowest thread priority |
| 39 | THREADPRIO_COUNT = 64, ///< Total number of possible thread priorities. | 39 | THREADPRIO_COUNT = 64, ///< Total number of possible thread priorities. |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | enum ThreadType : u32 { | 42 | enum ThreadType : u32 { |
| @@ -129,23 +129,24 @@ public: | |||
| 129 | using WakeupCallback = | 129 | using WakeupCallback = |
| 130 | std::function<bool(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | 130 | std::function<bool(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, |
| 131 | std::shared_ptr<SynchronizationObject> object, std::size_t index)>; | 131 | std::shared_ptr<SynchronizationObject> object, std::size_t index)>; |
| 132 | using HLECallback = std::function<bool(std::shared_ptr<Thread> thread)>; | ||
| 132 | 133 | ||
| 133 | /** | 134 | /** |
| 134 | * Creates and returns a new thread. The new thread is immediately scheduled | 135 | * Creates and returns a new thread. The new thread is immediately scheduled |
| 135 | * @param system The instance of the whole system | 136 | * @param system The instance of the whole system |
| 136 | * @param name The friendly name desired for the thread | 137 | * @param name The friendly name desired for the thread |
| 137 | * @param entry_point The address at which the thread should start execution | 138 | * @param entry_point The address at which the thread should start execution |
| 138 | * @param priority The thread's priority | 139 | * @param priority The thread's priority |
| 139 | * @param arg User data to pass to the thread | 140 | * @param arg User data to pass to the thread |
| 140 | * @param processor_id The ID(s) of the processors on which the thread is desired to be run | 141 | * @param processor_id The ID(s) of the processors on which the thread is desired to be run |
| 141 | * @param stack_top The address of the thread's stack top | 142 | * @param stack_top The address of the thread's stack top |
| 142 | * @param owner_process The parent process for the thread, if null, it's a kernel thread | 143 | * @param owner_process The parent process for the thread, if null, it's a kernel thread |
| 143 | * @return A shared pointer to the newly created thread | 144 | * @return A shared pointer to the newly created thread |
| 144 | */ | 145 | */ |
| 145 | static ResultVal<std::shared_ptr<Thread>> Create(Core::System& system, ThreadType type_flags, std::string name, | 146 | static ResultVal<std::shared_ptr<Thread>> Create(Core::System& system, ThreadType type_flags, |
| 146 | VAddr entry_point, u32 priority, u64 arg, | 147 | std::string name, VAddr entry_point, |
| 147 | s32 processor_id, VAddr stack_top, | 148 | u32 priority, u64 arg, s32 processor_id, |
| 148 | Process* owner_process); | 149 | VAddr stack_top, Process* owner_process); |
| 149 | 150 | ||
| 150 | /** | 151 | /** |
| 151 | * Creates and returns a new thread. The new thread is immediately scheduled | 152 | * Creates and returns a new thread. The new thread is immediately scheduled |
| @@ -161,10 +162,10 @@ public: | |||
| 161 | * @param thread_start_parameter The parameter which will passed to host context on init | 162 | * @param thread_start_parameter The parameter which will passed to host context on init |
| 162 | * @return A shared pointer to the newly created thread | 163 | * @return A shared pointer to the newly created thread |
| 163 | */ | 164 | */ |
| 164 | static ResultVal<std::shared_ptr<Thread>> Create(Core::System& system, ThreadType type_flags, std::string name, | 165 | static ResultVal<std::shared_ptr<Thread>> Create(Core::System& system, ThreadType type_flags, |
| 165 | VAddr entry_point, u32 priority, u64 arg, | 166 | std::string name, VAddr entry_point, |
| 166 | s32 processor_id, VAddr stack_top, | 167 | u32 priority, u64 arg, s32 processor_id, |
| 167 | Process* owner_process, | 168 | VAddr stack_top, Process* owner_process, |
| 168 | std::function<void(void*)>&& thread_start_func, | 169 | std::function<void(void*)>&& thread_start_func, |
| 169 | void* thread_start_parameter); | 170 | void* thread_start_parameter); |
| 170 | 171 | ||
| @@ -447,17 +448,37 @@ public: | |||
| 447 | } | 448 | } |
| 448 | 449 | ||
| 449 | bool HasWakeupCallback() const { | 450 | bool HasWakeupCallback() const { |
| 450 | return wakeup_callback != nullptr; | 451 | return hle_callback != nullptr; |
| 452 | } | ||
| 453 | |||
| 454 | bool HasHLECallback() const { | ||
| 455 | return hle_callback != nullptr; | ||
| 451 | } | 456 | } |
| 452 | 457 | ||
| 453 | void SetWakeupCallback(WakeupCallback callback) { | 458 | void SetWakeupCallback(WakeupCallback callback) { |
| 454 | wakeup_callback = std::move(callback); | 459 | hle_callback = std::move(callback); |
| 460 | } | ||
| 461 | |||
| 462 | void SetHLECallback(WakeupCallback callback) { | ||
| 463 | hle_callback = std::move(callback); | ||
| 464 | } | ||
| 465 | |||
| 466 | void SetHLETimeEvent(Handle time_event) { | ||
| 467 | hle_time_event = time_event; | ||
| 468 | } | ||
| 469 | |||
| 470 | Handle GetHLETimeEvent() const { | ||
| 471 | return hle_time_event; | ||
| 455 | } | 472 | } |
| 456 | 473 | ||
| 457 | void InvalidateWakeupCallback() { | 474 | void InvalidateWakeupCallback() { |
| 458 | SetWakeupCallback(nullptr); | 475 | SetWakeupCallback(nullptr); |
| 459 | } | 476 | } |
| 460 | 477 | ||
| 478 | void InvalidateHLECallback() { | ||
| 479 | SetHLECallback(nullptr); | ||
| 480 | } | ||
| 481 | |||
| 461 | /** | 482 | /** |
| 462 | * Invokes the thread's wakeup callback. | 483 | * Invokes the thread's wakeup callback. |
| 463 | * | 484 | * |
| @@ -466,6 +487,8 @@ public: | |||
| 466 | */ | 487 | */ |
| 467 | bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, | 488 | bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, |
| 468 | 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, | ||
| 491 | std::shared_ptr<SynchronizationObject> object, std::size_t index); | ||
| 469 | 492 | ||
| 470 | u32 GetIdealCore() const { | 493 | u32 GetIdealCore() const { |
| 471 | return ideal_core; | 494 | return ideal_core; |
| @@ -600,7 +623,8 @@ private: | |||
| 600 | /// Callback that will be invoked when the thread is resumed from a waiting state. If the thread | 623 | /// Callback that will be invoked when the thread is resumed from a waiting state. If the thread |
| 601 | /// was waiting via WaitSynchronization then the object will be the last object that became | 624 | /// was waiting via WaitSynchronization then the object will be the last object that became |
| 602 | /// available. In case of a timeout, the object will be nullptr. | 625 | /// available. In case of a timeout, the object will be nullptr. |
| 603 | WakeupCallback wakeup_callback; | 626 | WakeupCallback hle_callback; |
| 627 | Handle hle_time_event; | ||
| 604 | 628 | ||
| 605 | Scheduler* scheduler = nullptr; | 629 | Scheduler* scheduler = nullptr; |
| 606 | 630 | ||