mirror of
https://gitlab.com/suyu-emu/suyu.git
synced 2024-03-15 23:15:44 +00:00
Merge pull request #734 from lioncash/thread
thread: Convert ThreadStatus into an enum class
This commit is contained in:
commit
741cae1e1d
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue