summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2020-02-10 20:02:04 +0100
committerFernando Sahmkow <fsahmkow27@gmail.com>2020-06-18 22:29:22 +0200
commit49a7e0984a1210832b8be24433a95711c7ce029b (patch)
tree73cfc4456382895f75b6f56f5f1bb96501929de9 /src/core
parentCommon/Tests: Address Feedback (diff)
downloadyuzu-49a7e0984a1210832b8be24433a95711c7ce029b.tar
yuzu-49a7e0984a1210832b8be24433a95711c7ce029b.tar.gz
yuzu-49a7e0984a1210832b8be24433a95711c7ce029b.tar.bz2
yuzu-49a7e0984a1210832b8be24433a95711c7ce029b.tar.lz
yuzu-49a7e0984a1210832b8be24433a95711c7ce029b.tar.xz
yuzu-49a7e0984a1210832b8be24433a95711c7ce029b.tar.zst
yuzu-49a7e0984a1210832b8be24433a95711c7ce029b.zip
Diffstat (limited to 'src/core')
-rw-r--r--src/core/host_timing.cpp61
-rw-r--r--src/core/host_timing.h6
2 files changed, 41 insertions, 26 deletions
diff --git a/src/core/host_timing.cpp b/src/core/host_timing.cpp
index be80d9f8e..5d35a96b1 100644
--- a/src/core/host_timing.cpp
+++ b/src/core/host_timing.cpp
@@ -42,7 +42,7 @@ CoreTiming::CoreTiming() {
CoreTiming::~CoreTiming() = default;
void CoreTiming::ThreadEntry(CoreTiming& instance) {
- instance.Advance();
+ instance.ThreadLoop();
}
void CoreTiming::Initialize() {
@@ -137,38 +137,49 @@ void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) {
basic_lock.unlock();
}
-void CoreTiming::Advance() {
- has_started = true;
- while (!shutting_down) {
- while (!paused) {
- paused_set = false;
- basic_lock.lock();
- global_timer = GetGlobalTimeNs().count();
+std::optional<u64> CoreTiming::Advance() {
+ advance_lock.lock();
+ basic_lock.lock();
+ global_timer = GetGlobalTimeNs().count();
- while (!event_queue.empty() && event_queue.front().time <= global_timer) {
- Event evt = std::move(event_queue.front());
- std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>());
- event_queue.pop_back();
- basic_lock.unlock();
+ while (!event_queue.empty() && event_queue.front().time <= global_timer) {
+ Event evt = std::move(event_queue.front());
+ std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>());
+ event_queue.pop_back();
+ basic_lock.unlock();
- if (auto event_type{evt.type.lock()}) {
- event_type->callback(evt.userdata, global_timer - evt.time);
- }
+ if (auto event_type{evt.type.lock()}) {
+ event_type->callback(evt.userdata, global_timer - evt.time);
+ }
- basic_lock.lock();
- }
+ basic_lock.lock();
+ }
- if (!event_queue.empty()) {
- std::chrono::nanoseconds next_time =
- std::chrono::nanoseconds(event_queue.front().time - global_timer);
- basic_lock.unlock();
- event.WaitFor(next_time);
+ if (!event_queue.empty()) {
+ const u64 next_time = event_queue.front().time - global_timer;
+ basic_lock.unlock();
+ advance_lock.unlock();
+ return next_time;
+ } else {
+ basic_lock.unlock();
+ advance_lock.unlock();
+ return std::nullopt;
+ }
+}
+
+void CoreTiming::ThreadLoop() {
+ has_started = true;
+ while (!shutting_down) {
+ while (!paused) {
+ paused_set = false;
+ const auto next_time = Advance();
+ if (next_time) {
+ std::chrono::nanoseconds next_time_ns = std::chrono::nanoseconds(*next_time);
+ event.WaitFor(next_time_ns);
} else {
- basic_lock.unlock();
wait_set = true;
event.Wait();
}
-
wait_set = false;
}
paused_set = true;
diff --git a/src/core/host_timing.h b/src/core/host_timing.h
index 679fcf491..cd44b308c 100644
--- a/src/core/host_timing.h
+++ b/src/core/host_timing.h
@@ -103,6 +103,9 @@ public:
/// Returns current time in nanoseconds.
std::chrono::nanoseconds GetGlobalTimeNs() const;
+ /// Checks for events manually and returns time in nanoseconds for next event, threadsafe.
+ std::optional<u64> Advance();
+
private:
struct Event;
@@ -110,7 +113,7 @@ private:
void ClearPendingEvents();
static void ThreadEntry(CoreTiming& instance);
- void Advance();
+ void ThreadLoop();
std::unique_ptr<Common::WallClock> clock;
@@ -128,6 +131,7 @@ private:
std::shared_ptr<EventType> ev_lost;
Common::Event event{};
Common::SpinLock basic_lock{};
+ Common::SpinLock advance_lock{};
std::unique_ptr<std::thread> timer_thread;
std::atomic<bool> paused{};
std::atomic<bool> paused_set{};