threading: never require logging from sync.h (take 2) #34823

pull theuni wants to merge 1 commits into bitcoin:master from theuni:thread-no-logging changing 2 files +29 −7
  1. theuni commented at 4:53 PM on March 13, 2026: member

    This is an updated version of #34793 after stickies-v pointed out that the approach there was broken.

    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.

  2. DrahtBot commented at 4:54 PM on March 13, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK stickies-v, sedited

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

    <!--174a7506f384e20aa4161008e828411d-->

    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.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  3. theuni commented at 4:54 PM on March 13, 2026: member

    ping @hebasto and @stickies-v. This one actually works :)

  4. ajtowns commented at 5:00 PM on March 13, 2026: contributor

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

    The cost incurred should be trivial compared to the lock contention. (The logging won't occur if the category is disabled)

  5. in src/sync.h:83 in 46de6787b9
      78 | + * thread, or spuriously. Responsible for locking the lock before returning.
      79 | + */
      80 | +#ifdef DEBUG_LOCKCONTENTION
      81 | +
      82 | +template <typename LockType>
      83 | +void ContendedLock(const char* pszName, const char* pszFile, int nLine, LockType& lock);
    


    stickies-v commented at 3:02 PM on March 15, 2026:

    nit: I don't understand why we can't easily use std::string_view for this new code. The strings get forwarded to strprintf which works well with std::string_view, so this seems like a straightforward small improvement? I don't think this introduces any new null-termination concerns that weren't already there, and I'm not sure why we need either all or none of the debugging functions to take std::string_view?

    <details> <summary>git diff on 46de6787b9</summary>

    diff --git a/src/sync.cpp b/src/sync.cpp
    index ea5886492b..0e5c623d21 100644
    --- a/src/sync.cpp
    +++ b/src/sync.cpp
    @@ -23,13 +23,13 @@
     #ifdef DEBUG_LOCKCONTENTION
     
     template <typename LockType>
    -void ContendedLock(const char* pszName, const char* pszFile, int nLine, LockType& lock)
    +void ContendedLock(std::string_view name, std::string_view file, int nLine, LockType& lock)
     {
    -    LOG_TIME_MICROS_WITH_CATEGORY(strprintf("lock contention %s, %s:%d", pszName, pszFile, nLine), BCLog::LOCK);
    +    LOG_TIME_MICROS_WITH_CATEGORY(strprintf("lock contention %s, %s:%d", name, file, nLine), BCLog::LOCK);
         lock.lock();
     }
    -template void ContendedLock(const char* pszName, const char* pszFile, int nLine, std::unique_lock<std::mutex>& lock);
    -template void ContendedLock(const char* pszName, const char* pszFile, int nLine, std::unique_lock<std::recursive_mutex>& lock);
    +template void ContendedLock(std::string_view name, std::string_view file, int nLine, std::unique_lock<std::mutex>& lock);
    +template void ContendedLock(std::string_view name, std::string_view file, int nLine, std::unique_lock<std::recursive_mutex>& lock);
     
     #endif
     
    diff --git a/src/sync.h b/src/sync.h
    index 9a6313d938..00fdaae942 100644
    --- a/src/sync.h
    +++ b/src/sync.h
    @@ -80,7 +80,7 @@ inline bool LockStackEmpty() { return true; }
     #ifdef DEBUG_LOCKCONTENTION
     
     template <typename LockType>
    -void ContendedLock(const char* pszName, const char* pszFile, int nLine, LockType& lock);
    +void ContendedLock(std::string_view name, std::string_view file, int nLine, LockType& lock);
     #endif
     
     /**
    
    

    </details>


    theuni commented at 6:19 PM on March 16, 2026:

    @stickies-v I suppose there's no reason not to :)

    Changed, thanks.

  6. stickies-v approved
  7. stickies-v commented at 4:17 PM on March 15, 2026: contributor

    ACK 46de6787b96f8defd04abc5b0045073b0aa1dac5

  8. threading: never require logging from sync.h
    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.
    79467e3ec7
  9. theuni force-pushed on Mar 16, 2026
  10. in src/sync.h:83 in 79467e3ec7
      78 | + * thread, or spuriously. Responsible for locking the lock before returning.
      79 | + */
      80 | +#ifdef DEBUG_LOCKCONTENTION
      81 | +
      82 | +template <typename LockType>
      83 | +void ContendedLock(std::string_view name, std::string_view file, int nLine, LockType& lock);
    


    stickies-v commented at 10:32 AM on March 17, 2026:

    Leaving this as a comment for easier discussion, but unrelated to this line

    An alternative approach could be to just move the UniqueLock::Enter implementation to sync.cpp, removing the need for ContendedLock altogether. It would probably prevent this function from being inlined, but compared to the cost of acquiring a lock (happy path) the extra function call should be negligible?

    <details> <summary>git diff on 79467e3ec7</summary>

    diff --git a/src/sync.cpp b/src/sync.cpp
    index 0e5c623d21..c8b902945d 100644
    --- a/src/sync.cpp
    +++ b/src/sync.cpp
    @@ -20,18 +20,19 @@
     #include <utility>
     #include <vector>
     
    -#ifdef DEBUG_LOCKCONTENTION
    -
    -template <typename LockType>
    -void ContendedLock(std::string_view name, std::string_view file, int nLine, LockType& lock)
    +template <typename MutexType>
    +void UniqueLock<MutexType>::Enter(const char* pszName, const char* pszFile, int nLine)
     {
    -    LOG_TIME_MICROS_WITH_CATEGORY(strprintf("lock contention %s, %s:%d", name, file, nLine), BCLog::LOCK);
    -    lock.lock();
    -}
    -template void ContendedLock(std::string_view name, std::string_view file, int nLine, std::unique_lock<std::mutex>& lock);
    -template void ContendedLock(std::string_view name, std::string_view file, int nLine, std::unique_lock<std::recursive_mutex>& lock);
    -
    +    EnterCritical(pszName, pszFile, nLine, Base::mutex());
    +#ifdef DEBUG_LOCKCONTENTION
    +    if (Base::try_lock()) return;
    +    LOG_TIME_MICROS_WITH_CATEGORY(strprintf("lock contention %s, %s:%d", pszName, pszFile, nLine), BCLog::LOCK);
     #endif
    +    Base::lock();
    +}
    +template void UniqueLock<Mutex>::Enter(const char*, const char*, int);
    +template void UniqueLock<RecursiveMutex>::Enter(const char*, const char*, int);
    +template void UniqueLock<GlobalMutex>::Enter(const char*, const char*, int);
     
     #ifdef DEBUG_LOCKORDER
     //
    diff --git a/src/sync.h b/src/sync.h
    index 00fdaae942..93dfe59a1e 100644
    --- a/src/sync.h
    +++ b/src/sync.h
    @@ -73,16 +73,6 @@ inline void DeleteLock(void* cs) {}
     inline bool LockStackEmpty() { return true; }
     #endif
     
    -/*
    - * Called when a mutex fails to lock immediately because it is held by another
    - * thread, or spuriously. Responsible for locking the lock before returning.
    - */
    -#ifdef DEBUG_LOCKCONTENTION
    -
    -template <typename LockType>
    -void ContendedLock(std::string_view name, std::string_view file, int nLine, LockType& lock);
    -#endif
    -
     /**
      * Template mixin that adds -Wthread-safety locking annotations and lock order
      * checking to a subset of the mutex API.
    @@ -153,17 +143,7 @@ class SCOPED_LOCKABLE UniqueLock : public MutexType::unique_lock
     private:
         using Base = typename MutexType::unique_lock;
     
    -    void Enter(const char* pszName, const char* pszFile, int nLine)
    -    {
    -        EnterCritical(pszName, pszFile, nLine, Base::mutex());
    -#ifdef DEBUG_LOCKCONTENTION
    -        if (!Base::try_lock()) {
    -            ContendedLock(pszName, pszFile, nLine, static_cast<Base&>(*this));
    -        }
    -#else
    -        Base::lock();
    -#endif
    -    }
    +    void Enter(const char* pszName, const char* pszFile, int nLine);
     
         bool TryEnter(const char* pszName, const char* pszFile, int nLine)
         {
    
    

    </details>


    theuni commented at 5:30 PM on March 17, 2026:

    I agree that losing the inlining would not be a huge deal, since a call to pthread_mutex_lock (or whatever the windows equivalent is) will likely always be emitted anyway. But I don't think we want to give up the property of sync.h being header-only, except in the obscure debugging cases.


    stickies-v commented at 5:55 PM on March 17, 2026:

    But I don't think we want to give up the property of sync.h being header-only, except in the obscure debugging cases.

    What's the benefit of a header-only sync.h, when I don't think we plan to ship util as a stand-alone library, and when the "except in the obscure debugging cases" caveat in practice doesn't make it header-only for our usage anyway?

    If this is indeed a useful property, it would be good to mention that in PR description (and maybe also a brief mention in sync.h, if you're up for adding a doc commit?)


    sedited commented at 10:51 AM on March 19, 2026:

    I'm fine with doing these small ad hoc changes to make working with low level headers easier. The point isn't that these should be shipped, but that they can easily be dropped into other places for experimentation and debugging (or at least that is how I used them before).

  11. stickies-v approved
  12. stickies-v commented at 10:33 AM on March 17, 2026: contributor

    re-ACK 79467e3ec7c2d756c4d824f642ed3856a4e72883 , thanks for doing the modernization right away 👍

  13. sedited approved
  14. sedited commented at 10:48 AM on March 19, 2026: contributor

    ACK 79467e3ec7c2d756c4d824f642ed3856a4e72883

  15. sedited merged this on Mar 19, 2026
  16. sedited closed this on Mar 19, 2026


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-18 15:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me