Skip to content

Commit d2dd169

Browse files
author
merge-script
committed
Merge bitcoin/bitcoin#22904: sync, log: inline lock contention logging macro to fix duration, improve BCLog::LogMsg()
f530202 Make unexpected time type in BCLog::LogMsg() a compile-time error (Martin Ankerl) bddae7e Add util/types.h with ALWAYS_FALSE template (MarcoFalke) 498b323 log, timer: improve BCLog::LogMsg() (Jon Atack) 8d2f847 sync: inline lock contention logging macro to fix time duration (Jon Atack) Pull request description: Follow-up to #22736. The first commit addresses the issue identified and reported by Martin Ankerl in bitcoin/bitcoin#22736 (comment) to fix the lock contention duration reporting. The next three commits make improvements to the timer code in `BCLog::LogMsg()` and add `util/types.h` with an `ALWAYS_FALSE` template, that springboard from bitcoin/bitcoin#22736 (comment) by Marco Falke. ACKs for top commit: martinus: re-ACK f530202. I ran a fully synced node for about a day. My node was mostly idle though so not much was going on. I [wrote a little script](https://github.com/martinus/bitcoin-stuff/blob/main/scripts/parse-debuglog-contention-single.rb) to parse the `debug.log` and summarize the output to see if anything interesting was going on, here is the result: theStack: ACK f530202 Tree-SHA512: 37d093eac5590e1b5846ab5994d0950d71e131177d1afe4a5f7fcd614270f977e0ea117e7af788e9a74ddcccab35b42ec8fa4db3a3378940d4988df7d21cdaaa
2 parents 1d0c57a + f530202 commit d2dd169

File tree

6 files changed

+27
-30
lines changed

6 files changed

+27
-30
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ BITCOIN_CORE_H = \
268268
util/tokenpipe.h \
269269
util/trace.h \
270270
util/translation.h \
271+
util/types.h \
271272
util/ui_change_type.h \
272273
util/url.h \
273274
util/vector.h \

src/logging/timer.h

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <logging.h>
1010
#include <util/macros.h>
1111
#include <util/time.h>
12+
#include <util/types.h>
1213

1314
#include <chrono>
1415
#include <string>
@@ -58,23 +59,15 @@ class Timer
5859
return strprintf("%s: %s", m_prefix, msg);
5960
}
6061

61-
if (std::is_same<TimeType, std::chrono::microseconds>::value) {
62+
if constexpr (std::is_same<TimeType, std::chrono::microseconds>::value) {
6263
return strprintf("%s: %s (%iμs)", m_prefix, msg, end_time.count());
64+
} else if constexpr (std::is_same<TimeType, std::chrono::milliseconds>::value) {
65+
return strprintf("%s: %s (%.2fms)", m_prefix, msg, end_time.count() * 0.001);
66+
} else if constexpr (std::is_same<TimeType, std::chrono::seconds>::value) {
67+
return strprintf("%s: %s (%.2fs)", m_prefix, msg, end_time.count() * 0.000001);
68+
} else {
69+
static_assert(ALWAYS_FALSE<TimeType>, "Error: unexpected time type");
6370
}
64-
65-
std::string units;
66-
float divisor = 1;
67-
68-
if (std::is_same<TimeType, std::chrono::milliseconds>::value) {
69-
units = "ms";
70-
divisor = 1000.;
71-
} else if (std::is_same<TimeType, std::chrono::seconds>::value) {
72-
units = "s";
73-
divisor = 1000. * 1000.;
74-
}
75-
76-
const float time_ms = end_time.count() / divisor;
77-
return strprintf("%s: %s (%.2f%s)", m_prefix, msg, time_ms, units);
7871
}
7972

8073
private:
@@ -89,7 +82,6 @@ class Timer
8982
//! Forwarded on to LogPrint if specified - has the effect of only
9083
//! outputting the timing log when a particular debug= category is specified.
9184
const BCLog::LogFlags m_log_category{};
92-
9385
};
9486

9587
} // namespace BCLog

src/sync.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <sync.h>
1010

