-
Notifications
You must be signed in to change notification settings - Fork 10
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
don't start kernel level platform timer when applying blocks #1130
Conversation
if(kevent64(kqueue_fd, &aTimerEvent, 1, NULL, 0, KEVENT_FLAG_IMMEDIATE, NULL) != 0) | ||
expired = true; | ||
_state = state_t::timed_out; |
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.
It looks like this wasn't updated completely in #1107. We should really refactor the code a bit to move the common state logic out of the platform specific impls.
if(prior_state == state_t::stopped) | ||
return; | ||
_state = state_t::stopped; | ||
if(prior_state == state_t::timed_out || timer_running_forever) |
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.
Another minor tweak here is to not stop the timer if it has already expired. Obviously that's a rather rare scenario, but might as well be thorough while tweaking all this.
if(tp == fc::time_point::maximum()) { | ||
_state = state_t::running; | ||
timer_running_forever = true; | ||
return; | ||
} | ||
fc::microseconds x = tp.time_since_epoch() - fc::time_point::now().time_since_epoch(); | ||
timer_running_forever = false; |
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.
No need to change, just a remark. Personally I prefer initializing members once if possible, as in:
if(tp == fc::time_point::maximum()) { | |
_state = state_t::running; | |
timer_running_forever = true; | |
return; | |
} | |
fc::microseconds x = tp.time_since_epoch() - fc::time_point::now().time_since_epoch(); | |
timer_running_forever = false; | |
timer_running_forever = (tp == fc::time_point::maximum()); | |
if(timer_running_forever ) { | |
_state = state_t::running; | |
return; | |
} | |
fc::microseconds x = tp.time_since_epoch() - fc::time_point::now().time_since_epoch(); |
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.
that does look good here
Note:start |
When passing
fc::time_point::max()
toplatform_timer::start()
,platform_timer
recognizes that,spring/libraries/chain/platform_timer_posix.cpp
Lines 57 to 62 in 909603c
and pretends the timer is running without actually starting the timer. Then when
stop()
is called it would still make a request to the kernel to stop the never started timer. There is nothing logically wrong with that, it's just a wasteful syscall that isn't needed that can end up happening thousands of times a second.My memory was that historically when applying a block,
transaction_context::init()
would effectivelyplatform_timer::start(fc::time_point::max())
. That would result in the condition above and it's why I wrote #1119 worded the way it is. But I can't actually find evidence of this in history so I may be misremembering it.Instead, today,
transaction_context::init()
passes a time 1 year in the future when applying a block. This actually makes the situation worse than what I thought: now for every transaction while applying a block a timer is entirely needlessly started and stopped.So this PR,
transaction_context::init()
doplatform_timer::start(fc::time_point::max())
; the timer somehow needs to indicaterunning
state for things likechecktime()
to work so unless wanting to touch a lot more code we can't just entirely be hands off the timer. We could also do something like aplatform_timer::start_forever()
instead if not liking overloading the meaning ofstart()
.platform_timer
now remembers when it was started withfc::time_point::max()
and when stopped skips the kernel call.There are a handful of ways to go about accomplishing various nuances in what this PR does. Any strong opinions for a different approach can be explored.