summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/k_thread.cpp55
-rw-r--r--src/core/hle/kernel/k_thread.h4
2 files changed, 26 insertions, 33 deletions
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 71e029a3f..3cb995ddb 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -417,12 +417,7 @@ void KThread::Pin(s32 current_core) {
417 static_cast<u32>(ThreadState::SuspendShift))); 417 static_cast<u32>(ThreadState::SuspendShift)));
418 418
419 // Update our state. 419 // Update our state.
420 const ThreadState old_state = thread_state; 420 UpdateState();
421 thread_state = static_cast<ThreadState>(GetSuspendFlags() |
422 static_cast<u32>(old_state & ThreadState::Mask));
423 if (thread_state != old_state) {
424 KScheduler::OnThreadStateChanged(kernel, this, old_state);
425 }
426 } 421 }
427 422
428 // TODO(bunnei): Update our SVC access permissions. 423 // TODO(bunnei): Update our SVC access permissions.
@@ -463,20 +458,13 @@ void KThread::Unpin() {
463 } 458 }
464 459
465 // Allow performing thread suspension (if termination hasn't been requested). 460 // Allow performing thread suspension (if termination hasn't been requested).
466 { 461 if (!IsTerminationRequested()) {
467 // Update our allow flags. 462 // Update our allow flags.
468 if (!IsTerminationRequested()) { 463 suspend_allowed_flags |= (1 << (static_cast<u32>(SuspendType::Thread) +
469 suspend_allowed_flags |= (1 << (static_cast<u32>(SuspendType::Thread) + 464 static_cast<u32>(ThreadState::SuspendShift)));
470 static_cast<u32>(ThreadState::SuspendShift)));
471 }
472 465
473 // Update our state. 466 // Update our state.
474 const ThreadState old_state = thread_state; 467 UpdateState();
475 thread_state = static_cast<ThreadState>(GetSuspendFlags() |
476 static_cast<u32>(old_state & ThreadState::Mask));
477 if (thread_state != old_state) {
478 KScheduler::OnThreadStateChanged(kernel, this, old_state);
479 }
480 } 468 }
481 469
482 // TODO(bunnei): Update our SVC access permissions. 470 // TODO(bunnei): Update our SVC access permissions.
@@ -689,12 +677,7 @@ void KThread::Resume(SuspendType type) {
689 ~(1u << (static_cast<u32>(ThreadState::SuspendShift) + static_cast<u32>(type))); 677 ~(1u << (static_cast<u32>(ThreadState::SuspendShift) + static_cast<u32>(type)));
690 678
691 // Update our state. 679 // Update our state.
692 const ThreadState old_state = thread_state; 680 this->UpdateState();
693 thread_state = static_cast<ThreadState>(GetSuspendFlags() |
694 static_cast<u32>(old_state & ThreadState::Mask));
695 if (thread_state != old_state) {
696 KScheduler::OnThreadStateChanged(kernel, this, old_state);
697 }
698} 681}
699 682
700void KThread::WaitCancel() { 683void KThread::WaitCancel() {
@@ -721,19 +704,22 @@ void KThread::TrySuspend() {
721 ASSERT(GetNumKernelWaiters() == 0); 704 ASSERT(GetNumKernelWaiters() == 0);
722 705
723 // Perform the suspend. 706 // Perform the suspend.
724 Suspend(); 707 this->UpdateState();
725} 708}
726 709
727void KThread::Suspend() { 710void KThread::UpdateState() {
728 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 711 ASSERT(kernel.GlobalSchedulerContext().IsLocked());
729 ASSERT(IsSuspendRequested());
730 712
731 // Set our suspend flags in state. 713 // Set our suspend flags in state.
732 const auto old_state = thread_state; 714 const auto old_state = thread_state;
733 thread_state = static_cast<ThreadState>(GetSuspendFlags()) | (old_state & ThreadState::Mask); 715 const auto new_state =
716 static_cast<ThreadState>(this->GetSuspendFlags()) | (old_state & ThreadState::Mask);
717 thread_state = new_state;
734 718
735 // Note the state change in scheduler. 719 // Note the state change in scheduler.
736 KScheduler::OnThreadStateChanged(kernel, this, old_state); 720 if (new_state != old_state) {
721 KScheduler::OnThreadStateChanged(kernel, this, old_state);
722 }
737} 723}
738 724
739void KThread::Continue() { 725void KThread::Continue() {
@@ -998,13 +984,16 @@ ResultCode KThread::Run() {
998 984
999 // If the current thread has been asked to suspend, suspend it and retry. 985 // If the current thread has been asked to suspend, suspend it and retry.
1000 if (GetCurrentThread(kernel).IsSuspended()) { 986 if (GetCurrentThread(kernel).IsSuspended()) {
1001 GetCurrentThread(kernel).Suspend(); 987 GetCurrentThread(kernel).UpdateState();
1002 continue; 988 continue;
1003 } 989 }
1004 990
1005 // If we're not a kernel thread and we've been asked to suspend, suspend ourselves. 991 // If we're not a kernel thread and we've been asked to suspend, suspend ourselves.
1006 if (IsUserThread() && IsSuspended()) { 992 if (KProcess* owner = this->GetOwnerProcess(); owner != nullptr) {
1007 Suspend(); 993 if (IsUserThread() && IsSuspended()) {
994 this->UpdateState();
995 }
996 owner->IncrementThreadCount();
1008 } 997 }
1009 998
1010 // Set our state and finish. 999 // Set our state and finish.
@@ -1031,6 +1020,10 @@ void KThread::Exit() {
1031 1020
1032 // Disallow all suspension. 1021 // Disallow all suspension.
1033 suspend_allowed_flags = 0; 1022 suspend_allowed_flags = 0;
1023 this->UpdateState();
1024
1025 // Disallow all suspension.
1026 suspend_allowed_flags = 0;
1034 1027
1035 // Start termination. 1028 // Start termination.
1036 StartTermination(); 1029 StartTermination();
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 83dfde69b..92c3493c5 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -192,9 +192,9 @@ public:
192 192
193 void TrySuspend(); 193 void TrySuspend();
194 194
195 void Continue(); 195 void UpdateState();
196 196
197 void Suspend(); 197 void Continue();
198 198
199 constexpr void SetSyncedIndex(s32 index) { 199 constexpr void SetSyncedIndex(s32 index) {
200 synced_index = index; 200 synced_index = index;