mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-11-15 13:50:06 +00:00
Kernel: Correct Signal on Thread Death and Setup Sync Objects on Thread for Debugging
This commit is contained in:
parent
75e10578f1
commit
b4dc01f16a
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
});
|
});
|
||||||
|
@ -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};
|
||||||
|
Loading…
Reference in New Issue
Block a user