Thread: Convert wait_handle member to a pointer

This commit is contained in:
Yuri Kunde Schlesner 2014-12-22 12:37:10 -02:00
parent 5eb52c950d
commit db0a526fbb
6 changed files with 34 additions and 30 deletions

View File

@ -30,6 +30,10 @@ public:
/// Arbitrate an address /// Arbitrate an address
ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) { ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) {
Object* object = Kernel::g_handle_table.GetGeneric(handle);
if (object == nullptr)
return InvalidHandle(ErrorModule::Kernel);
switch (type) { switch (type) {
// Signal thread(s) waiting for arbitrate address... // Signal thread(s) waiting for arbitrate address...
@ -47,7 +51,7 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
// Wait current thread (acquire the arbiter)... // Wait current thread (acquire the arbiter)...
case ArbitrationType::WaitIfLessThan: case ArbitrationType::WaitIfLessThan:
if ((s32)Memory::Read32(address) <= value) { if ((s32)Memory::Read32(address) <= value) {
Kernel::WaitCurrentThread(WAITTYPE_ARB, handle, address); Kernel::WaitCurrentThread(WAITTYPE_ARB, object, address);
HLE::Reschedule(__func__); HLE::Reschedule(__func__);
} }
break; break;

View File

@ -37,7 +37,7 @@ public:
if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) {
waiting_threads.push_back(thread); waiting_threads.push_back(thread);
} }
Kernel::WaitCurrentThread(WAITTYPE_EVENT, GetHandle()); Kernel::WaitCurrentThread(WAITTYPE_EVENT, this);
} }
if (reset_type != RESETTYPE_STICKY && !permanent_locked) { if (reset_type != RESETTYPE_STICKY && !permanent_locked) {
locked = true; locked = true;

View File

@ -171,7 +171,7 @@ Handle CreateMutex(bool initial_locked, const std::string& name) {
ResultVal<bool> Mutex::WaitSynchronization() { ResultVal<bool> Mutex::WaitSynchronization() {
bool wait = locked; bool wait = locked;
if (locked) { if (locked) {
Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle()); Kernel::WaitCurrentThread(WAITTYPE_MUTEX, this);
} }
else { else {
// Lock the mutex when the first thread accesses it // Lock the mutex when the first thread accesses it

View File

@ -37,7 +37,7 @@ public:
bool wait = !IsAvailable(); bool wait = !IsAvailable();
if (wait) { if (wait) {
Kernel::WaitCurrentThread(WAITTYPE_SEMA, GetHandle()); Kernel::WaitCurrentThread(WAITTYPE_SEMA, this);
waiting_threads.push(GetCurrentThread()->GetHandle()); waiting_threads.push(GetCurrentThread()->GetHandle());
} else { } else {
--available_count; --available_count;

View File

@ -28,7 +28,7 @@ ResultVal<bool> Thread::WaitSynchronization() {
if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) {
waiting_threads.push_back(thread); waiting_threads.push_back(thread);
} }
WaitCurrentThread(WAITTYPE_THREADEND, this->GetHandle()); WaitCurrentThread(WAITTYPE_THREADEND, this);
} }
return MakeResult<bool>(wait); return MakeResult<bool>(wait);
@ -82,7 +82,7 @@ void ResetThread(Thread* t, u32 arg, s32 lowest_priority) {
t->current_priority = t->initial_priority; t->current_priority = t->initial_priority;
} }
t->wait_type = WAITTYPE_NONE; t->wait_type = WAITTYPE_NONE;
t->wait_handle = 0; t->wait_object = nullptr;
t->wait_address = 0; t->wait_address = 0;
} }
@ -109,13 +109,13 @@ static bool CheckWaitType(const Thread* thread, WaitType type) {
} }
/// Check if a thread is blocking on a specified wait type with a specified handle /// Check if a thread is blocking on a specified wait type with a specified handle
static bool CheckWaitType(const Thread* thread, WaitType type, Handle wait_handle) { static bool CheckWaitType(const Thread* thread, WaitType type, Object* wait_object) {
return CheckWaitType(thread, type) && (wait_handle == thread->wait_handle); return CheckWaitType(thread, type) && wait_object == thread->wait_object;
} }
/// Check if a thread is blocking on a specified wait type with a specified handle and address /// Check if a thread is blocking on a specified wait type with a specified handle and address
static bool CheckWaitType(const Thread* thread, WaitType type, Handle wait_handle, VAddr wait_address) { static bool CheckWaitType(const Thread* thread, WaitType type, Object* wait_object, VAddr wait_address) {
return CheckWaitType(thread, type, wait_handle) && (wait_address == thread->wait_address); return CheckWaitType(thread, type, wait_object) && (wait_address == thread->wait_address);
} }
/// Stops the current thread /// Stops the current thread
@ -126,14 +126,14 @@ void Thread::Stop(const char* reason) {
ChangeReadyState(this, false); ChangeReadyState(this, false);
status = THREADSTATUS_DORMANT; status = THREADSTATUS_DORMANT;
for (Thread* waiting_thread : waiting_threads) { for (Thread* waiting_thread : waiting_threads) {
if (CheckWaitType(waiting_thread, WAITTYPE_THREADEND, GetHandle())) if (CheckWaitType(waiting_thread, WAITTYPE_THREADEND, this))
waiting_thread->ResumeFromWait(); waiting_thread->ResumeFromWait();
} }
waiting_threads.clear(); waiting_threads.clear();
// Stopped threads are never waiting. // Stopped threads are never waiting.
wait_type = WAITTYPE_NONE; wait_type = WAITTYPE_NONE;
wait_handle = 0; wait_object = nullptr;
wait_address = 0; wait_address = 0;
} }
@ -153,7 +153,7 @@ void ChangeThreadState(Thread* t, ThreadStatus new_status) {
} }
/// Arbitrate the highest priority thread that is waiting /// Arbitrate the highest priority thread that is waiting
Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) { Handle ArbitrateHighestPriorityThread(Handle arbiter, u32 address) {
Handle highest_priority_thread = 0; Handle highest_priority_thread = 0;
s32 priority = THREADPRIO_LOWEST; s32 priority = THREADPRIO_LOWEST;
@ -161,7 +161,7 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) {
for (Handle handle : thread_queue) { for (Handle handle : thread_queue) {
Thread* thread = g_handle_table.Get<Thread>(handle); Thread* thread = g_handle_table.Get<Thread>(handle);
if (!CheckWaitType(thread, WAITTYPE_ARB, arbiter, address)) if (!CheckWaitType(thread, WAITTYPE_ARB, Kernel::g_handle_table.GetGeneric(arbiter), address))
continue; continue;
if (thread == nullptr) if (thread == nullptr)
@ -183,13 +183,13 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) {
} }
/// Arbitrate all threads currently waiting /// Arbitrate all threads currently waiting
void ArbitrateAllThreads(u32 arbiter, u32 address) { void ArbitrateAllThreads(Handle arbiter, u32 address) {
// Iterate through threads, find highest priority thread that is waiting to be arbitrated... // Iterate through threads, find highest priority thread that is waiting to be arbitrated...
for (Handle handle : thread_queue) { for (Handle handle : thread_queue) {
Thread* thread = g_handle_table.Get<Thread>(handle); Thread* thread = g_handle_table.Get<Thread>(handle);
if (CheckWaitType(thread, WAITTYPE_ARB, arbiter, address)) if (CheckWaitType(thread, WAITTYPE_ARB, Kernel::g_handle_table.GetGeneric(arbiter), address))
thread->ResumeFromWait(); thread->ResumeFromWait();
} }
} }
@ -243,22 +243,22 @@ Thread* NextThread() {
return Kernel::g_handle_table.Get<Thread>(next); return Kernel::g_handle_table.Get<Thread>(next);
} }
void WaitCurrentThread(WaitType wait_type, Handle wait_handle) { void WaitCurrentThread(WaitType wait_type, Object* wait_object) {
Thread* thread = GetCurrentThread(); Thread* thread = GetCurrentThread();
thread->wait_type = wait_type; thread->wait_type = wait_type;
thread->wait_handle = wait_handle; thread->wait_object = wait_object;
ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND)));
} }
void WaitCurrentThread(WaitType wait_type, Handle wait_handle, VAddr wait_address) { void WaitCurrentThread(WaitType wait_type, Object* wait_object, VAddr wait_address) {
WaitCurrentThread(wait_type, wait_handle); WaitCurrentThread(wait_type, wait_object);
GetCurrentThread()->wait_address = wait_address; GetCurrentThread()->wait_address = wait_address;
} }
/// Resumes a thread from waiting by marking it as "ready" /// Resumes a thread from waiting by marking it as "ready"
void Thread::ResumeFromWait() { void Thread::ResumeFromWait() {
status &= ~THREADSTATUS_WAIT; status &= ~THREADSTATUS_WAIT;
wait_handle = 0; wait_object = nullptr;
wait_type = WAITTYPE_NONE; wait_type = WAITTYPE_NONE;
if (!(status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { if (!(status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) {
ChangeReadyState(this, true); ChangeReadyState(this, true);
@ -327,7 +327,7 @@ ResultVal<Thread*> Thread::Create(const char* name, u32 entry_point, s32 priorit
thread->initial_priority = thread->current_priority = priority; thread->initial_priority = thread->current_priority = priority;
thread->processor_id = processor_id; thread->processor_id = processor_id;
thread->wait_type = WAITTYPE_NONE; thread->wait_type = WAITTYPE_NONE;
thread->wait_handle = 0; thread->wait_object = nullptr;
thread->wait_address = 0; thread->wait_address = 0;
thread->name = name; thread->name = name;
@ -402,7 +402,7 @@ void Reschedule() {
for (Handle handle : thread_queue) { for (Handle handle : thread_queue) {
Thread* thread = g_handle_table.Get<Thread>(handle); Thread* thread = g_handle_table.Get<Thread>(handle);
LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X wait_handle=0x%08X", LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X wait_handle=0x%08X",
thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type, thread->wait_handle); thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type, thread->wait_object->GetHandle());
} }
} }

View File

@ -94,7 +94,7 @@ public:
s32 processor_id; s32 processor_id;
WaitType wait_type; WaitType wait_type;
Handle wait_handle; Object* wait_object;
VAddr wait_address; VAddr wait_address;
std::vector<Thread*> waiting_threads; // TODO(yuriks): Owned std::vector<Thread*> waiting_threads; // TODO(yuriks): Owned
@ -112,10 +112,10 @@ Thread* SetupMainThread(s32 priority, int stack_size = Kernel::DEFAULT_STACK_SIZ
void Reschedule(); void Reschedule();
/// Arbitrate the highest priority thread that is waiting /// Arbitrate the highest priority thread that is waiting
Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address); Handle ArbitrateHighestPriorityThread(Handle arbiter, u32 address);
/// Arbitrate all threads currently waiting... /// Arbitrate all threads currently waiting...
void ArbitrateAllThreads(u32 arbiter, u32 address); void ArbitrateAllThreads(Handle arbiter, u32 address);
/// Gets the current thread /// Gets the current thread
Thread* GetCurrentThread(); Thread* GetCurrentThread();
@ -123,17 +123,17 @@ Thread* GetCurrentThread();
/** /**
* Puts the current thread in the wait state for the given type * Puts the current thread in the wait state for the given type
* @param wait_type Type of wait * @param wait_type Type of wait
* @param wait_handle Handle of Kernel object that we are waiting on, defaults to current thread * @param wait_object Kernel object that we are waiting on, defaults to current thread
*/ */
void WaitCurrentThread(WaitType wait_type, Handle wait_handle = GetCurrentThread()->GetHandle()); void WaitCurrentThread(WaitType wait_type, Object* wait_object = GetCurrentThread());
/** /**
* Puts the current thread in the wait state for the given type * Puts the current thread in the wait state for the given type
* @param wait_type Type of wait * @param wait_type Type of wait
* @param wait_handle Handle of Kernel object that we are waiting on, defaults to current thread * @param wait_object Kernel object that we are waiting on
* @param wait_address Arbitration address used to resume from wait * @param wait_address Arbitration address used to resume from wait
*/ */
void WaitCurrentThread(WaitType wait_type, Handle wait_handle, VAddr wait_address); void WaitCurrentThread(WaitType wait_type, Object* wait_object, VAddr wait_address);
/// Put current thread in a wait state - on WaitSynchronization /// Put current thread in a wait state - on WaitSynchronization
void WaitThread_Synchronization(); void WaitThread_Synchronization();