diff options
Diffstat (limited to 'src/common/logging')
| -rw-r--r-- | src/common/logging/backend.cpp | 70 | ||||
| -rw-r--r-- | src/common/logging/backend.h | 5 | ||||
| -rw-r--r-- | src/common/logging/log.h | 1 |
3 files changed, 35 insertions, 41 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 12f6d0114..4462ff3fb 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp | |||
| @@ -39,10 +39,10 @@ public: | |||
| 39 | Impl(Impl const&) = delete; | 39 | Impl(Impl const&) = delete; |
| 40 | const Impl& operator=(Impl const&) = delete; | 40 | const Impl& operator=(Impl const&) = delete; |
| 41 | 41 | ||
| 42 | void PushEntry(Entry e) { | 42 | void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, |
| 43 | std::lock_guard<std::mutex> lock(message_mutex); | 43 | const char* function, std::string message) { |
| 44 | message_queue.Push(std::move(e)); | 44 | message_queue.Push( |
| 45 | message_cv.notify_one(); | 45 | CreateEntry(log_class, log_level, filename, line_num, function, std::move(message))); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | void AddBackend(std::unique_ptr<Backend> backend) { | 48 | void AddBackend(std::unique_ptr<Backend> backend) { |
| @@ -86,15 +86,13 @@ private: | |||
| 86 | } | 86 | } |
| 87 | }; | 87 | }; |
| 88 | while (true) { | 88 | while (true) { |
| 89 | { | 89 | entry = message_queue.PopWait(); |
| 90 | std::unique_lock<std::mutex> lock(message_mutex); | 90 | if (entry.final_entry) { |
| 91 | message_cv.wait(lock, [&] { return !running || message_queue.Pop(entry); }); | ||
| 92 | } | ||
| 93 | if (!running) { | ||
| 94 | break; | 91 | break; |
| 95 | } | 92 | } |
| 96 | write_logs(entry); | 93 | write_logs(entry); |
| 97 | } | 94 | } |
| 95 | |||
| 98 | // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case | 96 | // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case |
| 99 | // where a system is repeatedly spamming logs even on close. | 97 | // where a system is repeatedly spamming logs even on close. |
| 100 | const int MAX_LOGS_TO_WRITE = filter.IsDebug() ? INT_MAX : 100; | 98 | const int MAX_LOGS_TO_WRITE = filter.IsDebug() ? INT_MAX : 100; |
| @@ -106,18 +104,36 @@ private: | |||
| 106 | } | 104 | } |
| 107 | 105 | ||
| 108 | ~Impl() { | 106 | ~Impl() { |
| 109 | running = false; | 107 | Entry entry; |
| 110 | message_cv.notify_one(); | 108 | entry.final_entry = true; |
| 109 | message_queue.Push(entry); | ||
| 111 | backend_thread.join(); | 110 | backend_thread.join(); |
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | std::atomic_bool running{true}; | 113 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, |
| 115 | std::mutex message_mutex, writing_mutex; | 114 | const char* function, std::string message) const { |
| 116 | std::condition_variable message_cv; | 115 | using std::chrono::duration_cast; |
| 116 | using std::chrono::steady_clock; | ||
| 117 | |||
| 118 | Entry entry; | ||
| 119 | entry.timestamp = | ||
| 120 | duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin); | ||
| 121 | entry.log_class = log_class; | ||
| 122 | entry.log_level = log_level; | ||
| 123 | entry.filename = Common::TrimSourcePath(filename); | ||
| 124 | entry.line_num = line_nr; | ||
| 125 | entry.function = function; | ||
| 126 | entry.message = std::move(message); | ||
| 127 | |||
| 128 | return entry; | ||
| 129 | } | ||
| 130 | |||
| 131 | std::mutex writing_mutex; | ||
| 117 | std::thread backend_thread; | 132 | std::thread backend_thread; |
| 118 | std::vector<std::unique_ptr<Backend>> backends; | 133 | std::vector<std::unique_ptr<Backend>> backends; |
| 119 | Common::MPSCQueue<Log::Entry> message_queue; | 134 | Common::MPSCQueue<Log::Entry> message_queue; |
| 120 | Filter filter; | 135 | Filter filter; |
| 136 | std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; | ||
| 121 | }; | 137 | }; |
| 122 | 138 | ||
| 123 | void ConsoleBackend::Write(const Entry& entry) { | 139 | void ConsoleBackend::Write(const Entry& entry) { |
| @@ -232,6 +248,7 @@ void DebuggerBackend::Write(const Entry& entry) { | |||
| 232 | CLS(Render) \ | 248 | CLS(Render) \ |
| 233 | SUB(Render, Software) \ | 249 | SUB(Render, Software) \ |
| 234 | SUB(Render, OpenGL) \ | 250 | SUB(Render, OpenGL) \ |
| 251 | SUB(Render, Vulkan) \ | ||
| 235 | CLS(Audio) \ | 252 | CLS(Audio) \ |
| 236 | SUB(Audio, DSP) \ | 253 | SUB(Audio, DSP) \ |
| 237 | SUB(Audio, Sink) \ | 254 | SUB(Audio, Sink) \ |
| @@ -275,25 +292,6 @@ const char* GetLevelName(Level log_level) { | |||
| 275 | #undef LVL | 292 | #undef LVL |
| 276 | } | 293 | } |
| 277 | 294 | ||
| 278 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, | ||
| 279 | const char* function, std::string message) { | ||
| 280 | using std::chrono::duration_cast; | ||
| 281 | using std::chrono::steady_clock; | ||
| 282 | |||
| 283 | static steady_clock::time_point time_origin = steady_clock::now(); | ||
| 284 | |||
| 285 | Entry entry; | ||
| 286 | entry.timestamp = duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin); | ||
| 287 | entry.log_class = log_class; | ||
| 288 | entry.log_level = log_level; | ||
| 289 | entry.filename = Common::TrimSourcePath(filename); | ||
| 290 | entry.line_num = line_nr; | ||
| 291 | entry.function = function; | ||
| 292 | entry.message = std::move(message); | ||
| 293 | |||
| 294 | return entry; | ||
| 295 | } | ||
| 296 | |||
| 297 | void SetGlobalFilter(const Filter& filter) { | 295 | void SetGlobalFilter(const Filter& filter) { |
| 298 | Impl::Instance().SetGlobalFilter(filter); | 296 | Impl::Instance().SetGlobalFilter(filter); |
| 299 | } | 297 | } |
| @@ -318,9 +316,7 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, | |||
| 318 | if (!filter.CheckMessage(log_class, log_level)) | 316 | if (!filter.CheckMessage(log_class, log_level)) |
| 319 | return; | 317 | return; |
| 320 | 318 | ||
| 321 | Entry entry = | 319 | instance.PushEntry(log_class, log_level, filename, line_num, function, |
| 322 | CreateEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args)); | 320 | fmt::vformat(format, args)); |
| 323 | |||
| 324 | instance.PushEntry(std::move(entry)); | ||
| 325 | } | 321 | } |
| 326 | } // namespace Log | 322 | } // namespace Log |
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h index 91bb0c309..fca0267a1 100644 --- a/src/common/logging/backend.h +++ b/src/common/logging/backend.h | |||
| @@ -27,6 +27,7 @@ struct Entry { | |||
| 27 | unsigned int line_num; | 27 | unsigned int line_num; |
| 28 | std::string function; | 28 | std::string function; |
| 29 | std::string message; | 29 | std::string message; |
| 30 | bool final_entry = false; | ||
| 30 | 31 | ||
| 31 | Entry() = default; | 32 | Entry() = default; |
| 32 | Entry(Entry&& o) = default; | 33 | Entry(Entry&& o) = default; |
| @@ -134,10 +135,6 @@ const char* GetLogClassName(Class log_class); | |||
| 134 | */ | 135 | */ |
| 135 | const char* GetLevelName(Level log_level); | 136 | const char* GetLevelName(Level log_level); |
| 136 | 137 | ||
| 137 | /// Creates a log entry by formatting the given source location, and message. | ||
| 138 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, | ||
| 139 | const char* function, std::string message); | ||
| 140 | |||
| 141 | /** | 138 | /** |
| 142 | * The global filter will prevent any messages from even being processed if they are filtered. Each | 139 | * The global filter will prevent any messages from even being processed if they are filtered. Each |
| 143 | * backend can have a filter, but if the level is lower than the global filter, the backend will | 140 | * backend can have a filter, but if the level is lower than the global filter, the backend will |
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 { | |||
| 112 | Render, ///< Emulator video output and hardware acceleration | 112 | Render, ///< Emulator video output and hardware acceleration |
| 113 | Render_Software, ///< Software renderer backend | 113 | Render_Software, ///< Software renderer backend |
| 114 | Render_OpenGL, ///< OpenGL backend | 114 | Render_OpenGL, ///< OpenGL backend |
| 115 | Render_Vulkan, ///< Vulkan backend | ||
| 115 | Audio, ///< Audio emulation | 116 | Audio, ///< Audio emulation |
| 116 | Audio_DSP, ///< The HLE implementation of the DSP | 117 | Audio_DSP, ///< The HLE implementation of the DSP |
| 117 | Audio_Sink, ///< Emulator audio output backend | 118 | Audio_Sink, ///< Emulator audio output backend |