-
Notifications
You must be signed in to change notification settings - Fork 36.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace lock with thread safety annotation in CBlockTreeDB::LoadBlockIndexGuts() #24197
Replace lock with thread safety annotation in CBlockTreeDB::LoadBlockIndexGuts() #24197
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 20276ca, I have reviewed the code and it looks OK, I agree it can be merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK, I reviewed the code; I agree this is safe, and can be merged.
From a practical perspective, I wonder if this change (or changes like it) would see a performance gain, or if the goal is more about clean code. I also wonder if it is will result in future changes that are sub-optimal. What are the odds that something will want to call this function in the future that is not already locking cs_main?
Thanks for reviewing!
I think the goal is to remove any unneeded locks for performance, while using locks where needed for thread safety. If you launch bitcoind with
In this case, thanks to the thread safety annotation the compiler would give a warning, and the run-time assertion may be hit, both of which would serve to warn that a missing lock is needed. At this time, however, More information about Clang thread safety analysis, if helpful: |
Thanks for the response @jonatack completely agree with minimizing the time spent in critical sections (and doing so saftely) I have a few questions if you'd be so kind :) How expensive is locking a RecursiveMutex, if the same thread already has acquired it? Is it the same cost as acquiring an unlocked recursive mutex, or basically a no-op? My concern is not a future caller would trigger a data-race / thread insafety, the annotations / assertions prevent that. My question is more along the line of, if we introduce a call in the future in some function Thanks |
This is only called once in init, which already holds cs_main. It doesn't really make sense to call this anywhere in a hot loop |
@PastaPastaPasta if you'd like to dive deeper, have a look at |
…lockTreeDB::LoadBlockIndexGuts() 20276ca Replace lock with thread safety annotation in CBlockTreeDB::LoadBlockIndexGuts() (Jon Atack) Pull request description: Following up on bitcoin#22932 (comment) by Marco Falke (good observation, thank you), we can replace a cs_main lock in `CBlockTreeDB::LoadBlockIndexGuts()` with a Clang thread safety annotation/assertion instead. The unlocked code is reverted to its original state before bitcoin#22932. ACKs for top commit: hebasto: ACK 20276ca, I have reviewed the code and it looks OK, I agree it can be merged. Tree-SHA512: 2d91d1c962af0286d835d92a56396a27ea00e9d061b869eaff9421b448a083b0513828e1d4df7504396896057bf1e344e180a50271a5cfd1e1c7b6527155b2bb
Summary: > CBlockIndex::nStatus may be racy, i.e. potentially accessed by multiple threads, see [[bitcoin/bitcoin#17161 | core#17161]]. A solution is to guard it by cs_main, along with fellow data members nFile, nDataPos and nUndoPos. Co-authored-by: Vasil Dimov <[email protected]> This concludes backport of [[bitcoin/bitcoin#22932 | core#22932]] and [[bitcoin/bitcoin#24197 | core#24197]] bitcoin/bitcoin@6ea5682 bitcoin/bitcoin@20276ca Depends on D13037 Test Plan: With clang and DEBUG: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Subscribers: Fabien Differential Revision: https://reviews.bitcoinabc.org/D13038
Following up on #22932 (comment) by Marco Falke (good observation, thank you), we can replace a cs_main lock in
CBlockTreeDB::LoadBlockIndexGuts()
with a Clang thread safety annotation/assertion instead. The unlocked code is reverted to its original state before #22932.