summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/thread.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2020-12-28 22:16:43 +0100
committerbunnei <bunneidev@gmail.com>2021-01-11 23:23:16 +0100
commitc3c43e32fcf198444acb493483e03fcb193156df (patch)
treea516e116d7dbb9309b0adbfa2e3660861ff4e6b7 /src/core/hle/kernel/thread.cpp
parentcore: hle: kernel: Add some useful functions for checking kernel addresses. (diff)
downloadyuzu-c3c43e32fcf198444acb493483e03fcb193156df.tar
yuzu-c3c43e32fcf198444acb493483e03fcb193156df.tar.gz
yuzu-c3c43e32fcf198444acb493483e03fcb193156df.tar.bz2
yuzu-c3c43e32fcf198444acb493483e03fcb193156df.tar.lz
yuzu-c3c43e32fcf198444acb493483e03fcb193156df.tar.xz
yuzu-c3c43e32fcf198444acb493483e03fcb193156df.tar.zst
yuzu-c3c43e32fcf198444acb493483e03fcb193156df.zip
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
-rw-r--r--src/core/hle/kernel/thread.cpp81
1 files changed, 30 insertions, 51 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index ac19e2997..33a4e1fa3 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -44,7 +44,7 @@ Thread::~Thread() = default;
void Thread::Stop() {
{
KScopedSchedulerLock lock(kernel);
- SetState(ThreadStatus::Dead);
+ SetState(ThreadState::Terminated);
signaled = true;
NotifyAvailable();
kernel.GlobalHandleTable().Close(global_handle);
@@ -62,54 +62,43 @@ void Thread::Stop() {
void Thread::Wakeup() {
KScopedSchedulerLock lock(kernel);
- switch (status) {
- case ThreadStatus::Paused:
- case ThreadStatus::WaitSynch:
- case ThreadStatus::WaitHLEEvent:
- case ThreadStatus::WaitSleep:
- case ThreadStatus::WaitIPC:
- case ThreadStatus::WaitMutex:
- case ThreadStatus::WaitCondVar:
- case ThreadStatus::WaitArb:
- case ThreadStatus::Dormant:
- break;
-
- case ThreadStatus::Ready:
+ switch (thread_state) {
+ case ThreadState::Runnable:
// If the thread is waiting on multiple wait objects, it might be awoken more than once
// before actually resuming. We can ignore subsequent wakeups if the thread status has
// already been set to ThreadStatus::Ready.
return;
- case ThreadStatus::Dead:
+ case ThreadState::Terminated:
// This should never happen, as threads must complete before being stopped.
DEBUG_ASSERT_MSG(false, "Thread with object id {} cannot be resumed because it's DEAD.",
GetObjectId());
return;
}
- SetState(ThreadStatus::Ready);
+ SetState(ThreadState::Runnable);
}
void Thread::OnWakeUp() {
KScopedSchedulerLock lock(kernel);
- SetState(ThreadStatus::Ready);
+ SetState(ThreadState::Runnable);
}
ResultCode Thread::Start() {
KScopedSchedulerLock lock(kernel);
- SetState(ThreadStatus::Ready);
+ SetState(ThreadState::Runnable);
return RESULT_SUCCESS;
}
void Thread::CancelWait() {
KScopedSchedulerLock lock(kernel);
- if (GetState() != ThreadSchedStatus::Paused || !is_cancellable) {
+ if (GetState() != ThreadState::Waiting || !is_cancellable) {
is_sync_cancelled = true;
return;
}
// TODO(Blinkhawk): Implement cancel of server session
is_sync_cancelled = false;
SetSynchronizationResults(nullptr, ERR_SYNCHRONIZATION_CANCELED);
- SetState(ThreadStatus::Ready);
+ SetState(ThreadState::Runnable);
}
static void ResetThreadContext32(Core::ARM_Interface::ThreadContext32& context, u32 stack_top,
@@ -173,7 +162,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
std::shared_ptr<Thread> thread = std::make_shared<Thread>(kernel);
thread->thread_id = kernel.CreateNewThreadID();
- thread->status = ThreadStatus::Dormant;
+ thread->thread_state = ThreadState::Initialized;
thread->entry_point = entry_point;
thread->stack_top = stack_top;
thread->disable_count = 1;
@@ -235,27 +224,18 @@ VAddr Thread::GetCommandBufferAddress() const {
return GetTLSAddress() + command_header_offset;
}
-void Thread::SetState(ThreadStatus new_status) {
- if (new_status == status) {
+void Thread::SetState(ThreadState new_status) {
+ if (new_status == thread_state) {
return;
}
- switch (new_status) {
- case ThreadStatus::Ready:
- SetSchedulingStatus(ThreadSchedStatus::Runnable);
- break;
- case ThreadStatus::Dormant:
- SetSchedulingStatus(ThreadSchedStatus::None);
- break;
- case ThreadStatus::Dead:
- SetSchedulingStatus(ThreadSchedStatus::Exited);
- break;
- default:
- SetSchedulingStatus(ThreadSchedStatus::Paused);
- break;
+ if (new_status != ThreadState::Waiting) {
+ SetWaitingCondVar(false);
}
- status = new_status;
+ SetSchedulingStatus(new_status);
+
+ thread_state = new_status;
}
void Thread::AddMutexWaiter(std::shared_ptr<Thread> thread) {
@@ -312,13 +292,13 @@ void Thread::UpdatePriority() {
return;
}
- if (GetStatus() == ThreadStatus::WaitCondVar) {
+ if (GetState() == ThreadState::Waiting && is_waiting_on_condvar) {
owner_process->RemoveConditionVariableThread(SharedFrom(this));
}
SetCurrentPriority(new_priority);
- if (GetStatus() == ThreadStatus::WaitCondVar) {
+ if (GetState() == ThreadState::Waiting && is_waiting_on_condvar) {
owner_process->InsertConditionVariableThread(SharedFrom(this));
}
@@ -340,7 +320,7 @@ ResultCode Thread::SetActivity(ThreadActivity value) {
auto sched_status = GetState();
- if (sched_status != ThreadSchedStatus::Runnable && sched_status != ThreadSchedStatus::Paused) {
+ if (sched_status != ThreadState::Runnable && sched_status != ThreadState::Waiting) {
return ERR_INVALID_STATE;
}
@@ -366,7 +346,7 @@ ResultCode Thread::Sleep(s64 nanoseconds) {
Handle event_handle{};
{
KScopedSchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds);
- SetState(ThreadStatus::WaitSleep);
+ SetState(ThreadState::Waiting);
}
if (event_handle != InvalidHandle) {
@@ -377,25 +357,24 @@ ResultCode Thread::Sleep(s64 nanoseconds) {
}
void Thread::AddSchedulingFlag(ThreadSchedFlags flag) {
- const u32 old_state = scheduling_state;
+ const auto old_state = GetRawState();
pausing_state |= static_cast<u32>(flag);
- const u32 base_scheduling = static_cast<u32>(GetState());
- scheduling_state = base_scheduling | pausing_state;
+ const auto base_scheduling = GetState();
+ thread_state = base_scheduling | static_cast<ThreadState>(pausing_state);
KScheduler::OnThreadStateChanged(kernel, this, old_state);
}
void Thread::RemoveSchedulingFlag(ThreadSchedFlags flag) {
- const u32 old_state = scheduling_state;
+ const auto old_state = GetRawState();
pausing_state &= ~static_cast<u32>(flag);
- const u32 base_scheduling = static_cast<u32>(GetState());
- scheduling_state = base_scheduling | pausing_state;
+ const auto base_scheduling = GetState();
+ thread_state = base_scheduling | static_cast<ThreadState>(pausing_state);
KScheduler::OnThreadStateChanged(kernel, this, old_state);
}
-void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) {
- const u32 old_state = scheduling_state;
- scheduling_state = (scheduling_state & static_cast<u32>(ThreadSchedMasks::HighMask)) |
- static_cast<u32>(new_status);
+void Thread::SetSchedulingStatus(ThreadState new_status) {
+ const auto old_state = GetRawState();
+ thread_state = (thread_state & ThreadState::HighMask) | new_status;
KScheduler::OnThreadStateChanged(kernel, this, old_state);
}