xtimer: set now pointer correctly in _update_short_timers() loop#13850
xtimer: set now pointer correctly in _update_short_timers() loop#13850kaspar030 merged 3 commits intoRIOT-OS:masterfrom
Conversation
|
Good job tracking this down @miri64 and @cgundogan! |
3c34649 to
11d4b6f
Compare
|
Right. I wanted to mark @cgundogan as a co-author for the commit ^^". My mishap is now fixed ;-) |
|
Reminds me of this: #9530 (comment) 😁 |
Wrong mail address apparently :D |
kaspar030
left a comment
There was a problem hiding this comment.
ACK for the fix. Please someone else take a look at the test.
This fixes `xtimer` to use `xtimer_now64()` instead of `xtimer_now()` for updating the `*now` variable during the iteration in `_update_short_timers()` function. The same function is used to initialize `*now` in `_timer_callback()` below. While using `xtimer_now()` in this iteration step does not hinder the proper execution of all timers in the short term timers (for those the `xtimer` module only looks at the `start_time` member, not the `long_start_time` member) at least for the current long term time window (I did not test higher cases), it sets the `long_start_time` member to 0 for all timers following in the list of timers after this iteration step. However, external modules that rely on this to be correct, e.g. evtimer [1], fail their calculations when trying to compare to the current value to `xtimer_now64()`. [1] https://github.com/RIOT-OS/RIOT/blob/11f3d68/sys/evtimer/evtimer.c#L118-L121 Co-Authored-By: Cenk Gündoğan <mail+dev@gundogan.net>
11d4b6f to
ca8afaf
Compare
Fixed! |
ACK without test? Why is the Ham playing the Chicken here? |
Murdock should be running the test. |
@miri64 kept me up to date during the bug fixing. Once you see the fix, the bug is obvious. |
|
Oops, |
|
Because Line 334 in 11f3d68 long_start_time
Meaning there should be another timer in between. |
|
This works for me: Did I understand the problem correctly? Diff: |
|
Yepp that was the same idea I had yesterday before going to bed and it works for me as well! |
|
Added a third timer to the test. With that the bug becomes reproducible as expected. |
I think I pretty much understand it now. I updated the OP as such. |
|
Works for me and looks good to me. |
e1ecae4 to
f59ea80
Compare
So I can squash? |
|
yes |
Co-Authored-By: Julian Holzwarth <julian.holzwarth@fu-berlin.de>
|
While I wrote the test last night, I think we pretty much came to the same idea while I was keeping it behind the curtain. So I added you as a co-author :-). |
f59ea80 to
085c62e
Compare
|
thanks |
|
The shortest reproducer should be:
This should basically instantly trigger 3. |
This alone makes the test anything but short :-P
Unsurprisingly if you set 3 to trigger just after 2. I think my test is faster, involves less modules, and has less potential to be unstable because precise timings are required. |
|
@JulianHolzwarth seems to be happy about the current state of the tests and has understood the bug enough to come up with his own version of the test. So can we merge? |
Go through the list of changes, as I typically do to understand the thoughts behind a PR, and you find it pretty easy. |
Exactly. Nicer if it's length is one, not a multiple of that. If a PR fixes an important bug, it should do just that, and not piggyback style changes. If the diff of a PR fixes one line and that is the first, with only additions of a regression test following, that's easy to parse. If a PR fixes one line but the diff shows a couple of others, it is harder to parse. Just my opinion, I guess...
With wait 2**32min, I obviously meant "set _xtimer_current_time". :) Anyhow, I see this as sport, so here's something even simpler, faster, involving less modules and is even less timing critical (so overall much better): https://gist.github.com/272d7eb3e79b47a551e6c14798dfdadb Feel free to use that instead, I can also PR that after this is merged. |
|
Nah, I keep it as is now. |
|
Ok then, let's go! |
|
Backport provided in #13854 |

Contribution description
This fixes
xtimerto usextimer_now64()instead ofxtimer_now()for updating the*nowvariable during the iteration in_update_short_timers()function. The same function is used to initialize*nowin_timer_callback()below.While using
xtimer_now()in this iteration step does not hinder the proper execution of all timers in the short term timers (for those thextimermodule only looks at thestart_timemember, not thelong_start_timemember) at least for the current long term time window (I did not test higher cases), it sets thelong_start_timemember to 0 for all timers following in the list of timers after this iteration step. However, external modules that rely on this to be correct, e.g. evtimer, fail their calculations when trying to compare to the current value toxtimer_now64().If the changed header becomes the new head this behavior won't show up, as it is overwritten once the update of all headers is done. However, all timers later in the list will now have the wrong values.
Testing procedure
A regression test testing this behavior is provided. Confirm the bug, by reverting the fix and running it, run it with the patch to confirm that it fixes the bug:
Issues/PRs references
None, but should fix a known, but not reported issue, where RPL starts "spamming" DIS every minute instead of every 5 minutes after >71min.