Conversation
|
Desperately needed for the new NDP ;-). |
|
I tested it on native and are just about to test it on samr21-xpro. |
|
Mhhhh I hit some race condition on diff --git a/sys/evtimer/evtimer.c b/sys/evtimer/evtimer.c
index 797f146..d8da2e2 100644
--- a/sys/evtimer/evtimer.c
+++ b/sys/evtimer/evtimer.c
@@ -124,6 +124,7 @@ void evtimer_add(evtimer_t *evtimer, evtimer_event_t *event)
_update_head_offset(evtimer);
_add_event_to_list(evtimer, event);
+ xtimer_usleep(1);
if (evtimer->events == event) {
_set_timer(&evtimer->timer, event->offset);
}it runs through. Any idea why? |
|
Same goes for |
|
Added a workaround for the race condition for now: /* XXX: next two lines fix known race condition on Cortex-M0 boards */
volatile int i = 1;
while (i--); |
|
(adds 14 byte to the text segment). |
tests/evtimer/main.c
Outdated
| { .event = { .offset = 1500 }, .msg = { .content = { .ptr = "supposed to be 1500" } } }, | ||
| { .event = { .offset = 659 }, .msg = { .content = { .ptr = "supposed to be 659" } } }, | ||
| { .event = { .offset = 3954 }, .msg = { .content = { .ptr = "supposed to be 3954" } } }, | ||
| { .msg = { .content = { .ptr = NULL } } }, /* sentinel */ |
There was a problem hiding this comment.
please use helper variable for length (unsigned nevent = sizeof(events)/sizeof(events[0]);
tests/evtimer/main.c
Outdated
| evtimer_add_msg(&evtimer, event, pid); | ||
| count++; | ||
| } | ||
| printf("Are the reception times of all %i msgs near to the supposed values?\n", |
| evtimer_event_t *events; /**< Event queue */ | ||
| } evtimer_t; | ||
|
|
||
| /** |
There was a problem hiding this comment.
What do you think about moving all msg related stuff into "evtimer_msg.h"?
There was a problem hiding this comment.
There's still a #include "msg.h" in this file :-)
That is indeed weird. |
|
Addressed comments. |
| evtimer_event_t *events; /**< Event queue */ | ||
| } evtimer_t; | ||
|
|
||
| /** |
There was a problem hiding this comment.
There's still a #include "msg.h" in this file :-)
| #ifndef EVTIMER_MSG_H | ||
| #define EVTIMER_MSG_H | ||
|
|
||
| #include "evtimer.h" |
|
@miri64 Please check out my original branch. I've added a callback field to evtimer_t, in the hope of simplifying handlers in the future. I've tried to debug the race condition you've found. I think it is the optimizer not getting the link traversal hack in _add_event_to_list(). Just making that function non-static also solves the issue. @miri64 How do we proceed? I'm fine with closing my initial PR. we could also continue there. |
I basically started to do the same yesterday, but stopped because I thought you maybe wanted to save code size, but if you are okay we can leave it as is.
If that's true then let's do it this way instead of the hacky volatile int decrementation I did ;-).
I'd prefer keeping this one open and closing yours, since this way the workload and pushing force to getting this is into master is on me ;-). |
|
(the pull-in of @kaspar030's changes addressed @lebrush's comments) |
Size-wise both workarounds don't make a difference. |
| * @extends evtimer_t | ||
| */ | ||
| typedef evtimer_t evtimer_msg_t; | ||
| /** |
tests/evtimer_msg/main.c
Outdated
| { .event = { .offset = 3954 }, .msg = { .content = { .ptr = "supposed to be 3954" } } }, | ||
| }; | ||
|
|
||
| #define NEVENTS (sizeof(events) / sizeof(evtimer_msg_event_t)) |
There was a problem hiding this comment.
static const unsigned int?
There was a problem hiding this comment.
Did not improve code-size either.
sys/evtimer/evtimer.c
Outdated
|
|
||
| _update_timer(evtimer); | ||
|
|
||
| if (!irq_is_in()) { |
There was a problem hiding this comment.
isn't this always called from isr?
|
Could you do some underflow testing, e.g., what happens when adding events with offset = 0 or 1, in a loop? Not sure xtimer will handle that case correctly. ;) |
Done, they fail ;-) [edit] for both 0 and 1 [/edit] |
Did you try with a message queue for the calling thread? If xtimer's failsafe kicked in (target too close), it would have triggered the timer right away, causing msg_send_int() to fail if there's no message queue. |
Did not, but have now (see last commit). Still failing. |
|
Let's try to merge this today. |
|
(timeouts of 0 and 1 are not planned for NDP) |
Wait a minute.... isn't |
|
Any decision on this PR (needed for the |
tests/evtimer_underflow/main.c
Outdated
| for (unsigned i = 0; i < NEVENTS; i++) { | ||
| evtimer_add_msg(&evtimer, &events[i], pid); | ||
| } | ||
| thread_yield(); |
There was a problem hiding this comment.
Did you try with a message queue for the calling thread? If xtimer's failsafe kicked in (target too close), it would have triggered the timer right away, causing msg_send_int() to fail if there's no message queue.
Did not, but have now (see last commit). Still failing.
@kaspar030 if I add this thread_yield() here however, it works. Isn't the sender supposed to yield if the receivers message queue is full anyway?
There was a problem hiding this comment.
Can you try replacing "msg_send_int()" in "_evtimer_msg_handler()" with "msg_try_send()"?
There was a problem hiding this comment.
Then I get (with the thread_yield() here removed):
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/evtimer_underflow/bin/native/tests_evtimer_msg.elf: thread_yield_higher: interrupts are disabled - this should not be
received msg "1"
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/evtimer_underflow/bin/native/tests_evtimer_msg.elf: thread_yield_higher: interrupts are disabled - this should not be
received msg "2"
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/evtimer_underflow/bin/native/tests_evtimer_msg.elf: thread_yield_higher: interrupts are disabled - this should not be
received msg "3"
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/evtimer_underflow/bin/native/tests_evtimer_msg.elf: thread_yield_higher: interrupts are disabled - this should not be
received msg "4"
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/evtimer_underflow/bin/native/tests_evtimer_msg.elf: thread_yield_higher: interrupts are disabled - this should not be
received msg "5"
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/evtimer_underflow/bin/native/tests_evtimer_msg.elf: thread_yield_higher: interrupts are disabled - this should not be
received msg "6"
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/evtimer_underflow/bin/native/tests_evtimer_msg.elf: thread_yield_higher: interrupts are disabled - this should not be
received msg "7"
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/evtimer_underflow/bin/native/tests_evtimer_msg.elf: thread_yield_higher: interrupts are disabled - this should not be
received msg "8"
...
There was a problem hiding this comment.
Hmshit. Please try reverting to msg_send_int(), then add if (sched_context_switch_request) { thread_yield_higher(); } after the irq_disable() in evtimer_add().
There was a problem hiding this comment.
After irq_disable()? Wouldn't that result in the same message as above? Or did you mean after irq_restore()?
|
@miri64 or @kaspar030 could you briefly summarize the current state of this PR? There are a lot of comments up there and I am currently too tired and too lazy to read them all (: Since this new feature is needed by the new NDP implementation, we should put more focus to get this into decent shape quickly. |
Apart from possible formalities, there's a problem when setting very short (e.g., zero or 1) offsets. |
sys/evtimer/evtimer.c
Outdated
| void evtimer_add(evtimer_t *evtimer, evtimer_event_t *event) | ||
| { | ||
| unsigned state = irq_disable(); | ||
| unsigned int context_switch_request; |
There was a problem hiding this comment.
To not access the volatile variable during a potential context change.
There was a problem hiding this comment.
(don't know if that might be bad for this particular variable. You decide ;-))
|
Fixed doc errors reported by Murdock |
|
Ping @kaspar030? |
|
please squash! |
|
Squashed... since this was a little bit more complicated than anticipated: |
f7d885a to
0f39c55
Compare
|
Both Murdocks are happy :-) |
Extends #5999 by doc, some helpers for message-based events and a test. Also rebases it to current master.