-
Notifications
You must be signed in to change notification settings - Fork 2.1k
evtimer: initial import #6767
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
evtimer: initial import #6767
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
close instead of near?
sys/include/evtimer.h
Outdated
evtimer_event_t *events; /**< Event queue */ | ||
} evtimer_t; | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about moving all msg related stuff into "evtimer_msg.h"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to evtimer/msg.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's still a #include "msg.h"
in this file :-)
That is indeed weird. |
Addressed comments. |
sys/include/evtimer.h
Outdated
evtimer_event_t *events; /**< Event queue */ | ||
} evtimer_t; | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's still a #include "msg.h"
in this file :-)
sys/include/evtimer/msg.h
Outdated
#ifndef EVTIMER_MSG_H | ||
#define EVTIMER_MSG_H | ||
|
||
#include "evtimer.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing #include "msg.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. |
sys/include/evtimer/msg.h
Outdated
* @extends evtimer_t | ||
*/ | ||
typedef evtimer_t evtimer_msg_t; | ||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uh, newline missing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static const unsigned int?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? I use it one time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this always called from isr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is your code ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adressed
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you try replacing "msg_send_int()" in "_evtimer_msg_handler()" with "msg_try_send()"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After irq_disable()
? Wouldn't that result in the same message as above? Or did you mean after irq_restore()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(that works btw).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my latest commits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I meant 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the copy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To not access the volatile variable during a potential context change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(don't know if that might be bad for this particular variable. You decide ;-))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should work without.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
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.