RIOT
RIOT copied to clipboard
cpu/native: timer interrupt issue
~~AFAIK all interrupts shall cause a thread yield (thread_yield_higher
), right?~~
EDIT 01/02/17: Timer in native stops "working" ~~if fired too fast~~ sometimes. See https://github.com/RIOT-OS/RIOT/issues/6442#issuecomment-276765280
Shouldn't this be done here: https://github.com/RIOT-OS/RIOT/blob/master/cpu/native/native_cpu.c#L145 ?
I observed it while testing the callback of the xtimer_mutex_lock_timeout
. Removing the thread_yield_higher
call from the _mutex_timeout
callback, blocks indefinitely.
I thought it might be because no yielding is done, but I've not enough inside on this implementation. So maybe the issue is somewhere else.
Please provide a minimal application that reliably shows the defect.
So far I'm using tests/posix_semaphore
, keeping/removing the thread_yield_higher
in the callback of the timer to trigger this. I can't promise I have time to look further into this for this release.
As just mentioned in #6441 I also realized that in native
when one xtimer is set and fired I can't any future xtimer does not fire...
EDIT: had a quick look at it. The scheduler brings riot to the idle thread. There pm_set_lowest
is called and it never comes back. Commenting out the code in pm_set_lowest
(or adding there a thread_yield_higher
) doesn't help. It really seems that it doesn't trigger any "interrupt" more after one has occurred.
If it helps, running the test application in #6441 enabling output in periph/timer.c
and in native_cpu.c
produces the following output: http://pastebin.com/T3xRNMUZ
@LudwigKnuepfer try the following "snippet" to see what I mean. It's not that the thread doesn't yield but that the timer stops "working" if fired to fast. Main will print dots until thread 1 wakes and prints a newline character.
If you set the line with the /* change this value */
to around 1000 the thing works forever on my laptop (or until the battery runs flat). If you set it to 500 or lower it stops working. Not always at the same moment, so I guess that the SIG Alarm is not caught or maybe too late (?). Didn't dig into it yet.
#include <stdio.h>
#include "thread.h"
#include "mutex.h"
#include "xtimer.h"
static char stack[THREAD_STACKSIZE_MAIN];
static void *second_thread(void *arg)
{
(void) arg;
while (1) {
xtimer_usleep(1000000);
printf("\n");
}
return NULL;
}
int main(void)
{
xtimer_init();
thread_create(stack,
sizeof(stack),
THREAD_PRIORITY_MAIN - 1,
THREAD_CREATE_WOUT_YIELD | THREAD_CREATE_STACKTEST,
second_thread,
NULL,
"second_thread");
while (1) {
printf(".");
xtimer_usleep(500); /* change this value */
}
}
@lebrush: I just tested your snippet on macOS and got an interesting behavior:
- with
xtimer_usleep(500)
the application stops working after some time, not printing dots.
or newlines - with
xtimer_usleep(1000)
the application runs forever, but after some time it stops printing dots and only newlines from threads get printed.
So for the latter case the main thread seems to stuck or nor context switch is happening. I'll try again with some debug output enabled.
btw. setting it to 100 also runs ~~forever~~ (very long), but with 500 it stops even with 1000 sometimes. So firing too fast might not be the real/exact issue here?!
Thanks for testing! Description changed :-)
Terribly sorry, but I have no time to properly investigate right now. As a general remark: signals/interrupts in POSIX may be lost. I.e. if the next timer fires while signal for the current one is still being processed, there will be no signal for the next timer. This is what I would check for first.
Also: thank you for the thorough bug report!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.
For reference, may be related to #6052
I'm inclined to just close this one and blame xtimer. Anyone against this?
Yeah.