1111
#include <logging.h>
12-
#include <logging/timer.h>
1312
#include <tinyformat.h>
1413
#include <util/strencodings.h>
1514
#include <util/threadnames.h>
@@ -24,11 +23,6 @@
2423
#include <utility>
2524
#include <vector>
2625

27-
void LockContention(const char* pszName, const char* pszFile, int nLine)
28-
{
29-
LOG_TIME_MICROS_WITH_CATEGORY(strprintf("%s, %s:%d", pszName, pszFile, nLine), BCLog::LOCK);
30-
}
31-
3226
#ifdef DEBUG_LOCKORDER
3327
//
3428
// Early deadlock detection.

src/sync.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#ifndef BITCOIN_SYNC_H
77
#define BITCOIN_SYNC_H
88

9+
#include <logging.h>
10+
#include <logging/timer.h>
911
#include <threadsafety.h>
1012
#include <util/macros.h>
1113

@@ -126,9 +128,6 @@ using RecursiveMutex = AnnotatedMixin<std::recursive_mutex>;
126128
/** Wrapped mutex: supports waiting but not recursive locking */
127129
typedef AnnotatedMixin<std::mutex> Mutex;
128130

129-
/** Prints a lock contention to the log */
130-
void LockContention(const char* pszName, const char* pszFile, int nLine);
131-
132131
/** Wrapper around std::unique_lock style lock for Mutex. */
133132
template <typename Mutex, typename Base = typename Mutex::UniqueLock>
134133
class SCOPED_LOCKABLE UniqueLock : public Base
@@ -138,7 +137,7 @@ class SCOPED_LOCKABLE UniqueLock : public Base
138137
{
139138
EnterCritical(pszName, pszFile, nLine, Base::mutex());
140139
if (Base::try_lock()) return;
141-
LockContention(pszName, pszFile, nLine); // log the contention
140+
LOG_TIME_MICROS_WITH_CATEGORY(strprintf("lock contention %s, %s:%d", pszName, pszFile, nLine), BCLog::LOCK);
142141
Base::lock();
143142
}
144143

src/test/logging_tests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ BOOST_FIXTURE_TEST_SUITE(logging_tests, BasicTestingSetup)
1515
BOOST_AUTO_TEST_CASE(logging_timer)
1616
{
1717
SetMockTime(1);
18-
auto sec_timer = BCLog::Timer<std::chrono::seconds>("tests", "end_msg");
18+
auto micro_timer = BCLog::Timer<std::chrono::microseconds>("tests", "end_msg");
1919
SetMockTime(2);
20-
BOOST_CHECK_EQUAL(sec_timer.LogMsg("test secs"), "tests: test secs (1.00s)");
20+
BOOST_CHECK_EQUAL(micro_timer.LogMsg("test micros"), "tests: test micros (1000000μs)");
2121

2222
SetMockTime(1);
2323
auto ms_timer = BCLog::Timer<std::chrono::milliseconds>("tests", "end_msg");
2424
SetMockTime(2);
2525
BOOST_CHECK_EQUAL(ms_timer.LogMsg("test ms"), "tests: test ms (1000.00ms)");
2626

2727
SetMockTime(1);
28-
auto micro_timer = BCLog::Timer<std::chrono::microseconds>("tests", "end_msg");
28+
auto sec_timer = BCLog::Timer<std::chrono::seconds>("tests", "end_msg");
2929
SetMockTime(2);
30-
BOOST_CHECK_EQUAL(micro_timer.LogMsg("test micros"), "tests: test micros (1000000μs)");
30+
BOOST_CHECK_EQUAL(sec_timer.LogMsg("test secs"), "tests: test secs (1.00s)");
3131
}
3232

3333
BOOST_AUTO_TEST_SUITE_END()

src/util/types.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) 2021 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_UTIL_TYPES_H
6+
#define BITCOIN_UTIL_TYPES_H
7+
8+
template <class>
9+
inline constexpr bool ALWAYS_FALSE{false};
10+
11+
#endif // BITCOIN_UTIL_TYPES_H

0 commit comments

Comments
 (0)