diff options
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 27 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/scheduler.h | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 27 | ||||
| -rw-r--r-- | src/core/hle/kernel/synchronization.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/kernel/time_manager.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/time_manager.h | 1 | 
8 files changed, 38 insertions, 38 deletions
| diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 07acabc1d..e8f22b598 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -34,19 +34,9 @@ void AddressArbiter::WakeThreads(const std::vector<std::shared_ptr<Thread>>& wai      // Signal the waiting threads.      for (std::size_t i = 0; i < last; i++) { -        if (waiting_threads[i]->GetStatus() != ThreadStatus::WaitArb) { -            last++; -            last = std::min(waiting_threads.size(), last); -            continue; -        } - -        time_manager.CancelTimeEvent(waiting_threads[i].get()); - -        ASSERT(waiting_threads[i]->GetStatus() == ThreadStatus::WaitArb);          waiting_threads[i]->SetSynchronizationResults(nullptr, RESULT_SUCCESS);          RemoveThread(waiting_threads[i]);          waiting_threads[i]->WaitForArbitration(false); -        waiting_threads[i]->SetArbiterWaitAddress(0);          waiting_threads[i]->ResumeFromWait();      }  } @@ -172,20 +162,25 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6      {          SchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout); +        if (current_thread->IsPendingTermination()) { +            lock.CancelSleep(); +            return ERR_THREAD_TERMINATING; +        } +          // Ensure that we can read the address.          if (!memory.IsValidVirtualAddress(address)) {              lock.CancelSleep();              return ERR_INVALID_ADDRESS_STATE;          } -        /// TODO(Blinkhawk): Check termination pending. -          s32 current_value = static_cast<s32>(memory.Read32(address));          if (current_value >= value) {              lock.CancelSleep();              return ERR_INVALID_STATE;          } +        current_thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT); +          s32 decrement_value;          const std::size_t current_core = system.CurrentCoreIndex(); @@ -207,7 +202,6 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6              return RESULT_TIMEOUT;          } -        current_thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT);          current_thread->SetArbiterWaitAddress(address);          InsertThread(SharedFrom(current_thread));          current_thread->SetStatus(ThreadStatus::WaitArb); @@ -239,14 +233,17 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t      {          SchedulerLockAndSleep lock(kernel, event_handle, current_thread, timeout); +        if (current_thread->IsPendingTermination()) { +            lock.CancelSleep(); +            return ERR_THREAD_TERMINATING; +        } +          // Ensure that we can read the address.          if (!memory.IsValidVirtualAddress(address)) {              lock.CancelSleep();              return ERR_INVALID_ADDRESS_STATE;          } -        /// TODO(Blinkhawk): Check termination pending. -          s32 current_value = static_cast<s32>(memory.Read32(address));          if (current_value != value) {              lock.CancelSleep(); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index ba051a7d8..721ab1e70 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -49,6 +49,7 @@ namespace Kernel {   * @param cycles_late The number of CPU cycles that have passed since the desired wakeup time   */  static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_late) { +    UNREACHABLE();      const auto proper_handle = static_cast<Handle>(thread_handle);      const auto& system = Core::System::GetInstance(); diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index ab17204bb..5322f0aae 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -133,6 +133,7 @@ u32 GlobalScheduler::SelectThreads() {      u32 cores_needing_context_switch{};      for (u32 core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {          Scheduler& sched = kernel.Scheduler(core); +        ASSERT(top_threads[core] == nullptr || top_threads[core]->GetProcessorID() == core);          if (update_thread(top_threads[core], sched)) {              cores_needing_context_switch |= (1ul << core);          } @@ -244,7 +245,7 @@ bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread              winner = yielding_thread;          }      } else { -        winner = scheduled_queue[i].front(); +        winner = scheduled_queue[core_id].front();      }      if (kernel.GetCurrentHostThreadID() != core_id) { diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index 728cca802..5e062bf59 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h @@ -16,7 +16,7 @@  #include "core/hle/kernel/thread.h"  namespace Common { -    class Fiber; +class Fiber;  }  namespace Core { @@ -133,7 +133,8 @@ private:      /// and reschedules current core if needed.      void Unlock(); -    void EnableInterruptAndSchedule(u32 cores_pending_reschedule, Core::EmuThreadHandle global_thread); +    void EnableInterruptAndSchedule(u32 cores_pending_reschedule, +                                    Core::EmuThreadHandle global_thread);      /**       * Add a thread to the suggested queue of a cpu core. Suggested threads may be diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 371beed0d..aad2ac549 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1562,6 +1562,11 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add          current_thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT); +        if (thread->IsPendingTermination()) { +            lock.CancelSleep(); +            return ERR_THREAD_TERMINATING; +        } +          const auto release_result = current_process->GetMutex().Release(mutex_addr);          if (release_result.IsError()) {              lock.CancelSleep(); @@ -1588,6 +1593,11 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add      {          SchedulerLock lock(kernel); +        auto* owner = current_thread->GetLockOwner(); +        if (owner != nullptr) { +            owner->RemoveMutexWaiter(SharedFrom(current_thread)); +        } +          current_process->RemoveConditionVariableThread(SharedFrom(current_thread));      }      // Note: Deliberately don't attempt to inherit the lock owner's priority. @@ -1618,19 +1628,10 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_      for (std::size_t index = 0; index < last; ++index) {          auto& thread = waiting_threads[index]; -        if (thread->GetStatus() != ThreadStatus::WaitCondVar) { -            last++; -            last = std::min(waiting_threads.size(), last); -            continue; -        } - -        time_manager.CancelTimeEvent(thread.get()); -          ASSERT(thread->GetCondVarWaitAddress() == condition_variable_addr);          // liberate Cond Var Thread.          current_process->RemoveConditionVariableThread(thread); -        thread->SetCondVarWaitAddress(0);          const std::size_t current_core = system.CurrentCoreIndex();          auto& monitor = system.Monitor(); @@ -1655,9 +1656,6 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_          monitor.ClearExclusive();          if (mutex_val == 0) {              // We were able to acquire the mutex, resume this thread. -            ASSERT(thread->GetStatus() == ThreadStatus::WaitCondVar); -            thread->ResumeFromWait(); -              auto* const lock_owner = thread->GetLockOwner();              if (lock_owner != nullptr) {                  lock_owner->RemoveMutexWaiter(thread); @@ -1665,13 +1663,16 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_              thread->SetLockOwner(nullptr);              thread->SetSynchronizationResults(nullptr, RESULT_SUCCESS); +            thread->ResumeFromWait();          } else {              // The mutex is already owned by some other thread, make this thread wait on it.              const Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask);              const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();              auto owner = handle_table.Get<Thread>(owner_handle);              ASSERT(owner); -            thread->SetStatus(ThreadStatus::WaitMutex); +            if (thread->GetStatus() == ThreadStatus::WaitCondVar) { +                thread->SetStatus(ThreadStatus::WaitMutex); +            }              owner->AddMutexWaiter(thread);          } diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp index 4323fc120..275bf11cc 100644 --- a/src/core/hle/kernel/synchronization.cpp +++ b/src/core/hle/kernel/synchronization.cpp @@ -23,9 +23,10 @@ void Synchronization::SignalObject(SynchronizationObject& obj) const {      if (obj.IsSignaled()) {          for (auto thread : obj.GetWaitingThreads()) {              if (thread->GetSchedulingStatus() == ThreadSchedStatus::Paused) { +                ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch); +                ASSERT(thread->IsWaitingSync());                  thread->SetSynchronizationResults(&obj, RESULT_SUCCESS);                  thread->ResumeFromWait(); -                time_manager.CancelTimeEvent(thread.get());              }          }          obj.ClearWaitingThreads(); @@ -91,10 +92,11 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(          ResultCode signaling_result = thread->GetSignalingResult();          SynchronizationObject* signaling_object = thread->GetSignalingObject();          thread->SetSynchronizationObjects(nullptr); +        auto shared_thread = SharedFrom(thread);          for (auto& obj : sync_objects) { -            obj->RemoveWaitingThread(SharedFrom(thread)); +            obj->RemoveWaitingThread(shared_thread);          } -        if (signaling_result == RESULT_SUCCESS) { +        if (signaling_object != nullptr) {              const auto itr = std::find_if(                  sync_objects.begin(), sync_objects.end(),                  [signaling_object](const std::shared_ptr<SynchronizationObject>& object) { @@ -103,7 +105,7 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(              ASSERT(itr != sync_objects.end());              signaling_object->Acquire(thread);              const u32 index = static_cast<s32>(std::distance(sync_objects.begin(), itr)); -            return {RESULT_SUCCESS, index}; +            return {signaling_result, index};          }          return {signaling_result, -1};      } diff --git a/src/core/hle/kernel/time_manager.cpp b/src/core/hle/kernel/time_manager.cpp index dab5fc4c6..cc228f5f7 100644 --- a/src/core/hle/kernel/time_manager.cpp +++ b/src/core/hle/kernel/time_manager.cpp @@ -22,7 +22,6 @@ TimeManager::TimeManager(Core::System& system_) : system{system_} {              if (cancelled_events[proper_handle]) {                  return;              } -            event_fired[proper_handle] = true;              std::shared_ptr<Thread> thread =                  this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle);              thread->OnWakeUp(); @@ -39,7 +38,6 @@ void TimeManager::ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64          event_handle = InvalidHandle;      }      cancelled_events[event_handle] = false; -    event_fired[event_handle] = false;  }  void TimeManager::UnscheduleTimeEvent(Handle event_handle) { diff --git a/src/core/hle/kernel/time_manager.h b/src/core/hle/kernel/time_manager.h index 3080ac838..307a18765 100644 --- a/src/core/hle/kernel/time_manager.h +++ b/src/core/hle/kernel/time_manager.h @@ -42,7 +42,6 @@ private:      Core::System& system;      std::shared_ptr<Core::Timing::EventType> time_manager_event_type;      std::unordered_map<Handle, bool> cancelled_events; -    std::unordered_map<Handle, bool> event_fired;  };  } // namespace Kernel | 
