diff options
| -rw-r--r-- | src/core/core_timing.cpp | 42 | ||||
| -rw-r--r-- | src/core/core_timing.h | 9 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_hardware_timer.cpp | 6 | 
3 files changed, 28 insertions, 29 deletions
| diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 0e7b5f943..6bac6722f 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -142,16 +142,24 @@ void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time,  }  void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, -                                 std::uintptr_t user_data) { -    std::scoped_lock scope{basic_lock}; -    const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { -        return e.type.lock().get() == event_type.get() && e.user_data == user_data; -    }); - -    // Removing random items breaks the invariant so we have to re-establish it. -    if (itr != event_queue.end()) { -        event_queue.erase(itr, event_queue.end()); -        std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>()); +                                 std::uintptr_t user_data, bool wait) { +    { +        std::scoped_lock lk{basic_lock}; +        const auto itr = +            std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { +                return e.type.lock().get() == event_type.get() && e.user_data == user_data; +            }); + +        // Removing random items breaks the invariant so we have to re-establish it. +        if (itr != event_queue.end()) { +            event_queue.erase(itr, event_queue.end()); +            std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>()); +        } +    } + +    // Force any in-progress events to finish +    if (wait) { +        std::scoped_lock lk{advance_lock};      }  } @@ -190,20 +198,6 @@ u64 CoreTiming::GetClockTicks() const {      return CpuCyclesToClockCycles(ticks);  } -void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { -    std::scoped_lock lock{basic_lock}; - -    const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { -        return e.type.lock().get() == event_type.get(); -    }); - -    // Removing random items breaks the invariant so we have to re-establish it. -    if (itr != event_queue.end()) { -        event_queue.erase(itr, event_queue.end()); -        std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>()); -    } -} -  std::optional<s64> CoreTiming::Advance() {      std::scoped_lock lock{advance_lock, basic_lock};      global_timer = GetGlobalTimeNs().count(); diff --git a/src/core/core_timing.h b/src/core/core_timing.h index b5925193c..da366637b 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -98,10 +98,13 @@ public:                                const std::shared_ptr<EventType>& event_type,                                std::uintptr_t user_data = 0, bool absolute_time = false); -    void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data); +    void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data, +                         bool wait = true); -    /// We only permit one event of each type in the queue at a time. -    void RemoveEvent(const std::shared_ptr<EventType>& event_type); +    void UnscheduleEventWithoutWait(const std::shared_ptr<EventType>& event_type, +                                    std::uintptr_t user_data) { +        UnscheduleEvent(event_type, user_data, false); +    }      void AddTicks(u64 ticks_to_add); diff --git a/src/core/hle/kernel/k_hardware_timer.cpp b/src/core/hle/kernel/k_hardware_timer.cpp index 6bba79ea0..4dcd53821 100644 --- a/src/core/hle/kernel/k_hardware_timer.cpp +++ b/src/core/hle/kernel/k_hardware_timer.cpp @@ -18,7 +18,8 @@ void KHardwareTimer::Initialize() {  }  void KHardwareTimer::Finalize() { -    this->DisableInterrupt(); +    m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type, reinterpret_cast<uintptr_t>(this)); +    m_wakeup_time = std::numeric_limits<s64>::max();      m_event_type.reset();  } @@ -59,7 +60,8 @@ void KHardwareTimer::EnableInterrupt(s64 wakeup_time) {  }  void KHardwareTimer::DisableInterrupt() { -    m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type, reinterpret_cast<uintptr_t>(this)); +    m_kernel.System().CoreTiming().UnscheduleEventWithoutWait(m_event_type, +                                                              reinterpret_cast<uintptr_t>(this));      m_wakeup_time = std::numeric_limits<s64>::max();  } | 
