summaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/logging/backend.cpp20
-rw-r--r--src/common/logging/backend.h1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/common/swap.h6
-rw-r--r--src/common/threadsafe_queue.h53
5 files changed, 47 insertions, 34 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 12f6d0114..b369f199f 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -40,9 +40,7 @@ public:
const Impl& operator=(Impl const&) = delete;
void PushEntry(Entry e) {
- std::lock_guard<std::mutex> lock(message_mutex);
message_queue.Push(std::move(e));
- message_cv.notify_one();
}
void AddBackend(std::unique_ptr<Backend> backend) {
@@ -86,15 +84,13 @@ private:
}
};
while (true) {
- {
- std::unique_lock<std::mutex> lock(message_mutex);
- message_cv.wait(lock, [&] { return !running || message_queue.Pop(entry); });
- }
- if (!running) {
+ entry = message_queue.PopWait();
+ if (entry.final_entry) {
break;
}
write_logs(entry);
}
+
// Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case
// where a system is repeatedly spamming logs even on close.
const int MAX_LOGS_TO_WRITE = filter.IsDebug() ? INT_MAX : 100;
@@ -106,14 +102,13 @@ private:
}
~Impl() {
- running = false;
- message_cv.notify_one();
+ Entry entry;
+ entry.final_entry = true;
+ message_queue.Push(entry);
backend_thread.join();
}
- std::atomic_bool running{true};
- std::mutex message_mutex, writing_mutex;
- std::condition_variable message_cv;
+ std::mutex writing_mutex;
std::thread backend_thread;
std::vector<std::unique_ptr<Backend>> backends;
Common::MPSCQueue<Log::Entry> message_queue;
@@ -232,6 +227,7 @@ void DebuggerBackend::Write(const Entry& entry) {
CLS(Render) \
SUB(Render, Software) \
SUB(Render, OpenGL) \
+ SUB(Render, Vulkan) \
CLS(Audio) \
SUB(Audio, DSP) \
SUB(Audio, Sink) \
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h
index 91bb0c309..a31ee6968 100644
--- a/src/common/logging/backend.h
+++ b/src/common/logging/backend.h
@@ -27,6 +27,7 @@ struct Entry {
unsigned int line_num;
std::string function;
std::string message;
+ bool final_entry = false;
Entry() = default;
Entry(Entry&& o) = default;
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index d4ec31ec3..8ed6d5050 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -112,6 +112,7 @@ enum class Class : ClassType {
Render, ///< Emulator video output and hardware acceleration
Render_Software, ///< Software renderer backend
Render_OpenGL, ///< OpenGL backend
+ Render_Vulkan, ///< Vulkan backend
Audio, ///< Audio emulation
Audio_DSP, ///< The HLE implementation of the DSP
Audio_Sink, ///< Emulator audio output backend
diff --git a/src/common/swap.h b/src/common/swap.h
index 32af0b6ac..0e219747f 100644
--- a/src/common/swap.h
+++ b/src/common/swap.h
@@ -28,8 +28,8 @@
#include <cstring>
#include "common/common_types.h"
-// GCC 4.6+
-#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+// GCC
+#ifdef __GNUC__
#if __BYTE_ORDER__ && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) && !defined(COMMON_LITTLE_ENDIAN)
#define COMMON_LITTLE_ENDIAN 1
@@ -38,7 +38,7 @@
#endif
// LLVM/clang
-#elif __clang__
+#elif defined(__clang__)
#if __LITTLE_ENDIAN__ && !defined(COMMON_LITTLE_ENDIAN)
#define COMMON_LITTLE_ENDIAN 1
diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h
index edf13bc49..821e8536a 100644
--- a/src/common/threadsafe_queue.h
+++ b/src/common/threadsafe_queue.h
@@ -7,17 +7,17 @@
// a simple lockless thread-safe,
// single reader, single writer queue
-#include <algorithm>
#include <atomic>
+#include <condition_variable>
#include <cstddef>
#include <mutex>
-#include "common/common_types.h"
+#include <utility>
namespace Common {
-template <typename T, bool NeedSize = true>
+template <typename T>
class SPSCQueue {
public:
- SPSCQueue() : size(0) {
+ SPSCQueue() {
write_ptr = read_ptr = new ElementPtr();
}
~SPSCQueue() {
@@ -25,13 +25,12 @@ public:
delete read_ptr;
}
- u32 Size() const {
- static_assert(NeedSize, "using Size() on FifoQueue without NeedSize");
+ std::size_t Size() const {
return size.load();
}
bool Empty() const {
- return !read_ptr->next.load();
+ return Size() == 0;
}
T& Front() const {
@@ -47,13 +46,14 @@ public:
ElementPtr* new_ptr = new ElementPtr();
write_ptr->next.store(new_ptr, std::memory_order_release);
write_ptr = new_ptr;
- if (NeedSize)
- size++;
+ cv.notify_one();
+
+ ++size;
}
void Pop() {
- if (NeedSize)
- size--;
+ --size;
+
ElementPtr* tmpptr = read_ptr;
// advance the read pointer
read_ptr = tmpptr->next.load();
@@ -66,8 +66,7 @@ public:
if (Empty())
return false;
- if (NeedSize)
- size--;
+ --size;
ElementPtr* tmpptr = read_ptr;
read_ptr = tmpptr->next.load(std::memory_order_acquire);
@@ -77,6 +76,16 @@ public:
return true;
}
+ T PopWait() {
+ if (Empty()) {
+ std::unique_lock<std::mutex> lock(cv_mutex);
+ cv.wait(lock, [this]() { return !Empty(); });
+ }
+ T t;
+ Pop(t);
+ return t;
+ }
+
// not thread-safe
void Clear() {
size.store(0);
@@ -89,7 +98,7 @@ private:
// and a pointer to the next ElementPtr
class ElementPtr {
public:
- ElementPtr() : next(nullptr) {}
+ ElementPtr() {}
~ElementPtr() {
ElementPtr* next_ptr = next.load();
@@ -98,21 +107,23 @@ private:
}
T current;
- std::atomic<ElementPtr*> next;
+ std::atomic<ElementPtr*> next{nullptr};
};
ElementPtr* write_ptr;
ElementPtr* read_ptr;
- std::atomic<u32> size;
+ std::atomic_size_t size{0};
+ std::mutex cv_mutex;
+ std::condition_variable cv;
};
// a simple thread-safe,
// single reader, multiple writer queue
-template <typename T, bool NeedSize = true>
+template <typename T>
class MPSCQueue {
public:
- u32 Size() const {
+ std::size_t Size() const {
return spsc_queue.Size();
}
@@ -138,13 +149,17 @@ public:
return spsc_queue.Pop(t);
}
+ T PopWait() {
+ return spsc_queue.PopWait();
+ }
+
// not thread-safe
void Clear() {
spsc_queue.Clear();
}
private:
- SPSCQueue<T, NeedSize> spsc_queue;
+ SPSCQueue<T> spsc_queue;
std::mutex write_lock;
};
} // namespace Common