Kernel: Correct Signal on Thread Death and Setup Sync Objects on Thread for Debugging

This commit is contained in:
Fernando Sahmkow 2020-03-03 13:37:11 -04:00
parent 75e10578f1
commit b4dc01f16a
3 changed files with 17 additions and 15 deletions

View File

@ -70,6 +70,8 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(
for (auto& object : sync_objects) { for (auto& object : sync_objects) {
object->AddWaitingThread(SharedFrom(thread)); object->AddWaitingThread(SharedFrom(thread));
} }
thread->SetSynchronizationObjects(&sync_objects);
thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT); thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);
thread->SetStatus(ThreadStatus::WaitSynch); thread->SetStatus(ThreadStatus::WaitSynch);
} }
@ -83,6 +85,7 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(
SchedulerLock lock(kernel); SchedulerLock lock(kernel);
ResultCode signaling_result = thread->GetSignalingResult(); ResultCode signaling_result = thread->GetSignalingResult();
SynchronizationObject* signaling_object = thread->GetSignalingObject(); SynchronizationObject* signaling_object = thread->GetSignalingObject();
thread->SetSynchronizationObjects(nullptr);
for (auto& obj : sync_objects) { for (auto& obj : sync_objects) {
obj->RemoveWaitingThread(SharedFrom(thread)); obj->RemoveWaitingThread(SharedFrom(thread));
} }

View File

@ -50,11 +50,11 @@ void Thread::Stop() {
{ {
SchedulerLock lock(kernel); SchedulerLock lock(kernel);
// Cancel any outstanding wakeup events for this thread // Cancel any outstanding wakeup events for this thread
Signal();
Core::System::GetInstance().CoreTiming().UnscheduleEvent( Core::System::GetInstance().CoreTiming().UnscheduleEvent(
kernel.ThreadWakeupCallbackEventType(), global_handle); kernel.ThreadWakeupCallbackEventType(), global_handle);
kernel.GlobalHandleTable().Close(global_handle);
SetStatus(ThreadStatus::Dead); SetStatus(ThreadStatus::Dead);
Signal();
kernel.GlobalHandleTable().Close(global_handle);
owner_process->UnregisterThread(this); owner_process->UnregisterThread(this);
@ -81,7 +81,6 @@ void Thread::CancelWakeupTimer() {
} }
void Thread::ResumeFromWait() { void Thread::ResumeFromWait() {
ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects");
SchedulerLock lock(kernel); SchedulerLock lock(kernel);
switch (status) { switch (status) {
case ThreadStatus::Paused: case ThreadStatus::Paused:
@ -219,7 +218,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
thread->processor_id = processor_id; thread->processor_id = processor_id;
thread->ideal_core = processor_id; thread->ideal_core = processor_id;
thread->affinity_mask = 1ULL << processor_id; thread->affinity_mask = 1ULL << processor_id;
thread->wait_objects.clear(); thread->wait_objects = nullptr;
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;
@ -272,9 +271,9 @@ void Thread::SetSynchronizationResults(SynchronizationObject* object, ResultCode
} }
s32 Thread::GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const { s32 Thread::GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const {
ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything"); ASSERT_MSG(!wait_objects->empty(), "Thread is not waiting for anything");
const auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object); const auto match = std::find(wait_objects->rbegin(), wait_objects->rend(), object);
return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1); return static_cast<s32>(std::distance(match, wait_objects->rend()) - 1);
} }
VAddr Thread::GetCommandBufferAddress() const { VAddr Thread::GetCommandBufferAddress() const {
@ -389,7 +388,7 @@ void Thread::UpdatePriority() {
} }
bool Thread::AllSynchronizationObjectsReady() const { bool Thread::AllSynchronizationObjectsReady() const {
return std::none_of(wait_objects.begin(), wait_objects.end(), return std::none_of(wait_objects->begin(), wait_objects->end(),
[this](const std::shared_ptr<SynchronizationObject>& object) { [this](const std::shared_ptr<SynchronizationObject>& object) {
return object->ShouldWait(this); return object->ShouldWait(this);
}); });

View File

@ -21,7 +21,7 @@ class Fiber;
namespace Core { namespace Core {
class System; class System;
} } // namespace Core
namespace Kernel { namespace Kernel {
@ -386,18 +386,18 @@ public:
} }
const ThreadSynchronizationObjects& GetSynchronizationObjects() const { const ThreadSynchronizationObjects& GetSynchronizationObjects() const {
return wait_objects; return *wait_objects;
} }
void SetSynchronizationObjects(ThreadSynchronizationObjects objects) { void SetSynchronizationObjects(ThreadSynchronizationObjects* objects) {
wait_objects = std::move(objects); wait_objects = objects;
} }
void ClearSynchronizationObjects() { void ClearSynchronizationObjects() {
for (const auto& waiting_object : wait_objects) { for (const auto& waiting_object : *wait_objects) {
waiting_object->RemoveWaitingThread(SharedFrom(this)); waiting_object->RemoveWaitingThread(SharedFrom(this));
} }
wait_objects.clear(); wait_objects->clear();
} }
/// Determines whether all the objects this thread is waiting on are ready. /// Determines whether all the objects this thread is waiting on are ready.
@ -595,7 +595,7 @@ private:
/// Objects that the thread is waiting on, in the same order as they were /// Objects that the thread is waiting on, in the same order as they were
/// passed to WaitSynchronization. /// passed to WaitSynchronization.
ThreadSynchronizationObjects wait_objects; ThreadSynchronizationObjects* wait_objects;
SynchronizationObject* signaling_object; SynchronizationObject* signaling_object;
ResultCode signaling_result{RESULT_SUCCESS}; ResultCode signaling_result{RESULT_SUCCESS};