summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-02-27 10:47:02 -0400
committerGravatar Fernando Sahmkow2020-06-27 11:35:18 -0400
commitcc3aa959265480e1990b10ee37ebf1c0ade3da64 (patch)
tree0188b3adeab5cb83362f296e6894d70b53cb86e0 /src
parentSVC: Add locks to the memory management. (diff)
downloadyuzu-cc3aa959265480e1990b10ee37ebf1c0ade3da64.tar.gz
yuzu-cc3aa959265480e1990b10ee37ebf1c0ade3da64.tar.xz
yuzu-cc3aa959265480e1990b10ee37ebf1c0ade3da64.zip
NVFlinger: Lock race condition between CPU, Host Timing, VSync.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp2
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h7
-rw-r--r--src/core/hle/service/vi/vi.cpp2
3 files changed, 11 insertions, 0 deletions
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index aaf28995d..b97f71350 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -36,10 +36,12 @@ NVFlinger::NVFlinger(Core::System& system) : system(system) {
36 displays.emplace_back(2, "Edid", system); 36 displays.emplace_back(2, "Edid", system);
37 displays.emplace_back(3, "Internal", system); 37 displays.emplace_back(3, "Internal", system);
38 displays.emplace_back(4, "Null", system); 38 displays.emplace_back(4, "Null", system);
39 guard = std::make_shared<std::mutex>();
39 40
40 // Schedule the screen composition events 41 // Schedule the screen composition events
41 composition_event = 42 composition_event =
42 Core::Timing::CreateEvent("ScreenComposition", [this](u64 userdata, s64 ns_late) { 43 Core::Timing::CreateEvent("ScreenComposition", [this](u64 userdata, s64 ns_late) {
44 Lock();
43 Compose(); 45 Compose();
44 const auto ticks = GetNextTicks(); 46 const auto ticks = GetNextTicks();
45 this->system.CoreTiming().ScheduleEvent(std::max<s64>(0LL, ticks - ns_late), 47 this->system.CoreTiming().ScheduleEvent(std::max<s64>(0LL, ticks - ns_late),
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 57a21f33b..02c081494 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <mutex>
8#include <optional> 9#include <optional>
9#include <string> 10#include <string>
10#include <string_view> 11#include <string_view>
@@ -79,6 +80,10 @@ public:
79 80
80 s64 GetNextTicks() const; 81 s64 GetNextTicks() const;
81 82
83 std::unique_lock<std::mutex> Lock() {
84 return std::unique_lock{*guard};
85 }
86
82private: 87private:
83 /// Finds the display identified by the specified ID. 88 /// Finds the display identified by the specified ID.
84 VI::Display* FindDisplay(u64 display_id); 89 VI::Display* FindDisplay(u64 display_id);
@@ -108,6 +113,8 @@ private:
108 /// Event that handles screen composition. 113 /// Event that handles screen composition.
109 std::shared_ptr<Core::Timing::EventType> composition_event; 114 std::shared_ptr<Core::Timing::EventType> composition_event;
110 115
116 std::shared_ptr<std::mutex> guard;
117
111 Core::System& system; 118 Core::System& system;
112}; 119};
113 120
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 46e14c2a3..157092074 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -511,6 +511,7 @@ private:
511 LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id, 511 LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id,
512 static_cast<u32>(transaction), flags); 512 static_cast<u32>(transaction), flags);
513 513
514 nv_flinger->Lock();
514 auto& buffer_queue = nv_flinger->FindBufferQueue(id); 515 auto& buffer_queue = nv_flinger->FindBufferQueue(id);
515 516
516 switch (transaction) { 517 switch (transaction) {
@@ -550,6 +551,7 @@ private:
550 [=](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, 551 [=](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
551 Kernel::ThreadWakeupReason reason) { 552 Kernel::ThreadWakeupReason reason) {
552 // Repeat TransactParcel DequeueBuffer when a buffer is available 553 // Repeat TransactParcel DequeueBuffer when a buffer is available
554 nv_flinger->Lock();
553 auto& buffer_queue = nv_flinger->FindBufferQueue(id); 555 auto& buffer_queue = nv_flinger->FindBufferQueue(id);
554 auto result = buffer_queue.DequeueBuffer(width, height); 556 auto result = buffer_queue.DequeueBuffer(width, height);
555 ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer."); 557 ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer.");