Skip to content
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

drivers/periph_common/timer: protect timer_set from IRQs #13060

Merged

Conversation

MichelRottleuthner
Copy link
Contributor

Contribution description

This fixes a concurrency problem in the timer_set implementation.
Somewhere between getting the current time from timer_read(), adding the timeout, and then actually writing it to the timer a thread might be de-scheduled causing the targeted time to be already passed.

Testing procedure

Reading the code + thinking ;)
Running tests/periph_timer and tests/bench_timer but that didn't really show errors before...

Issues/PRs references

@MichelRottleuthner MichelRottleuthner added Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Area: timers Area: timer subsystems labels Jan 9, 2020
Copy link
Contributor

@kaspar030 kaspar030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK. About time. 😉

@fjmolinas fjmolinas added CI: run tests If set, CI server will run tests on hardware for the labeled PR CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Jan 9, 2020
@kaspar030
Copy link
Contributor

I've been doing this in ztimer for a while without problems.

Note that this does not prevent underflows for very small values. E.g., samr21-xpro still underflows for values <8. tests/periph_timer_short_relative_set gives insightful results. Eventually, we should check for valid minimum values.

@MichelRottleuthner
Copy link
Contributor Author

Eventually, we should check for valid minimum values

Yeah, either within protecting it like you did in ztimer or actually inside of the irq disabled block of this function would be the only reasonable way to do such a check, to not suffer from possible de-scheduling.


#ifndef PERIPH_TIMER_PROVIDES_SET
int timer_set(tim_t dev, int channel, unsigned int timeout)
{
return timer_set_absolute(dev, channel, timer_read(dev) + timeout);
unsigned int state = irq_disable();
unsigned int base = timer_read(dev);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to use an additional local variable to read the current timer value when no further processing of the current time is taking place, such as testing for underflows?

It's just a question, the compiler will probably generate the same code and keep the current timer value in a register and not require additional stack space.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think the compiler will be smarter than me here. There is absolutely no reason to not make it explicitly without this variable. Updated it and squashed directly, thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hah, that was a style nit I chose not to mention. 😉 I also like it much better now.

@MichelRottleuthner
Copy link
Contributor Author

@kaspar030 I assume your ACK is still valid? Ready to merge?

@kaspar030
Copy link
Contributor

@kaspar030 I assume your ACK is still valid? Ready to merge?

Yes!

@kaspar030 kaspar030 merged commit 69b522e into RIOT-OS:master Jan 10, 2020
@fjmolinas fjmolinas added this to the Release 2020.01 milestone Jan 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: timers Area: timer subsystems CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: run tests If set, CI server will run tests on hardware for the labeled PR Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants