diff options
| author | 2020-03-07 12:44:35 -0400 | |
|---|---|---|
| committer | 2020-06-27 11:35:33 -0400 | |
| commit | 83c7ba1ef700eff17f30b6c2782db77710dc322e (patch) | |
| tree | 63b5901d96afa6a823a8a14859db84d6c74a283d /src/core/hle/kernel/thread.cpp | |
| parent | SCC: Small corrections to CancelSynchronization (diff) | |
| download | yuzu-83c7ba1ef700eff17f30b6c2782db77710dc322e.tar.gz yuzu-83c7ba1ef700eff17f30b6c2782db77710dc322e.tar.xz yuzu-83c7ba1ef700eff17f30b6c2782db77710dc322e.zip | |
SVC: Correct SetThreadActivity.
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index e8962a0d8..b99e3b7a5 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -113,20 +113,11 @@ void Thread::ResumeFromWait() { | |||
| 113 | return; | 113 | return; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | if (activity == ThreadActivity::Paused) { | ||
| 117 | SetStatus(ThreadStatus::Paused); | ||
| 118 | return; | ||
| 119 | } | ||
| 120 | |||
| 121 | SetStatus(ThreadStatus::Ready); | 116 | SetStatus(ThreadStatus::Ready); |
| 122 | } | 117 | } |
| 123 | 118 | ||
| 124 | void Thread::OnWakeUp() { | 119 | void Thread::OnWakeUp() { |
| 125 | SchedulerLock lock(kernel); | 120 | SchedulerLock lock(kernel); |
| 126 | if (activity == ThreadActivity::Paused) { | ||
| 127 | SetStatus(ThreadStatus::Paused); | ||
| 128 | return; | ||
| 129 | } | ||
| 130 | 121 | ||
| 131 | SetStatus(ThreadStatus::Ready); | 122 | SetStatus(ThreadStatus::Ready); |
| 132 | } | 123 | } |
| @@ -143,7 +134,7 @@ void Thread::CancelWait() { | |||
| 143 | is_sync_cancelled = true; | 134 | is_sync_cancelled = true; |
| 144 | return; | 135 | return; |
| 145 | } | 136 | } |
| 146 | //TODO(Blinkhawk): Implement cancel of server session | 137 | // TODO(Blinkhawk): Implement cancel of server session |
| 147 | is_sync_cancelled = false; | 138 | is_sync_cancelled = false; |
| 148 | SetSynchronizationResults(nullptr, ERR_SYNCHRONIZATION_CANCELED); | 139 | SetSynchronizationResults(nullptr, ERR_SYNCHRONIZATION_CANCELED); |
| 149 | SetStatus(ThreadStatus::Ready); | 140 | SetStatus(ThreadStatus::Ready); |
| @@ -407,19 +398,31 @@ bool Thread::InvokeHLECallback(std::shared_ptr<Thread> thread) { | |||
| 407 | return hle_callback(std::move(thread)); | 398 | return hle_callback(std::move(thread)); |
| 408 | } | 399 | } |
| 409 | 400 | ||
| 410 | void Thread::SetActivity(ThreadActivity value) { | 401 | ResultCode Thread::SetActivity(ThreadActivity value) { |
| 411 | activity = value; | 402 | SchedulerLock lock(kernel); |
| 403 | |||
| 404 | auto sched_status = GetSchedulingStatus(); | ||
| 405 | |||
| 406 | if (sched_status != ThreadSchedStatus::Runnable && sched_status != ThreadSchedStatus::Paused) { | ||
| 407 | return ERR_INVALID_STATE; | ||
| 408 | } | ||
| 409 | |||
| 410 | if (IsPendingTermination()) { | ||
| 411 | return RESULT_SUCCESS; | ||
| 412 | } | ||
| 412 | 413 | ||
| 413 | if (value == ThreadActivity::Paused) { | 414 | if (value == ThreadActivity::Paused) { |
| 414 | // Set status if not waiting | 415 | if (pausing_state & static_cast<u32>(ThreadSchedFlags::ThreadPauseFlag) != 0) { |
| 415 | if (status == ThreadStatus::Ready || status == ThreadStatus::Running) { | 416 | return ERR_INVALID_STATE; |
| 416 | SetStatus(ThreadStatus::Paused); | ||
| 417 | kernel.PrepareReschedule(processor_id); | ||
| 418 | } | 417 | } |
| 419 | } else if (status == ThreadStatus::Paused) { | 418 | AddSchedulingFlag(ThreadSchedFlags::ThreadPauseFlag); |
| 420 | // Ready to reschedule | 419 | } else { |
| 421 | ResumeFromWait(); | 420 | if (pausing_state & static_cast<u32>(ThreadSchedFlags::ThreadPauseFlag) == 0) { |
| 421 | return ERR_INVALID_STATE; | ||
| 422 | } | ||
| 423 | RemoveSchedulingFlag(ThreadSchedFlags::ThreadPauseFlag); | ||
| 422 | } | 424 | } |
| 425 | return RESULT_SUCCESS; | ||
| 423 | } | 426 | } |
| 424 | 427 | ||
| 425 | ResultCode Thread::Sleep(s64 nanoseconds) { | 428 | ResultCode Thread::Sleep(s64 nanoseconds) { |
| @@ -460,11 +463,27 @@ ResultCode Thread::YieldAndWaitForLoadBalancing() { | |||
| 460 | return RESULT_SUCCESS; | 463 | return RESULT_SUCCESS; |
| 461 | } | 464 | } |
| 462 | 465 | ||
| 466 | void Thread::AddSchedulingFlag(ThreadSchedFlags flag) { | ||
| 467 | const u32 old_state = scheduling_state; | ||
| 468 | pausing_state |= static_cast<u32>(flag); | ||
| 469 | const u32 base_scheduling = static_cast<u32>(GetSchedulingStatus()); | ||
| 470 | scheduling_state = base_scheduling | pausing_state; | ||
| 471 | kernel.GlobalScheduler().AdjustSchedulingOnStatus(this, old_state); | ||
| 472 | } | ||
| 473 | |||
| 474 | void Thread::RemoveSchedulingFlag(ThreadSchedFlags flag) { | ||
| 475 | const u32 old_state = scheduling_state; | ||
| 476 | pausing_state &= ~static_cast<u32>(flag); | ||
| 477 | const u32 base_scheduling = static_cast<u32>(GetSchedulingStatus()); | ||
| 478 | scheduling_state = base_scheduling | pausing_state; | ||
| 479 | kernel.GlobalScheduler().AdjustSchedulingOnStatus(this, old_state); | ||
| 480 | } | ||
| 481 | |||
| 463 | void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) { | 482 | void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) { |
| 464 | const u32 old_flags = scheduling_state; | 483 | const u32 old_state = scheduling_state; |
| 465 | scheduling_state = (scheduling_state & static_cast<u32>(ThreadSchedMasks::HighMask)) | | 484 | scheduling_state = (scheduling_state & static_cast<u32>(ThreadSchedMasks::HighMask)) | |
| 466 | static_cast<u32>(new_status); | 485 | static_cast<u32>(new_status); |
| 467 | kernel.GlobalScheduler().AdjustSchedulingOnStatus(this, old_flags); | 486 | kernel.GlobalScheduler().AdjustSchedulingOnStatus(this, old_state); |
| 468 | } | 487 | } |
| 469 | 488 | ||
| 470 | void Thread::SetCurrentPriority(u32 new_priority) { | 489 | void Thread::SetCurrentPriority(u32 new_priority) { |