Skip to content

threading: never require logging from sync.h#34793

Closed
theuni wants to merge 1 commit intobitcoin:masterfrom
theuni:thread-no-logging
Closed

threading: never require logging from sync.h#34793
theuni wants to merge 1 commit intobitcoin:masterfrom
theuni:thread-no-logging

Conversation

@theuni
Copy link
Member

@theuni theuni commented Mar 10, 2026

sync.h is low-level and should not require any other subsystems.

Move the lone remaining logging call to the .cpp. Any cost incurred by an additional function call should be trivial compared to the logging itself.

sync.h is low-level and should not require any other subsystems.

Move the lone remaining logging call to the .cpp. Any cost incurred by an
additional function call should be trivial compared to the logging itself.
@DrahtBot
Copy link
Contributor

DrahtBot commented Mar 10, 2026

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK hebasto
Concept ACK stickies-v

If your review is incorrectly listed, please copy-paste <!--meta-tag:bot-skip--> into the comment that the bot should ignore.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #34639 (iwyu: Document or remove some pragma: export and other improvements by hebasto)
  • #34448 (ci, iwyu: Fix warnings in src/util and treat them as errors by hebasto)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK.

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 975f14d, I have reviewed the code and it looks OK.


#include <sync.h>

#include <logging/timer.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Strictly speaking, this header should be guarded with #ifdef DEBUG_LOCKCONTENTION as is done in the master branch. Similarly, other includes should be guarded with #ifdef DEBUG_LOCKORDER.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I had a second commit which split the includes and functions into 3 chunks: contention, order, both. I decided to leave it out for the sake of simplicity: anyone who needs this .cpp will have all of those headers available.

I can push that commit if you'd like, but I don't think it's worth the complexity. At least for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can push that commit if you'd like, but I don't think it's worth the complexity. At least for now.

No need. This can be done once IWYU begins force warnings for sync.cpp.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's another option, btw, which is to leave out all of the ifdefs in the .cpp. Because the functions are only used if the inlines in the .h aren't, it doesn't hurt to just always have the full functionality in the .cpp.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would look like:

diff --git a/src/sync.cpp b/src/sync.cpp
index 812aa3d480e..0c6b9067fe1 100644
--- a/src/sync.cpp
+++ b/src/sync.cpp
@@ -2,6 +2,14 @@
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.

+#ifndef DEBUG_LOCKCONTENTION
+#define DEBUG_LOCKCONTENTION
+#endif
+
+#ifndef DEBUG_LOCKORDER
+#define DEBUG_LOCKORDER
+#endif
+
 #include <sync.h>

 #include <logging/timer.h>
@@ -20,14 +28,11 @@
 #include <utility>
 #include <vector>

-#ifdef DEBUG_LOCKCONTENTION
 void LogContention(const char* pszName, const char* pszFile, int nLine)
 {
     LOG_TIME_MICROS_WITH_CATEGORY(strprintf("lock contention %s, %s:%d", pszName, pszFile, nLine), BCLog::LOCK);
 }
-#endif

-#ifdef DEBUG_LOCKORDER
 //
 // Early deadlock detection.
 // Problem being solved:
@@ -325,4 +330,3 @@ bool LockStackEmpty()

 bool g_debug_lockorder_abort = true;

-#endif /* DEBUG_LOCKORDER */

Though, if we were going that route, rather than playing define tricks, I'd prefer to instead create internal/external versions of each function instead. Like:

inline void LogContentionInt(const char* pszName, const char* pszFile, int nLine)
{
#ifdef DEBUG_LOCKCONTENTION
    LogContention(pszName, pszFile, nLine);
#endif
}

Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK. I think it's a smell that/when util is using logging, and have been doing similar work/investigation to reduce it.

As per my comment, I don't think the current approach works though.

#ifdef DEBUG_LOCKCONTENTION
void LogContention(const char* pszName, const char* pszFile, int nLine)
{
LOG_TIME_MICROS_WITH_CATEGORY(strprintf("lock contention %s, %s:%d", pszName, pszFile, nLine), BCLog::LOCK);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this breaks the timing component, in that the timer now only measure the time of doing the logging, but not the lock contention?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative approach using a callback: master...stickies-v:bitcoin:2026-03/lock-contention-handler

Using globals is not ideal. But on the upside, it completely removes sync's dependency on logging, which I think is a nice property (and relevant for e.g. kernel).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this seems overly complicated.

Pushed a fixed up version to theuni@46de678

Is that missing something compared to the callback approach?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that looks good! I'd probably modernize the strings to string_view but that's a detail.

I was curious to see what it would take to decouple sync from logging entirely, but I think your version is better when there's currently no hard requirement to decouple them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks!

Fwiw, I don't think the two are incompatible. For ex, your global approach would be easier after moving everything out of the header. So I think it's a good thing to do either way. Will open a fresh PR.

But also, kernel could supply a different "kernel_sync.cpp" that implements the necessary methods. For most things I'd consider that a really ugly hack, but for low-level thread debugging, I don't think it would be the end of the world.

@theuni
Copy link
Member Author

theuni commented Mar 11, 2026

🤦

Well that's embarrassing. I forgot that the macro is RAII. Thanks @stickies-v for catching it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants