core: hle: kernel: KThread: Replace Suspend with UpdateState & various updates.

- This makes our implementations of these more closely match HOS.
This commit is contained in:
bunnei 2022-01-14 16:31:47 -08:00
parent c905044e1b
commit 03884b7ea6
2 changed files with 26 additions and 33 deletions

View File

@ -417,12 +417,7 @@ void KThread::Pin(s32 current_core) {
static_cast<u32>(ThreadState::SuspendShift))); static_cast<u32>(ThreadState::SuspendShift)));
// Update our state. // Update our state.
const ThreadState old_state = thread_state; UpdateState();
thread_state = static_cast<ThreadState>(GetSuspendFlags() |
static_cast<u32>(old_state & ThreadState::Mask));
if (thread_state != old_state) {
KScheduler::OnThreadStateChanged(kernel, this, old_state);
}
} }
// TODO(bunnei): Update our SVC access permissions. // TODO(bunnei): Update our SVC access permissions.
@ -463,20 +458,13 @@ void KThread::Unpin() {
} }
// Allow performing thread suspension (if termination hasn't been requested). // Allow performing thread suspension (if termination hasn't been requested).
{
// Update our allow flags.
if (!IsTerminationRequested()) { if (!IsTerminationRequested()) {
// Update our allow flags.
suspend_allowed_flags |= (1 << (static_cast<u32>(SuspendType::Thread) + suspend_allowed_flags |= (1 << (static_cast<u32>(SuspendType::Thread) +
static_cast<u32>(ThreadState::SuspendShift))); static_cast<u32>(ThreadState::SuspendShift)));
}
// Update our state. // Update our state.
const ThreadState old_state = thread_state; UpdateState();
thread_state = static_cast<ThreadState>(GetSuspendFlags() |
static_cast<u32>(old_state & ThreadState::Mask));
if (thread_state != old_state) {
KScheduler::OnThreadStateChanged(kernel, this, old_state);
}
} }
// TODO(bunnei): Update our SVC access permissions. // TODO(bunnei): Update our SVC access permissions.
@ -689,12 +677,7 @@ void KThread::Resume(SuspendType type) {
~(1u << (static_cast<u32>(ThreadState::SuspendShift) + static_cast<u32>(type))); ~(1u << (static_cast<u32>(ThreadState::SuspendShift) + static_cast<u32>(type)));
// Update our state. // Update our state.
const ThreadState old_state = thread_state; this->UpdateState();
thread_state = static_cast<ThreadState>(GetSuspendFlags() |
static_cast<u32>(old_state & ThreadState::Mask));
if (thread_state != old_state) {
KScheduler::OnThreadStateChanged(kernel, this, old_state);
}
} }
void KThread::WaitCancel() { void KThread::WaitCancel() {
@ -721,20 +704,23 @@ void KThread::TrySuspend() {
ASSERT(GetNumKernelWaiters() == 0); ASSERT(GetNumKernelWaiters() == 0);
// Perform the suspend. // Perform the suspend.
Suspend(); this->UpdateState();
} }
void KThread::Suspend() { void KThread::UpdateState() {
ASSERT(kernel.GlobalSchedulerContext().IsLocked()); ASSERT(kernel.GlobalSchedulerContext().IsLocked());
ASSERT(IsSuspendRequested());
// Set our suspend flags in state. // Set our suspend flags in state.
const auto old_state = thread_state; const auto old_state = thread_state;
thread_state = static_cast<ThreadState>(GetSuspendFlags()) | (old_state & ThreadState::Mask); const auto new_state =
static_cast<ThreadState>(this->GetSuspendFlags()) | (old_state & ThreadState::Mask);
thread_state = new_state;
// Note the state change in scheduler. // Note the state change in scheduler.
if (new_state != old_state) {
KScheduler::OnThreadStateChanged(kernel, this, old_state); KScheduler::OnThreadStateChanged(kernel, this, old_state);
} }
}
void KThread::Continue() { void KThread::Continue() {
ASSERT(kernel.GlobalSchedulerContext().IsLocked()); ASSERT(kernel.GlobalSchedulerContext().IsLocked());
@ -998,13 +984,16 @@ ResultCode KThread::Run() {
// If the current thread has been asked to suspend, suspend it and retry. // If the current thread has been asked to suspend, suspend it and retry.
if (GetCurrentThread(kernel).IsSuspended()) { if (GetCurrentThread(kernel).IsSuspended()) {
GetCurrentThread(kernel).Suspend(); GetCurrentThread(kernel).UpdateState();
continue; continue;
} }
// If we're not a kernel thread and we've been asked to suspend, suspend ourselves. // If we're not a kernel thread and we've been asked to suspend, suspend ourselves.
if (KProcess* owner = this->GetOwnerProcess(); owner != nullptr) {
if (IsUserThread() && IsSuspended()) { if (IsUserThread() && IsSuspended()) {
Suspend(); this->UpdateState();
}
owner->IncrementThreadCount();
} }
// Set our state and finish. // Set our state and finish.
@ -1029,6 +1018,10 @@ void KThread::Exit() {
{ {
KScopedSchedulerLock sl{kernel}; KScopedSchedulerLock sl{kernel};
// Disallow all suspension.
suspend_allowed_flags = 0;
this->UpdateState();
// Disallow all suspension. // Disallow all suspension.
suspend_allowed_flags = 0; suspend_allowed_flags = 0;

View File

@ -192,9 +192,9 @@ public:
void TrySuspend(); void TrySuspend();
void Continue(); void UpdateState();
void Suspend(); void Continue();
constexpr void SetSyncedIndex(s32 index) { constexpr void SetSyncedIndex(s32 index) {
synced_index = index; synced_index = index;