[riot-notifications] [RIOT-OS/RIOT] sys/xtimer: Fixed interrupt race-condition in _xtimer_set_absolute (#11087)

Olivier de Schaetzen notifications at github.com
Fri Mar 1 15:05:50 CET 2019


<!--
The RIOT community cares a lot about code quality.
Therefore, before describing what your contribution is about, we would like
you to make sure that your modifications are compliant with the RIOT
coding conventions, see https://github.com/RIOT-OS/RIOT/wiki/Coding-conventions.
-->

### Contribution description
When setting a short timer using `xtimer_usleep`, there exists a race condition if an interrupt occurs between the `_xtimer_now()` call done in `_xtimer_set` and the one done in `_xtimer_set_absolute`. If this interrupt lasts longer than the duration of the timer, the offset variable in `_xtimer_set_absolute` will underflow, causing the timer to practically permanently sleep, until it fully wraps around.

I have fixed this problem by checking if the target has already been exceeded, and if so, immediately shoot the timer. In case we need to back off, I have also replaced `xtimer_spin_until` with `_xtimer_spin` because of an identical issue: Even if the calculated offset was correct, an interrupt between the offset calculation and the spin might cause the target to be exceeded before the spin, causing `xtimer_spin_until` to also permanently sleep until a wrap around.

### Testing procedure
I discovered this bug while working on a custom board, which runs on an stm32l496. I created the following test-case, which caused the main thread to freeze (and thus the led to stop blinking), usually after a few seconds up to a minute, given that a lot of data is being send on UART_0:

```C
static void SRV_PTC_UART_DSP_ReceiveCB(void *arg, uint8_t data) {
	for (volatile int i = 0 ; i < 100000 ; i++);
}

int main(void) {
	xtimer_init();
	uart_init(UART_DEV(0), 1200, SRV_PTC_UART_DSP_ReceiveCB, NULL);
	while (1) {
		LED1_TOGGLE;		
		for (size_t i = 0 ; i < 10000 ; i++)
			xtimer_usleep(30);
	}
}
```
With the changes in this commit, this code seems to be stable.

### Issues/PRs references
I haven't made an issue for this problem, so there is nothing to refer to. If needed I can make one, though.

You can view, comment on, or merge this pull request online at:

  https://github.com/RIOT-OS/RIOT/pull/11087

-- Commit Summary --

  * Fixed interrupt race-condition in _xtimer_set_absolute

-- File Changes --

    M sys/xtimer/xtimer_core.c (7)

-- Patch Links --

https://github.com/RIOT-OS/RIOT/pull/11087.patch
https://github.com/RIOT-OS/RIOT/pull/11087.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/RIOT-OS/RIOT/pull/11087
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/notifications/attachments/20190301/52a76542/attachment.html>


More information about the notifications mailing list