refactor: remove RecursiveMutex cs_nBlockSequenceId #22824

pull theStack wants to merge 1 commits into bitcoin:master from theStack:202108-refactor-use_atomic_for_nblocksequenceid changing 2 files +3 −7
  1. theStack commented at 10:15 AM on August 28, 2021: member

    The RecursiveMutex cs_nBlockSequenceId is only used at one place in CChainState::ReceivedBlockTransactions() to atomically read-and-increment the nBlockSequenceId member:

    https://github.com/bitcoin/bitcoin/blob/83daf47898f8a79cb20d20316c64becd564cf54c/src/validation.cpp#L2973-L2976

    For this simple use-case, we can make the member std::atomic instead to achieve the same result (see https://en.cppreference.com/w/cpp/atomic/atomic/operator_arith).

    This is related to #19303. As suggested in the issue, I first planned to change the RecursiveMutex to Mutex (still possible if the change doesn't get Concept ACKs), but using a Mutex for this simple operation seems to be overkill. Note that at the time when this mutex was introduced (PR #3370, commit 75f51f2a63e0ebe34ab290c2b7141dd240b98c3b) std::atomic were not used in the codebase yet -- according to git log -S std::atomic they have first appeared in 2016 (commit 7e908c7b826cedbf29560ce7a668af809ee71524), probably also because the compilers didn't support them properly earlier.

    At this point, the cs_main lock is set, hence we can use a plain int for the member and mark it as guarded by cs_main.

  2. fanquake added the label Validation on Aug 28, 2021
  3. hebasto commented at 10:20 AM on August 28, 2021: member

    Concept ACK.

  4. Zero-1729 commented at 11:47 AM on August 28, 2021: contributor

    Concept ACK

  5. ryanofsky approved
  6. ryanofsky commented at 12:16 PM on August 28, 2021: member

    Code review ACK 98d60b1c54112c772663e3add6665a65d264498c. Funny, I suggested this exact change yesterday #22564 (review)!

  7. hebasto approved
  8. hebasto commented at 12:36 PM on August 28, 2021: member

    ACK 98d60b1c54112c772663e3add6665a65d264498c. I have reviewed the code and it looks OK, I agree it can be merged.

    Thanks for slaying another RecursiveMutex :crossed_swords:

  9. MarcoFalke commented at 2:11 PM on August 28, 2021: member

    As this is only accessed in one place (that already has cs_main), it would also be possible to make it a plain int

  10. hebasto commented at 2:16 PM on August 28, 2021: member

    As this is only accessed in one place (that already has cs_main), it would also be possible to make it a plain int

    Doesn't it make code fragile for future changes?

  11. Zero-1729 approved
  12. Zero-1729 commented at 6:17 PM on August 28, 2021: contributor

    crACK 98d60b1 🧉

  13. DrahtBot commented at 4:01 AM on August 29, 2021: member

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #22564 ([WIP] refactor: Move mutable globals cleared in ::UnloadBlockIndex to BlockManager by dongcarl)

    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.

  14. MarcoFalke commented at 7:33 AM on August 29, 2021: member

    Doesn't it make code fragile for future changes?

    How?

  15. hebasto commented at 7:37 AM on August 29, 2021: member

    Doesn't it make code fragile for future changes?

    How?

    Another access to the variable will be added in a new place, but the variable remains plain int32_t.

  16. MarcoFalke commented at 8:08 AM on August 29, 2021: member

    We are using lock annotations to protect against this, no?

  17. hebasto commented at 8:13 AM on August 29, 2021: member

    We are using lock annotations to protect against this, no?

    Thread safety annotations go with a mutex. Without a mutex (this PR) nothing will guard the access to a plain int32_t, no?

  18. MarcoFalke commented at 9:10 AM on August 29, 2021: member

    Yes, I mentioned the validation mutex cs_main, which seems fine because the block's sequence is only used by validation.

  19. hebasto commented at 11:00 AM on August 29, 2021: member

    @MarcoFalke

    Yes, I mentioned the validation mutex cs_main, which seems fine because the block's sequence is only used by validation.

    You are right. The following change:

    diff --git a/src/validation.cpp b/src/validation.cpp
    index ec457da5c..9944e3155 100644
    --- a/src/validation.cpp
    +++ b/src/validation.cpp
    @@ -2970,10 +2970,7 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
                 CBlockIndex *pindex = queue.front();
                 queue.pop_front();
                 pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
    -            {
    -                LOCK(cs_nBlockSequenceId);
    -                pindex->nSequenceId = nBlockSequenceId++;
    -            }
    +            pindex->nSequenceId = nBlockSequenceId++;
                 if (m_chain.Tip() == nullptr || !setBlockIndexCandidates.value_comp()(pindex, m_chain.Tip())) {
                     setBlockIndexCandidates.insert(pindex);
                 }
    diff --git a/src/validation.h b/src/validation.h
    index b80fa9d32..58eed48c9 100644
    --- a/src/validation.h
    +++ b/src/validation.h
    @@ -558,9 +558,8 @@ protected:
          * Every received block is assigned a unique and increasing identifier, so we
          * know which one to give priority in case of a fork.
          */
    -    RecursiveMutex cs_nBlockSequenceId;
         /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
    -    int32_t nBlockSequenceId = 1;
    +    int32_t nBlockSequenceId GUARDED_BY(::cs_main) = 1;
         /** Decreasing counter (used by subsequent preciousblock calls). */
         int32_t nBlockReverseSequenceId = -1;
         /** chainwork for the last block that preciousblock has been applied to. */
    @@ -749,7 +748,7 @@ public:
     
         void PruneBlockIndexCandidates();
     
    -    void UnloadBlockIndex();
    +    void UnloadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
     
         /** Check whether we are doing an initial block download (synchronizing from disk or network) */
         bool IsInitialBlockDownload() const;
    

    looks more preferable.

  20. refactor: remove RecursiveMutex cs_nBlockSequenceId
    The RecursiveMutex cs_nBlockSequenceId is only used at one place in
    CChainState::ReceivedBlockTransactions() to atomically read-and-increment the
    nBlockSequenceId member. At this point, the cs_main lock is set, hence we can
    use a plain int for the member and mark it as guarded by cs_main.
    0bd882b740
  21. theStack renamed this:
    refactor: remove RecursiveMutex cs_nBlockSequenceId, use std::atomic instead
    refactor: remove RecursiveMutex cs_nBlockSequenceId
    on Aug 29, 2021
  22. theStack force-pushed on Aug 29, 2021
  23. theStack commented at 11:38 AM on August 29, 2021: member

    @MarcoFalke @hebasto: Thanks, that makes sense. I agree, considering that CChainState::ReceivedBlockTransactions() holds cs_main (which I wasn't aware of before), just using a plain int and marking it as guarded by cs_main is preferred.

    Updated PR title and description, force-pushed with the suggested change.

  24. Zero-1729 approved
  25. Zero-1729 commented at 1:21 PM on August 29, 2021: contributor

    ACK 0bd882b

  26. promag commented at 1:50 PM on August 29, 2021: member

    Code review ACK 0bd882b7405414b5355e69a9fdcd7a533e504b6b.

  27. fanquake deleted a comment on Aug 29, 2021
  28. hebasto approved
  29. hebasto commented at 6:46 PM on August 29, 2021: member

    ACK 0bd882b7405414b5355e69a9fdcd7a533e504b6b

  30. MarcoFalke merged this on Aug 30, 2021
  31. MarcoFalke closed this on Aug 30, 2021

  32. jonatack commented at 9:28 AM on August 30, 2021: member

    Markdown <strike></strike> markup doesn't translate well to text formatting in the merge commit description. Seems good not to rely on markdown in the PR description for it to make sense, especially strike-through formatting.

  33. sidhujag referenced this in commit 16d4b8d9dc on Aug 30, 2021
  34. PastaPastaPasta referenced this in commit 80c1316da7 on Mar 13, 2022
  35. DrahtBot locked this on Aug 30, 2022

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-14 21:14 UTC

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