-
Notifications
You must be signed in to change notification settings - Fork 38.8k
p2p: Eliminate atomic for m_last_getheaders_timestamp #25557
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
Conversation
src/net_processing.cpp
Outdated
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.
Why change NodeSeconds{} to {}?
m_last_getheaders_timestamp is of type
NodeClock::time_point aka
std::chrono::time_point<NodeClock> aka
std::chrono::time_point<std::chrono::system_clock>
while NodeSeconds is of type
std::chrono::time_point<NodeClock, std::chrono::seconds> aka
std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>.
So, the type of m_last_getheaders_timestamp omits the second template parameter. It defaults to std::chrono::system_clock::duration. From the documentation, it is std::chrono::duration<rep, period>, but I can't find where it is specified that std::chrono::system_clock::period is std::ratio<1>. It only says:
period -- a std::ratio type representing the tick period of the clock, in seconds
Even if that is ok, there is now inconsistency wrt how m_last_getheaders_timestamp is set - in its declaration NodeSeconds{} is used and here {} is used.
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.
NodeSeconds{}, as well as std::chrono::time_point<NodeClock>{} will construct a time point representing the clock's epoch, see https://en.cppreference.com/w/cpp/chrono/time_point/time_point. The duration (/time) since epoch is always zero, regardless of the durations period. So this should be fine as is.
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.
Alright, zero is always zero even if the period is std::ratio<1> for one and something else for the other.
This means that it should be possible to use just {} in the declaration for consistency, right?
-NodeClock::time_point m_last_getheaders_timestamp GUARDED_BY(m_last_getheaders_mutex) {NodeSeconds{}};
+NodeClock::time_point m_last_getheaders_timestamp GUARDED_BY(m_last_getheaders_mutex) {};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.
This means that it should be possible to use just {} in the declaration for consistency, right?
For atomic that isn't possible due to compiler bugs, but without atomic, it may be possible.
src/net_processing.cpp
Outdated
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.
A similar result can be achieved without a mutex, in a lock-free manner:
// Only allow a new getheaders message to go out if we don't have a recent
// one already in-flight
- if (current_time - peer.m_last_getheaders_timestamp.load() > HEADERS_RESPONSE_TIME) {
+ auto last = peer.m_last_getheaders_timestamp.load();
+ if (current_time - last > HEADERS_RESPONSE_TIME &&
+ peer.m_last_getheaders_timestamp.compare_exchange_strong(last, current_time)) {
+
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETHEADERS, locator, uint256()));
- peer.m_last_getheaders_timestamp = current_time;
return true;
}Anyway, feel free to ignore. I think in this case using a mutex is also ok.
src/net_processing.cpp
Outdated
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.
Is it not better to first lock the mutex and then acquire the current time, because locking the mutex can take "long" time and then we would operate on an outdated current_time?
maflcko
left a comment
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.
Concept ACK removing atomic (see my rationale: #25454 (comment))
Though, I don't think a Mutex is needed either? #25454 (comment)
This variable is only used in a single thread, so no atomic or mutex is necessary to guard it.
8b09242 to
613e221
Compare
|
Updated the first commit to remove the mutex as well, since I had it wrong that this variable was being accessed in multiple threads. |
vasild
left a comment
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 613e221
|
review ACK 613e221 This brings it consistently in line with other members that are only used in one thread, such as |
Eliminate the unnecessary atomic guarding
m_last_getheaders_timestamp, which is only accessed in a single thread (thanks to MarcoFalke for pointing this out).Also address a nit that came up in #25454.