cosmo-hf: add limited busy-polls in all wait paths #2055
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Presently, the
cosmo-hf
driver has three functions that wait for some status to change before continuing:wait_fpga_busy
,wait_fpga_rx
, andwait_flash_busy
. All of these functions check the desired condition in a loop and sleep for 1ms when it is not satisfied. Currently,wait_fpga_busy
will first perform a limited number of busy-polls before starting to sleep between polls, but the other functions do not. While investigating HF write performance on Grapefruit,@cbiffle and I found that commenting out the sleeps in these polling functions improved HF write performance significantly: writing 2MiB of random data using
humility qspi -D
went from taking about a minute to about 36 seconds --- that's a 40% performance improvement.This branch is like a slightly more principled version of commenting out the
sleep_for
calls. I've generalized the perviouswait_fpga_busy
of doing 32 busy-polls before starting to sleep to something that can be used by all three wait-for-condition type functions. I did change the code for implementing this a bit from the previous thing, which implemented the counter using afor i in 0..
loop that checkedi > 32
This was a bit more concise and kind of a cute trick, but had a somewhat surprising behavior: the loop wasn't actually infinite, and would terminate afteru32::MAX
polls. Of course, polling for 4,294,967,295ms means we would have waited about 50 days for a write to complete before terminating the loop unexpectedly, and if that happened, something would have to be REALLY broken. But, it's still a pretty wrong behavior, so the implementation I've done --- using awhile
loop with an explicitly incremented counter --- will never terminate unless the condition has actually changed, which seems a little less anxiety-inducing.