thread: Convert ThreadStatus into an enum class

Makes the thread status strongly typed, so implicit conversions can't
happen. It also makes it easier to catch mistakes at compile time.
This commit is contained in:
Lioncash 2018-07-19 21:39:05 -04:00
parent d3cfaf95c8
commit dbfe82773d
10 changed files with 92 additions and 93 deletions

View file

@ -20,7 +20,7 @@ namespace AddressArbiter {
static ResultCode WaitForAddress(VAddr address, s64 timeout) { static ResultCode WaitForAddress(VAddr address, s64 timeout) {
SharedPtr<Thread> current_thread = GetCurrentThread(); SharedPtr<Thread> current_thread = GetCurrentThread();
current_thread->arb_wait_address = address; current_thread->arb_wait_address = address;
current_thread->status = THREADSTATUS_WAIT_ARB; current_thread->status = ThreadStatus::WaitArb;
current_thread->wakeup_callback = nullptr; current_thread->wakeup_callback = nullptr;
current_thread->WakeAfterDelay(timeout); current_thread->WakeAfterDelay(timeout);
@ -65,7 +65,7 @@ static void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num
// Signal the waiting threads. // Signal the waiting threads.
for (size_t i = 0; i < last; i++) { for (size_t i = 0; i < last; i++) {
ASSERT(waiting_threads[i]->status == THREADSTATUS_WAIT_ARB); ASSERT(waiting_threads[i]->status == ThreadStatus::WaitArb);
waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS);
waiting_threads[i]->arb_wait_address = 0; waiting_threads[i]->arb_wait_address = 0;
waiting_threads[i]->ResumeFromWait(); waiting_threads[i]->ResumeFromWait();

View file

@ -38,7 +38,7 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
thread->wakeup_callback = thread->wakeup_callback =
[context = *this, callback](ThreadWakeupReason reason, SharedPtr<Thread> thread, [context = *this, callback](ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object, size_t index) mutable -> bool { SharedPtr<WaitObject> object, size_t index) mutable -> bool {
ASSERT(thread->status == THREADSTATUS_WAIT_HLE_EVENT); ASSERT(thread->status == ThreadStatus::WaitHLEEvent);
callback(thread, context, reason); callback(thread, context, reason);
context.WriteToOutgoingCommandBuffer(*thread); context.WriteToOutgoingCommandBuffer(*thread);
return true; return true;
@ -50,7 +50,7 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
} }
event->Clear(); event->Clear();
thread->status = THREADSTATUS_WAIT_HLE_EVENT; thread->status = ThreadStatus::WaitHLEEvent;
thread->wait_objects = {event}; thread->wait_objects = {event};
event->AddWaitingThread(thread); event->AddWaitingThread(thread);

View file

@ -28,7 +28,7 @@ static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread(
if (thread->mutex_wait_address != mutex_addr) if (thread->mutex_wait_address != mutex_addr)
continue; continue;
ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); ASSERT(thread->status == ThreadStatus::WaitMutex);
++num_waiters; ++num_waiters;
if (highest_priority_thread == nullptr || if (highest_priority_thread == nullptr ||
@ -83,7 +83,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
GetCurrentThread()->mutex_wait_address = address; GetCurrentThread()->mutex_wait_address = address;
GetCurrentThread()->wait_handle = requesting_thread_handle; GetCurrentThread()->wait_handle = requesting_thread_handle;
GetCurrentThread()->status = THREADSTATUS_WAIT_MUTEX; GetCurrentThread()->status = ThreadStatus::WaitMutex;
GetCurrentThread()->wakeup_callback = nullptr; GetCurrentThread()->wakeup_callback = nullptr;
// Update the lock holder thread's priority to prevent priority inversion. // Update the lock holder thread's priority to prevent priority inversion.
@ -121,7 +121,7 @@ ResultCode Mutex::Release(VAddr address) {
// Grant the mutex to the next waiting thread and resume it. // Grant the mutex to the next waiting thread and resume it.
Memory::Write32(address, mutex_value); Memory::Write32(address, mutex_value);
ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); ASSERT(thread->status == ThreadStatus::WaitMutex);
thread->ResumeFromWait(); thread->ResumeFromWait();
thread->lock_owner = nullptr; thread->lock_owner = nullptr;

View file

@ -34,7 +34,7 @@ Thread* Scheduler::PopNextReadyThread() {
Thread* next = nullptr; Thread* next = nullptr;
Thread* thread = GetCurrentThread(); Thread* thread = GetCurrentThread();
if (thread && thread->status == THREADSTATUS_RUNNING) { if (thread && thread->status == ThreadStatus::Running) {
// We have to do better than the current thread. // We have to do better than the current thread.
// This call returns null when that's not possible. // This call returns null when that's not possible.
next = ready_queue.pop_first_better(thread->current_priority); next = ready_queue.pop_first_better(thread->current_priority);
@ -57,17 +57,17 @@ void Scheduler::SwitchContext(Thread* new_thread) {
previous_thread->last_running_ticks = CoreTiming::GetTicks(); previous_thread->last_running_ticks = CoreTiming::GetTicks();
cpu_core->SaveContext(previous_thread->context); cpu_core->SaveContext(previous_thread->context);
if (previous_thread->status == THREADSTATUS_RUNNING) { if (previous_thread->status == ThreadStatus::Running) {
// This is only the case when a reschedule is triggered without the current thread // This is only the case when a reschedule is triggered without the current thread
// yielding execution (i.e. an event triggered, system core time-sliced, etc) // yielding execution (i.e. an event triggered, system core time-sliced, etc)
ready_queue.push_front(previous_thread->current_priority, previous_thread); ready_queue.push_front(previous_thread->current_priority, previous_thread);
previous_thread->status = THREADSTATUS_READY; previous_thread->status = ThreadStatus::Ready;
} }
} }
// Load context of new thread // Load context of new thread
if (new_thread) { if (new_thread) {
ASSERT_MSG(new_thread->status == THREADSTATUS_READY, ASSERT_MSG(new_thread->status == ThreadStatus::Ready,
"Thread must be ready to become running."); "Thread must be ready to become running.");
// Cancel any outstanding wakeup events for this thread // Cancel any outstanding wakeup events for this thread
@ -78,7 +78,7 @@ void Scheduler::SwitchContext(Thread* new_thread) {
current_thread = new_thread; current_thread = new_thread;
ready_queue.remove(new_thread->current_priority, new_thread); ready_queue.remove(new_thread->current_priority, new_thread);
new_thread->status = THREADSTATUS_RUNNING; new_thread->status = ThreadStatus::Running;
if (previous_process != current_thread->owner_process) { if (previous_process != current_thread->owner_process) {
Core::CurrentProcess() = current_thread->owner_process; Core::CurrentProcess() = current_thread->owner_process;
@ -129,14 +129,14 @@ void Scheduler::RemoveThread(Thread* thread) {
void Scheduler::ScheduleThread(Thread* thread, u32 priority) { void Scheduler::ScheduleThread(Thread* thread, u32 priority) {
std::lock_guard<std::mutex> lock(scheduler_mutex); std::lock_guard<std::mutex> lock(scheduler_mutex);
ASSERT(thread->status == THREADSTATUS_READY); ASSERT(thread->status == ThreadStatus::Ready);
ready_queue.push_back(priority, thread); ready_queue.push_back(priority, thread);
} }
void Scheduler::UnscheduleThread(Thread* thread, u32 priority) { void Scheduler::UnscheduleThread(Thread* thread, u32 priority) {
std::lock_guard<std::mutex> lock(scheduler_mutex); std::lock_guard<std::mutex> lock(scheduler_mutex);
ASSERT(thread->status == THREADSTATUS_READY); ASSERT(thread->status == ThreadStatus::Ready);
ready_queue.remove(priority, thread); ready_queue.remove(priority, thread);
} }
@ -144,7 +144,7 @@ void Scheduler::SetThreadPriority(Thread* thread, u32 priority) {
std::lock_guard<std::mutex> lock(scheduler_mutex); std::lock_guard<std::mutex> lock(scheduler_mutex);
// If thread was ready, adjust queues // If thread was ready, adjust queues
if (thread->status == THREADSTATUS_READY) if (thread->status == ThreadStatus::Ready)
ready_queue.move(thread, thread->current_priority, priority); ready_queue.move(thread, thread->current_priority, priority);
else else
ready_queue.prepare(priority); ready_queue.prepare(priority);

View file

@ -110,10 +110,10 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
result = hle_handler->HandleSyncRequest(context); result = hle_handler->HandleSyncRequest(context);
} }
if (thread->status == THREADSTATUS_RUNNING) { if (thread->status == ThreadStatus::Running) {
// Put the thread to sleep until the server replies, it will be awoken in // Put the thread to sleep until the server replies, it will be awoken in
// svcReplyAndReceive for LLE servers. // svcReplyAndReceive for LLE servers.
thread->status = THREADSTATUS_WAIT_IPC; thread->status = ThreadStatus::WaitIPC;
if (hle_handler != nullptr) { if (hle_handler != nullptr) {
// For HLE services, we put the request threads to sleep for a short duration to // For HLE services, we put the request threads to sleep for a short duration to

View file

@ -133,7 +133,7 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
/// Default thread wakeup callback for WaitSynchronization /// Default thread wakeup callback for WaitSynchronization
static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object, size_t index) { SharedPtr<WaitObject> object, size_t index) {
ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); ASSERT(thread->status == ThreadStatus::WaitSynchAny);
if (reason == ThreadWakeupReason::Timeout) { if (reason == ThreadWakeupReason::Timeout) {
thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); thread->SetWaitSynchronizationResult(RESULT_TIMEOUT);
@ -197,7 +197,7 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
object->AddWaitingThread(thread); object->AddWaitingThread(thread);
thread->wait_objects = std::move(objects); thread->wait_objects = std::move(objects);
thread->status = THREADSTATUS_WAIT_SYNCH_ANY; thread->status = ThreadStatus::WaitSynchAny;
// Create an event to wake the thread up after the specified nanosecond delay has passed // Create an event to wake the thread up after the specified nanosecond delay has passed
thread->WakeAfterDelay(nano_seconds); thread->WakeAfterDelay(nano_seconds);
@ -217,7 +217,7 @@ static ResultCode CancelSynchronization(Handle thread_handle) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); ASSERT(thread->status == ThreadStatus::WaitSynchAny);
thread->SetWaitSynchronizationResult( thread->SetWaitSynchronizationResult(
ResultCode(ErrorModule::Kernel, ErrCodes::SynchronizationCanceled)); ResultCode(ErrorModule::Kernel, ErrCodes::SynchronizationCanceled));
thread->ResumeFromWait(); thread->ResumeFromWait();
@ -468,8 +468,8 @@ static void ExitProcess() {
continue; continue;
// TODO(Subv): When are the other running/ready threads terminated? // TODO(Subv): When are the other running/ready threads terminated?
ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY || ASSERT_MSG(thread->status == ThreadStatus::WaitSynchAny ||
thread->status == THREADSTATUS_WAIT_SYNCH_ALL, thread->status == ThreadStatus::WaitSynchAll,
"Exiting processes with non-waiting threads is currently unimplemented"); "Exiting processes with non-waiting threads is currently unimplemented");
thread->Stop(); thread->Stop();
@ -545,7 +545,7 @@ static ResultCode StartThread(Handle thread_handle) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
ASSERT(thread->status == THREADSTATUS_DORMANT); ASSERT(thread->status == ThreadStatus::Dormant);
thread->ResumeFromWait(); thread->ResumeFromWait();
Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule(); Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule();
@ -596,7 +596,7 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
current_thread->condvar_wait_address = condition_variable_addr; current_thread->condvar_wait_address = condition_variable_addr;
current_thread->mutex_wait_address = mutex_addr; current_thread->mutex_wait_address = mutex_addr;
current_thread->wait_handle = thread_handle; current_thread->wait_handle = thread_handle;
current_thread->status = THREADSTATUS_WAIT_MUTEX; current_thread->status = ThreadStatus::WaitMutex;
current_thread->wakeup_callback = nullptr; current_thread->wakeup_callback = nullptr;
current_thread->WakeAfterDelay(nano_seconds); current_thread->WakeAfterDelay(nano_seconds);
@ -656,7 +656,7 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
if (mutex_val == 0) { if (mutex_val == 0) {
// We were able to acquire the mutex, resume this thread. // We were able to acquire the mutex, resume this thread.
Memory::Write32(thread->mutex_wait_address, thread->wait_handle); Memory::Write32(thread->mutex_wait_address, thread->wait_handle);
ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); ASSERT(thread->status == ThreadStatus::WaitMutex);
thread->ResumeFromWait(); thread->ResumeFromWait();
auto lock_owner = thread->lock_owner; auto lock_owner = thread->lock_owner;
@ -672,8 +672,8 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask);
auto owner = g_handle_table.Get<Thread>(owner_handle); auto owner = g_handle_table.Get<Thread>(owner_handle);
ASSERT(owner); ASSERT(owner);
ASSERT(thread->status != THREADSTATUS_RUNNING); ASSERT(thread->status != ThreadStatus::Running);
thread->status = THREADSTATUS_WAIT_MUTEX; thread->status = ThreadStatus::WaitMutex;
thread->wakeup_callback = nullptr; thread->wakeup_callback = nullptr;
// Signal that the mutex now has a waiting thread. // Signal that the mutex now has a waiting thread.

View file

@ -30,7 +30,7 @@ namespace Kernel {
static CoreTiming::EventType* ThreadWakeupEventType = nullptr; static CoreTiming::EventType* ThreadWakeupEventType = nullptr;
bool Thread::ShouldWait(Thread* thread) const { bool Thread::ShouldWait(Thread* thread) const {
return status != THREADSTATUS_DEAD; return status != ThreadStatus::Dead;
} }
void Thread::Acquire(Thread* thread) { void Thread::Acquire(Thread* thread) {
@ -63,11 +63,11 @@ void Thread::Stop() {
// Clean up thread from ready queue // Clean up thread from ready queue
// This is only needed when the thread is termintated forcefully (SVC TerminateProcess) // This is only needed when the thread is termintated forcefully (SVC TerminateProcess)
if (status == THREADSTATUS_READY) { if (status == ThreadStatus::Ready) {
scheduler->UnscheduleThread(this, current_priority); scheduler->UnscheduleThread(this, current_priority);
} }
status = THREADSTATUS_DEAD; status = ThreadStatus::Dead;
WakeupAllWaitingThreads(); WakeupAllWaitingThreads();
@ -86,7 +86,7 @@ void Thread::Stop() {
void WaitCurrentThread_Sleep() { void WaitCurrentThread_Sleep() {
Thread* thread = GetCurrentThread(); Thread* thread = GetCurrentThread();
thread->status = THREADSTATUS_WAIT_SLEEP; thread->status = ThreadStatus::WaitSleep;
} }
void ExitCurrentThread() { void ExitCurrentThread() {
@ -110,10 +110,9 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
bool resume = true; bool resume = true;
if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY || if (thread->status == ThreadStatus::WaitSynchAny ||
thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == ThreadStatus::WaitSynchAll ||
thread->status == THREADSTATUS_WAIT_HLE_EVENT) { thread->status == ThreadStatus::WaitHLEEvent) {
// Remove the thread from each of its waiting objects' waitlists // Remove the thread from each of its waiting objects' waitlists
for (auto& object : thread->wait_objects) for (auto& object : thread->wait_objects)
object->RemoveWaitingThread(thread.get()); object->RemoveWaitingThread(thread.get());
@ -126,7 +125,7 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
if (thread->mutex_wait_address != 0 || thread->condvar_wait_address != 0 || if (thread->mutex_wait_address != 0 || thread->condvar_wait_address != 0 ||
thread->wait_handle) { thread->wait_handle) {
ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); ASSERT(thread->status == ThreadStatus::WaitMutex);
thread->mutex_wait_address = 0; thread->mutex_wait_address = 0;
thread->condvar_wait_address = 0; thread->condvar_wait_address = 0;
thread->wait_handle = 0; thread->wait_handle = 0;
@ -141,7 +140,7 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
} }
if (thread->arb_wait_address != 0) { if (thread->arb_wait_address != 0) {
ASSERT(thread->status == THREADSTATUS_WAIT_ARB); ASSERT(thread->status == ThreadStatus::WaitArb);
thread->arb_wait_address = 0; thread->arb_wait_address = 0;
} }
@ -178,28 +177,28 @@ void Thread::ResumeFromWait() {
ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects"); ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects");
switch (status) { switch (status) {
case THREADSTATUS_WAIT_SYNCH_ALL: case ThreadStatus::WaitSynchAll:
case THREADSTATUS_WAIT_SYNCH_ANY: case ThreadStatus::WaitSynchAny:
case THREADSTATUS_WAIT_HLE_EVENT: case ThreadStatus::WaitHLEEvent:
case THREADSTATUS_WAIT_SLEEP: case ThreadStatus::WaitSleep:
case THREADSTATUS_WAIT_IPC: case ThreadStatus::WaitIPC:
case THREADSTATUS_WAIT_MUTEX: case ThreadStatus::WaitMutex:
case THREADSTATUS_WAIT_ARB: case ThreadStatus::WaitArb:
break; break;
case THREADSTATUS_READY: case ThreadStatus::Ready:
// The thread's wakeup callback must have already been cleared when the thread was first // The thread's wakeup callback must have already been cleared when the thread was first
// awoken. // awoken.
ASSERT(wakeup_callback == nullptr); ASSERT(wakeup_callback == nullptr);
// If the thread is waiting on multiple wait objects, it might be awoken more than once // 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 // before actually resuming. We can ignore subsequent wakeups if the thread status has
// already been set to THREADSTATUS_READY. // already been set to ThreadStatus::Ready.
return; return;
case THREADSTATUS_RUNNING: case ThreadStatus::Running:
DEBUG_ASSERT_MSG(false, "Thread with object id {} has already resumed.", GetObjectId()); DEBUG_ASSERT_MSG(false, "Thread with object id {} has already resumed.", GetObjectId());
return; return;
case THREADSTATUS_DEAD: case ThreadStatus::Dead:
// This should never happen, as threads must complete before being stopped. // 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.", DEBUG_ASSERT_MSG(false, "Thread with object id {} cannot be resumed because it's DEAD.",
GetObjectId()); GetObjectId());
@ -208,7 +207,7 @@ void Thread::ResumeFromWait() {
wakeup_callback = nullptr; wakeup_callback = nullptr;
status = THREADSTATUS_READY; status = ThreadStatus::Ready;
boost::optional<s32> new_processor_id = GetNextProcessorId(affinity_mask); boost::optional<s32> new_processor_id = GetNextProcessorId(affinity_mask);
if (!new_processor_id) { if (!new_processor_id) {
@ -310,7 +309,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
SharedPtr<Thread> thread(new Thread); SharedPtr<Thread> thread(new Thread);
thread->thread_id = NewThreadId(); thread->thread_id = NewThreadId();
thread->status = THREADSTATUS_DORMANT; thread->status = ThreadStatus::Dormant;
thread->entry_point = entry_point; thread->entry_point = entry_point;
thread->stack_top = stack_top; thread->stack_top = stack_top;
thread->nominal_priority = thread->current_priority = priority; thread->nominal_priority = thread->current_priority = priority;
@ -471,7 +470,7 @@ void Thread::ChangeCore(u32 core, u64 mask) {
ideal_core = core; ideal_core = core;
affinity_mask = mask; affinity_mask = mask;
if (status != THREADSTATUS_READY) { if (status != ThreadStatus::Ready) {
return; return;
} }

View file

@ -36,18 +36,18 @@ enum ThreadProcessorId : s32 {
(1 << THREADPROCESSORID_2) | (1 << THREADPROCESSORID_3) (1 << THREADPROCESSORID_2) | (1 << THREADPROCESSORID_3)
}; };
enum ThreadStatus { enum class ThreadStatus {
THREADSTATUS_RUNNING, ///< Currently running Running, ///< Currently running
THREADSTATUS_READY, ///< Ready to run Ready, ///< Ready to run
THREADSTATUS_WAIT_HLE_EVENT, ///< Waiting for hle event to finish WaitHLEEvent, ///< Waiting for hle event to finish
THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC WaitSleep, ///< Waiting due to a SleepThread SVC
THREADSTATUS_WAIT_IPC, ///< Waiting for the reply from an IPC request WaitIPC, ///< Waiting for the reply from an IPC request
THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false WaitSynchAny, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false
THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true WaitSynchAll, ///< Waiting due to WaitSynchronizationN with wait_all = true
THREADSTATUS_WAIT_MUTEX, ///< Waiting due to an ArbitrateLock/WaitProcessWideKey svc WaitMutex, ///< Waiting due to an ArbitrateLock/WaitProcessWideKey svc
THREADSTATUS_WAIT_ARB, ///< Waiting due to a SignalToAddress/WaitForAddress svc WaitArb, ///< Waiting due to a SignalToAddress/WaitForAddress svc
THREADSTATUS_DORMANT, ///< Created but not yet made ready Dormant, ///< Created but not yet made ready
THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated Dead ///< Run to completion, or forcefully terminated
}; };
enum class ThreadWakeupReason { enum class ThreadWakeupReason {
@ -194,14 +194,14 @@ public:
* with wait_all = true. * with wait_all = true.
*/ */
bool IsSleepingOnWaitAll() const { bool IsSleepingOnWaitAll() const {
return status == THREADSTATUS_WAIT_SYNCH_ALL; return status == ThreadStatus::WaitSynchAll;
} }
ARM_Interface::ThreadContext context; ARM_Interface::ThreadContext context;
u32 thread_id; u32 thread_id;
u32 status; ThreadStatus status;
VAddr entry_point; VAddr entry_point;
VAddr stack_top; VAddr stack_top;

View file

@ -38,9 +38,9 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
for (const auto& thread : waiting_threads) { for (const auto& thread : waiting_threads) {
// The list of waiting threads must not contain threads that are not waiting to be awakened. // The list of waiting threads must not contain threads that are not waiting to be awakened.
ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY || ASSERT_MSG(thread->status == ThreadStatus::WaitSynchAny ||
thread->status == THREADSTATUS_WAIT_SYNCH_ALL || thread->status == ThreadStatus::WaitSynchAll ||
thread->status == THREADSTATUS_WAIT_HLE_EVENT, thread->status == ThreadStatus::WaitHLEEvent,
"Inconsistent thread statuses in waiting_threads"); "Inconsistent thread statuses in waiting_threads");
if (thread->current_priority >= candidate_priority) if (thread->current_priority >= candidate_priority)
@ -49,10 +49,10 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
if (ShouldWait(thread.get())) if (ShouldWait(thread.get()))
continue; continue;
// A thread is ready to run if it's either in THREADSTATUS_WAIT_SYNCH_ANY or // A thread is ready to run if it's either in ThreadStatus::WaitSynchAny or
// in THREADSTATUS_WAIT_SYNCH_ALL and the rest of the objects it is waiting on are ready. // in ThreadStatus::WaitSynchAll and the rest of the objects it is waiting on are ready.
bool ready_to_run = true; bool ready_to_run = true;
if (thread->status == THREADSTATUS_WAIT_SYNCH_ALL) { if (thread->status == ThreadStatus::WaitSynchAll) {
ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(), ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(),
[&thread](const SharedPtr<WaitObject>& object) { [&thread](const SharedPtr<WaitObject>& object) {
return object->ShouldWait(thread.get()); return object->ShouldWait(thread.get());

View file

@ -194,32 +194,32 @@ QString WaitTreeThread::GetText() const {
const auto& thread = static_cast<const Kernel::Thread&>(object); const auto& thread = static_cast<const Kernel::Thread&>(object);
QString status; QString status;
switch (thread.status) { switch (thread.status) {
case THREADSTATUS_RUNNING: case ThreadStatus::Running:
status = tr("running"); status = tr("running");
break; break;
case THREADSTATUS_READY: case ThreadStatus::Ready:
status = tr("ready"); status = tr("ready");
break; break;
case THREADSTATUS_WAIT_HLE_EVENT: case ThreadStatus::WaitHLEEvent:
status = tr("waiting for HLE return"); status = tr("waiting for HLE return");
break; break;
case THREADSTATUS_WAIT_SLEEP: case ThreadStatus::WaitSleep:
status = tr("sleeping"); status = tr("sleeping");
break; break;
case THREADSTATUS_WAIT_SYNCH_ALL: case ThreadStatus::WaitSynchAll:
case THREADSTATUS_WAIT_SYNCH_ANY: case ThreadStatus::WaitSynchAny:
status = tr("waiting for objects"); status = tr("waiting for objects");
break; break;
case THREADSTATUS_WAIT_MUTEX: case ThreadStatus::WaitMutex:
status = tr("waiting for mutex"); status = tr("waiting for mutex");
break; break;
case THREADSTATUS_WAIT_ARB: case ThreadStatus::WaitArb:
status = tr("waiting for address arbiter"); status = tr("waiting for address arbiter");
break; break;
case THREADSTATUS_DORMANT: case ThreadStatus::Dormant:
status = tr("dormant"); status = tr("dormant");
break; break;
case THREADSTATUS_DEAD: case ThreadStatus::Dead:
status = tr("dead"); status = tr("dead");
break; break;
} }
@ -232,22 +232,22 @@ QString WaitTreeThread::GetText() const {
QColor WaitTreeThread::GetColor() const { QColor WaitTreeThread::GetColor() const {
const auto& thread = static_cast<const Kernel::Thread&>(object); const auto& thread = static_cast<const Kernel::Thread&>(object);
switch (thread.status) { switch (thread.status) {
case THREADSTATUS_RUNNING: case ThreadStatus::Running:
return QColor(Qt::GlobalColor::darkGreen); return QColor(Qt::GlobalColor::darkGreen);
case THREADSTATUS_READY: case ThreadStatus::Ready:
return QColor(Qt::GlobalColor::darkBlue); return QColor(Qt::GlobalColor::darkBlue);
case THREADSTATUS_WAIT_HLE_EVENT: case ThreadStatus::WaitHLEEvent:
return QColor(Qt::GlobalColor::darkRed); return QColor(Qt::GlobalColor::darkRed);
case THREADSTATUS_WAIT_SLEEP: case ThreadStatus::WaitSleep:
return QColor(Qt::GlobalColor::darkYellow); return QColor(Qt::GlobalColor::darkYellow);
case THREADSTATUS_WAIT_SYNCH_ALL: case ThreadStatus::WaitSynchAll:
case THREADSTATUS_WAIT_SYNCH_ANY: case ThreadStatus::WaitSynchAny:
case THREADSTATUS_WAIT_MUTEX: case ThreadStatus::WaitMutex:
case THREADSTATUS_WAIT_ARB: case ThreadStatus::WaitArb:
return QColor(Qt::GlobalColor::red); return QColor(Qt::GlobalColor::red);
case THREADSTATUS_DORMANT: case ThreadStatus::Dormant:
return QColor(Qt::GlobalColor::darkCyan); return QColor(Qt::GlobalColor::darkCyan);
case THREADSTATUS_DEAD: case ThreadStatus::Dead:
return QColor(Qt::GlobalColor::gray); return QColor(Qt::GlobalColor::gray);
default: default:
return WaitTreeItem::GetColor(); return WaitTreeItem::GetColor();
@ -291,8 +291,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
else else
list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex"))); list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex")));
if (thread.status == THREADSTATUS_WAIT_SYNCH_ANY || if (thread.status == ThreadStatus::WaitSynchAny ||
thread.status == THREADSTATUS_WAIT_SYNCH_ALL) { thread.status == ThreadStatus::WaitSynchAll) {
list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects, list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects,
thread.IsSleepingOnWaitAll())); thread.IsSleepingOnWaitAll()));
} }