Skip to content

Commit 7ab904a

Browse files
committed
Application of TheBlueMatt's original async logging patch
bitcoinfibre@6b6a3ae
1 parent c5870ab commit 7ab904a

File tree

3 files changed

+75
-2
lines changed

3 files changed

+75
-2
lines changed

src/init.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ void Shutdown()
290290
g_wallet_init_interface.Close();
291291
globalVerifyHandle.reset();
292292
ECC_Stop();
293+
StopDebugLogFlushThread();
293294
LogPrintf("%s: done\n", __func__);
294295
}
295296

src/logging.cpp

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
#include <logging.h>
77
#include <utiltime.h>
8+
#include <mutex>
9+
#include <condition_variable>
10+
#include <thread>
811

912
const char * const DEFAULT_DEBUGLOGFILE = "debug.log";
1013

@@ -25,9 +28,75 @@ BCLog::Logger* const g_logger = new BCLog::Logger();
2528

2629
bool fLogIPs = DEFAULT_LOGIPS;
2730

31+
#define LOG_LINE_BUFFER_SIZE 128
32+
static std::atomic_int g_next_pending_log_line(0);
33+
static std::atomic_int g_next_undef_log_line(0);
34+
static std::atomic_bool g_debug_log_flush_thread_exit;
35+
static std::mutex g_log_buff_mutex;
36+
static std::condition_variable g_log_buff_cv;
37+
static std::array<std::string, LOG_LINE_BUFFER_SIZE> g_debug_log_buff;
38+
static std::unique_ptr<std::thread> g_buff_flush_thread; // non-ptr fails to build in LTO?
39+
static std::once_flag g_buff_flush_thread_started;
40+
41+
static void DebugLogFlush()
42+
{
43+
while (true) {
44+
int next_pending_log = g_next_pending_log_line.load(std::memory_order_acquire);
45+
int next_undef_log = g_next_undef_log_line.load(std::memory_order_acquire);
46+
if (next_pending_log == next_undef_log) {
47+
if (g_debug_log_flush_thread_exit) return;
48+
std::unique_lock<std::mutex> lock(g_log_buff_mutex);
49+
while (next_pending_log == next_undef_log && !g_debug_log_flush_thread_exit) {
50+
g_log_buff_cv.wait(lock);
51+
next_pending_log = g_next_pending_log_line.load(std::memory_order_acquire);
52+
next_undef_log = g_next_undef_log_line.load(std::memory_order_acquire);
53+
}
54+
}
55+
56+
while (next_pending_log != next_undef_log) {
57+
fwrite(g_debug_log_buff[next_pending_log].data(), 1, g_debug_log_buff[next_pending_log].size(), g_logger->m_fileout);
58+
g_debug_log_buff[next_pending_log].clear();
59+
g_debug_log_buff[next_pending_log].shrink_to_fit();
60+
next_pending_log = (next_pending_log + 1) % LOG_LINE_BUFFER_SIZE;
61+
g_next_pending_log_line.store(next_pending_log, std::memory_order_release);
62+
g_log_buff_cv.notify_one();
63+
}
64+
}
65+
}
66+
67+
void StopDebugLogFlushThread() {
68+
g_debug_log_flush_thread_exit = true;
69+
{
70+
std::unique_lock<std::mutex> lock(g_log_buff_mutex);
71+
g_log_buff_cv.notify_all();
72+
}
73+
if (g_buff_flush_thread) {
74+
g_buff_flush_thread->join();
75+
}
76+
}
77+
2878
static int FileWriteStr(const std::string &str, FILE *fp)
2979
{
30-
return fwrite(str.data(), 1, str.size(), fp);
80+
std::call_once(g_buff_flush_thread_started, [] {
81+
g_buff_flush_thread.reset(new std::thread(DebugLogFlush));
82+
});
83+
84+
std::unique_lock<std::mutex> lock(g_log_buff_mutex);
85+
int next_pending_log = g_next_pending_log_line.load(std::memory_order_acquire);
86+
int next_undef_log = g_next_undef_log_line.load(std::memory_order_acquire);
87+
while (next_pending_log == (next_undef_log + 1) % LOG_LINE_BUFFER_SIZE && !g_debug_log_flush_thread_exit) {
88+
g_log_buff_cv.wait(lock);
89+
next_pending_log = g_next_pending_log_line.load(std::memory_order_acquire);
90+
next_undef_log = g_next_undef_log_line.load(std::memory_order_acquire);
91+
}
92+
if (g_debug_log_flush_thread_exit) {
93+
return fwrite(str.data(), 1, str.size(), fp);
94+
} else {
95+
g_debug_log_buff[next_undef_log] = str;
96+
g_next_undef_log_line.store((next_undef_log + 1) % LOG_LINE_BUFFER_SIZE, std::memory_order_release);
97+
g_log_buff_cv.notify_all();
98+
return str.size();
99+
}
31100
}
32101

33102
bool BCLog::Logger::OpenDebugLog()
@@ -198,6 +267,7 @@ std::string BCLog::Logger::LogTimestampStr(const std::string &str)
198267
return strStamped;
199268
}
200269

270+
201271
void BCLog::Logger::LogPrintStr(const std::string &str)
202272
{
203273
std::string strTimestamped = LogTimestampStr(str);

src/logging.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ namespace BCLog {
5959
class Logger
6060
{
6161
private:
62-
FILE* m_fileout = nullptr;
6362
std::mutex m_file_mutex;
6463
std::list<std::string> m_msgs_before_open;
6564

@@ -76,6 +75,7 @@ namespace BCLog {
7675
std::string LogTimestampStr(const std::string& str);
7776

7877
public:
78+
FILE* m_fileout = nullptr;
7979
bool m_print_to_console = false;
8080
bool m_print_to_file = false;
8181

@@ -163,4 +163,6 @@ template<typename T, typename... Args> static inline void MarkUsed(const T& t, c
163163
} while(0)
164164
#endif
165165

166+
void StopDebugLogFlushThread();
167+
166168
#endif // BITCOIN_LOGGING_H

0 commit comments

Comments
 (0)