diff options
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 67 | 
1 files changed, 41 insertions, 26 deletions
| diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 1fd1a732a..ee1e9f006 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -534,6 +534,8 @@ static ResultCode CancelSynchronization(Core::System& system, Handle thread_hand      }      thread->CancelWait(); +    if (thread->GetProcessorID() >= 0) +        Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();      return RESULT_SUCCESS;  } @@ -1066,6 +1068,9 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act      }      thread->SetActivity(static_cast<ThreadActivity>(activity)); + +    if (thread->GetProcessorID() >= 0) +        Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();      return RESULT_SUCCESS;  } @@ -1147,7 +1152,8 @@ static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 pri      thread->SetPriority(priority); -    system.CpuCore(thread->GetProcessorID()).PrepareReschedule(); +    if (thread->GetProcessorID() >= 0) +        Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();      return RESULT_SUCCESS;  } @@ -1503,7 +1509,8 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e      thread->SetName(          fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle)); -    system.CpuCore(thread->GetProcessorID()).PrepareReschedule(); +    if (thread->GetProcessorID() >= 0) +        Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();      return RESULT_SUCCESS;  } @@ -1525,7 +1532,10 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) {      thread->ResumeFromWait();      if (thread->GetStatus() == ThreadStatus::Ready) { -        system.CpuCore(thread->GetProcessorID()).PrepareReschedule(); +        if (thread->GetProcessorID() >= 0) +            Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); +        else +            Core::System::GetInstance().GlobalScheduler().SetReselectionPending();      }      return RESULT_SUCCESS; @@ -1537,7 +1547,7 @@ static void ExitThread(Core::System& system) {      auto* const current_thread = system.CurrentScheduler().GetCurrentThread();      current_thread->Stop(); -    system.CurrentScheduler().RemoveThread(current_thread); +    system.GlobalScheduler().RemoveThread(current_thread);      system.PrepareReschedule();  } @@ -1557,13 +1567,13 @@ static void SleepThread(Core::System& system, s64 nanoseconds) {      if (nanoseconds <= 0) {          switch (static_cast<SleepType>(nanoseconds)) {          case SleepType::YieldWithoutLoadBalancing: -            scheduler.YieldWithoutLoadBalancing(current_thread); +            current_thread->YieldType0();              break;          case SleepType::YieldWithLoadBalancing: -            scheduler.YieldWithLoadBalancing(current_thread); +            current_thread->YieldType1();              break;          case SleepType::YieldAndWaitForLoadBalancing: -            scheduler.YieldAndWaitForLoadBalancing(current_thread); +            current_thread->YieldType2();              break;          default:              UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); @@ -1632,24 +1642,16 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var      LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}",                condition_variable_addr, target); -    const auto RetrieveWaitingThreads = [&system](std::size_t core_index, -                                                  std::vector<SharedPtr<Thread>>& waiting_threads, -                                                  VAddr condvar_addr) { -        const auto& scheduler = system.Scheduler(core_index); -        const auto& thread_list = scheduler.GetThreadList(); - -        for (const auto& thread : thread_list) { -            if (thread->GetCondVarWaitAddress() == condvar_addr) -                waiting_threads.push_back(thread); -        } -    }; -      // Retrieve a list of all threads that are waiting for this condition variable.      std::vector<SharedPtr<Thread>> waiting_threads; -    RetrieveWaitingThreads(0, waiting_threads, condition_variable_addr); -    RetrieveWaitingThreads(1, waiting_threads, condition_variable_addr); -    RetrieveWaitingThreads(2, waiting_threads, condition_variable_addr); -    RetrieveWaitingThreads(3, waiting_threads, condition_variable_addr); +    const auto& scheduler = Core::System::GetInstance().GlobalScheduler(); +    const auto& thread_list = scheduler.GetThreadList(); + +    for (const auto& thread : thread_list) { +        if (thread->GetCondVarWaitAddress() == condition_variable_addr) +            waiting_threads.push_back(thread); +    } +      // Sort them by priority, such that the highest priority ones come first.      std::sort(waiting_threads.begin(), waiting_threads.end(),                [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) { @@ -1704,7 +1706,8 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var              thread->SetLockOwner(nullptr);              thread->SetMutexWaitAddress(0);              thread->SetWaitHandle(0); -            system.CpuCore(thread->GetProcessorID()).PrepareReschedule(); +            if (thread->GetProcessorID() >= 0) +                Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();          } else {              // Atomically signal that the mutex now has a waiting thread.              do { @@ -1728,6 +1731,8 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var              thread->SetStatus(ThreadStatus::WaitMutex);              owner->AddMutexWaiter(thread); +            if (thread->GetProcessorID() >= 0) +                Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();          }      } @@ -1753,8 +1758,14 @@ static ResultCode WaitForAddress(Core::System& system, VAddr address, u32 type,      }      const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type); -    auto& address_arbiter = system.Kernel().CurrentProcess()->GetAddressArbiter(); -    return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout); +    auto& address_arbiter = +        system.Kernel().CurrentProcess()->GetAddressArbiter(); +    ResultCode result = address_arbiter.WaitForAddress(address, arbitration_type, value, timeout); +    if (result == RESULT_SUCCESS) +        Core::System::GetInstance() +            .CpuCore(GetCurrentThread()->GetProcessorID()) +            .PrepareReschedule(); +    return result;  }  // Signals to an address (via Address Arbiter) @@ -2040,7 +2051,10 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle,          return ERR_INVALID_HANDLE;      } +    Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();      thread->ChangeCore(core, affinity_mask); +    if (thread->GetProcessorID() >= 0) +        Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();      return RESULT_SUCCESS;  } @@ -2151,6 +2165,7 @@ static ResultCode SignalEvent(Core::System& system, Handle handle) {      }      writable_event->Signal(); +    Core::System::GetInstance().PrepareReschedule();      return RESULT_SUCCESS;  } | 
