Thread: Convert wait_handle member to a pointer
This commit is contained in:
parent
5eb52c950d
commit
db0a526fbb
6 changed files with 34 additions and 30 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue