diff options
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 81 |
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; | |||
| 44 | void Thread::Stop() { | 44 | void Thread::Stop() { |
| 45 | { | 45 | { |
| 46 | KScopedSchedulerLock lock(kernel); | 46 | KScopedSchedulerLock lock(kernel); |
| 47 | SetState(ThreadStatus::Dead); | 47 | SetState(ThreadState::Terminated); |
| 48 | signaled = true; | 48 | signaled = true; |
| 49 | NotifyAvailable(); | 49 | NotifyAvailable(); |
| 50 | kernel.GlobalHandleTable().Close(global_handle); | 50 | kernel.GlobalHandleTable().Close(global_handle); |
| @@ -62,54 +62,43 @@ void Thread::Stop() { | |||
| 62 | 62 | ||
| 63 | void Thread::Wakeup() { | 63 | void Thread::Wakeup() { |
| 64 | KScopedSchedulerLock lock(kernel); | 64 | KScopedSchedulerLock lock(kernel); |
| 65 | switch (status) { | 65 | switch (thread_state) { |
| 66 | case ThreadStatus::Paused: | 66 | case ThreadState::Runnable: |
| 67 | case ThreadStatus::WaitSynch: | ||
| 68 | case ThreadStatus::WaitHLEEvent: | ||
| 69 | case ThreadStatus::WaitSleep: | ||
| 70 | case ThreadStatus::WaitIPC: | ||
| 71 | case ThreadStatus::WaitMutex: | ||
| 72 | case ThreadStatus::WaitCondVar: | ||
| 73 | case ThreadStatus::WaitArb: | ||
| 74 | case ThreadStatus::Dormant: | ||
| 75 | break; | ||
| 76 | |||
| 77 | case ThreadStatus::Ready: | ||
| 78 | // If the thread is waiting on multiple wait objects, it might be awoken more than once | 67 | // If the thread is waiting on multiple wait objects, it might be awoken more than once |
| 79 | // before actually resuming. We can ignore subsequent wakeups if the thread status has | 68 | // before actually resuming. We can ignore subsequent wakeups if the thread status has |
| 80 | // already been set to ThreadStatus::Ready. | 69 | // already been set to ThreadStatus::Ready. |
| 81 | return; | 70 | return; |
| 82 | case ThreadStatus::Dead: | 71 | case ThreadState::Terminated: |
| 83 | // This should never happen, as threads must complete before being stopped. | 72 | // This should never happen, as threads must complete before being stopped. |
| 84 | DEBUG_ASSERT_MSG(false, "Thread with object id {} cannot be resumed because it's DEAD.", | 73 | DEBUG_ASSERT_MSG(false, "Thread with object id {} cannot be resumed because it's DEAD.", |
| 85 | GetObjectId()); | 74 | GetObjectId()); |
| 86 | return; | 75 | return; |
| 87 | } | 76 | } |
| 88 | 77 | ||
| 89 | SetState(ThreadStatus::Ready); | 78 | SetState(ThreadState::Runnable); |
| 90 | } | 79 | } |
| 91 | 80 | ||
| 92 | void Thread::OnWakeUp() { | 81 | void Thread::OnWakeUp() { |
| 93 | KScopedSchedulerLock lock(kernel); | 82 | KScopedSchedulerLock lock(kernel); |
| 94 | SetState(ThreadStatus::Ready); | 83 | SetState(ThreadState::Runnable); |
| 95 | } | 84 | } |
| 96 | 85 | ||
| 97 | ResultCode Thread::Start() { | 86 | ResultCode Thread::Start() { |
| 98 | KScopedSchedulerLock lock(kernel); | 87 | KScopedSchedulerLock lock(kernel); |
| 99 | SetState(ThreadStatus::Ready); | 88 | SetState(ThreadState::Runnable); |
| 100 | return RESULT_SUCCESS; | 89 | return RESULT_SUCCESS; |
| 101 | } | 90 | } |
| 102 | 91 | ||
| 103 | void Thread::CancelWait() { | 92 | void Thread::CancelWait() { |
| 104 | KScopedSchedulerLock lock(kernel); | 93 | KScopedSchedulerLock lock(kernel); |
| 105 | if (GetState() != ThreadSchedStatus::Paused || !is_cancellable) { | 94 | if (GetState() != ThreadState::Waiting || !is_cancellable) { |
| 106 | is_sync_cancelled = true; | 95 | is_sync_cancelled = true; |
| 107 | return; | 96 | return; |
| 108 | } | 97 | } |
| 109 | // TODO(Blinkhawk): Implement cancel of server session | 98 | // TODO(Blinkhawk): Implement cancel of server session |
| 110 | is_sync_cancelled = false; | 99 | is_sync_cancelled = false; |
| 111 | SetSynchronizationResults(nullptr, ERR_SYNCHRONIZATION_CANCELED); | 100 | SetSynchronizationResults(nullptr, ERR_SYNCHRONIZATION_CANCELED); |
| 112 | SetState(ThreadStatus::Ready); | 101 | SetState(ThreadState::Runnable); |
| 113 | } | 102 | } |
| 114 | 103 | ||
| 115 | static void ResetThreadContext32(Core::ARM_Interface::ThreadContext32& context, u32 stack_top, | 104 | 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 | |||
| 173 | std::shared_ptr<Thread> thread = std::make_shared<Thread>(kernel); | 162 | std::shared_ptr<Thread> thread = std::make_shared<Thread>(kernel); |
| 174 | 163 | ||
| 175 | thread->thread_id = kernel.CreateNewThreadID(); | 164 | thread->thread_id = kernel.CreateNewThreadID(); |
| 176 | thread->status = ThreadStatus::Dormant; | 165 | thread->thread_state = ThreadState::Initialized; |
| 177 | thread->entry_point = entry_point; | 166 | thread->entry_point = entry_point; |
| 178 | thread->stack_top = stack_top; | 167 | thread->stack_top = stack_top; |
| 179 | thread->disable_count = 1; | 168 | thread->disable_count = 1; |
| @@ -235,27 +224,18 @@ VAddr Thread::GetCommandBufferAddress() const { | |||
| 235 | return GetTLSAddress() + command_header_offset; | 224 | return GetTLSAddress() + command_header_offset; |
| 236 | } | 225 | } |
| 237 | 226 | ||
| 238 | void Thread::SetState(ThreadStatus new_status) { | 227 | void Thread::SetState(ThreadState new_status) { |
| 239 | if (new_status == status) { | 228 | if (new_status == thread_state) { |
| 240 | return; | 229 | return; |
| 241 | } | 230 | } |
| 242 | 231 | ||
| 243 | switch (new_status) { | 232 | if (new_status != ThreadState::Waiting) { |
| 244 | case ThreadStatus::Ready: | 233 | SetWaitingCondVar(false); |
| 245 | SetSchedulingStatus(ThreadSchedStatus::Runnable); | ||
| 246 | break; | ||
| 247 | case ThreadStatus::Dormant: | ||
| 248 | SetSchedulingStatus(ThreadSchedStatus::None); | ||
| 249 | break; | ||
| 250 | case ThreadStatus::Dead: | ||
| 251 | SetSchedulingStatus(ThreadSchedStatus::Exited); | ||
| 252 | break; | ||
| 253 | default: | ||
| 254 | SetSchedulingStatus(ThreadSchedStatus::Paused); | ||
| 255 | break; | ||
| 256 | } | 234 | } |
| 257 | 235 | ||
| 258 | status = new_status; | 236 | SetSchedulingStatus(new_status); |
| 237 | |||
| 238 | thread_state = new_status; | ||
| 259 | } | 239 | } |
| 260 | 240 | ||
| 261 | void Thread::AddMutexWaiter(std::shared_ptr<Thread> thread) { | 241 | void Thread::AddMutexWaiter(std::shared_ptr<Thread> thread) { |
| @@ -312,13 +292,13 @@ void Thread::UpdatePriority() { | |||
| 312 | return; | 292 | return; |
| 313 | } | 293 | } |
| 314 | 294 | ||
| 315 | if (GetStatus() == ThreadStatus::WaitCondVar) { | 295 | if (GetState() == ThreadState::Waiting && is_waiting_on_condvar) { |
| 316 | owner_process->RemoveConditionVariableThread(SharedFrom(this)); | 296 | owner_process->RemoveConditionVariableThread(SharedFrom(this)); |
| 317 | } | 297 | } |
| 318 | 298 | ||
| 319 | SetCurrentPriority(new_priority); | 299 | SetCurrentPriority(new_priority); |
| 320 | 300 | ||
| 321 | if (GetStatus() == ThreadStatus::WaitCondVar) { | 301 | if (GetState() == ThreadState::Waiting && is_waiting_on_condvar) { |
| 322 | owner_process->InsertConditionVariableThread(SharedFrom(this)); | 302 | owner_process->InsertConditionVariableThread(SharedFrom(this)); |
| 323 | } | 303 | } |
| 324 | 304 | ||
| @@ -340,7 +320,7 @@ ResultCode Thread::SetActivity(ThreadActivity value) { | |||
| 340 | 320 | ||
| 341 | auto sched_status = GetState(); | 321 | auto sched_status = GetState(); |
| 342 | 322 | ||
| 343 | if (sched_status != ThreadSchedStatus::Runnable && sched_status != ThreadSchedStatus::Paused) { | 323 | if (sched_status != ThreadState::Runnable && sched_status != ThreadState::Waiting) { |
| 344 | return ERR_INVALID_STATE; | 324 | return ERR_INVALID_STATE; |
| 345 | } | 325 | } |
| 346 | 326 | ||
| @@ -366,7 +346,7 @@ ResultCode Thread::Sleep(s64 nanoseconds) { | |||
| 366 | Handle event_handle{}; | 346 | Handle event_handle{}; |
| 367 | { | 347 | { |
| 368 | KScopedSchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds); | 348 | KScopedSchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds); |
| 369 | SetState(ThreadStatus::WaitSleep); | 349 | SetState(ThreadState::Waiting); |
| 370 | } | 350 | } |
| 371 | 351 | ||
| 372 | if (event_handle != InvalidHandle) { | 352 | if (event_handle != InvalidHandle) { |
| @@ -377,25 +357,24 @@ ResultCode Thread::Sleep(s64 nanoseconds) { | |||
| 377 | } | 357 | } |
| 378 | 358 | ||
| 379 | void Thread::AddSchedulingFlag(ThreadSchedFlags flag) { | 359 | void Thread::AddSchedulingFlag(ThreadSchedFlags flag) { |
| 380 | const u32 old_state = scheduling_state; | 360 | const auto old_state = GetRawState(); |
| 381 | pausing_state |= static_cast<u32>(flag); | 361 | pausing_state |= static_cast<u32>(flag); |
| 382 | const u32 base_scheduling = static_cast<u32>(GetState()); | 362 | const auto base_scheduling = GetState(); |
| 383 | scheduling_state = base_scheduling | pausing_state; | 363 | thread_state = base_scheduling | static_cast<ThreadState>(pausing_state); |
| 384 | KScheduler::OnThreadStateChanged(kernel, this, old_state); | 364 | KScheduler::OnThreadStateChanged(kernel, this, old_state); |
| 385 | } | 365 | } |
| 386 | 366 | ||
| 387 | void Thread::RemoveSchedulingFlag(ThreadSchedFlags flag) { | 367 | void Thread::RemoveSchedulingFlag(ThreadSchedFlags flag) { |
| 388 | const u32 old_state = scheduling_state; | 368 | const auto old_state = GetRawState(); |
| 389 | pausing_state &= ~static_cast<u32>(flag); | 369 | pausing_state &= ~static_cast<u32>(flag); |
| 390 | const u32 base_scheduling = static_cast<u32>(GetState()); | 370 | const auto base_scheduling = GetState(); |
| 391 | scheduling_state = base_scheduling | pausing_state; | 371 | thread_state = base_scheduling | static_cast<ThreadState>(pausing_state); |
| 392 | KScheduler::OnThreadStateChanged(kernel, this, old_state); | 372 | KScheduler::OnThreadStateChanged(kernel, this, old_state); |
| 393 | } | 373 | } |
| 394 | 374 | ||
| 395 | void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) { | 375 | void Thread::SetSchedulingStatus(ThreadState new_status) { |
| 396 | const u32 old_state = scheduling_state; | 376 | const auto old_state = GetRawState(); |
| 397 | scheduling_state = (scheduling_state & static_cast<u32>(ThreadSchedMasks::HighMask)) | | 377 | thread_state = (thread_state & ThreadState::HighMask) | new_status; |
| 398 | static_cast<u32>(new_status); | ||
| 399 | KScheduler::OnThreadStateChanged(kernel, this, old_state); | 378 | KScheduler::OnThreadStateChanged(kernel, this, old_state); |
| 400 | } | 379 | } |
| 401 | 380 | ||