sys: add asynchronous event system#6000
Conversation
|
PR #6000 🎉 |
|
Are there still plans on your side to merge this with the event timer in #5999? |
|
yes, but I wanted to get this PR'ed for numerological reasons. ;) -----Original Message----- Are there still plans on your side to merge this with the event timer in #5999? You are receiving this because you authored the thread. |
|
As talked offline, this PR would be very useful for integrating events into SAUL! @kaspar030: would you mind to
|
|
Postponed due to feature freeze. |
|
Any plans to further work on this? |
|
Yes! I've been using it for the latest jerryscript work. I'll update this PR soon. |
e4351af to
3c1d721
Compare
|
This is ready for review. |
This PR contains some code for timing events, but for now they're xtimer based. If we see it would make sense, we can extend or modify later. |
Done.
Done. |
|
|
||
| /** | ||
| * @ingroup sys_event | ||
| * @brief Provides functionality to trigger events after timeout |
There was a problem hiding this comment.
Question for clarification: Is this to replace evtimer?
There was a problem hiding this comment.
Nope. This is so that users of the event module can also have timed events. It would probably be a good idea to implement event_timer_t on top of evtimer. The similarity of the names is unfortunately confusing...
There was a problem hiding this comment.
Well this PR provides an event queue implementation, evtimer is a timed event queue. Shouldn't there be some way to merge them? What is event_timer_t?
There was a problem hiding this comment.
There is, maybe, but not a trivial one... Also, the use-cases are quite different. evtimer basically runs thread-independent, with it's event handlers being run in ISR context.
This event queue is much more under user control.
What is event_timer_t?
I meant event_timeout_t, the method of haveing timed events within event queues.
sys/include/event.h
Outdated
| * one thread, e.g., in order to create a state-machine like process flow. | ||
| * This is not (easily) possible using msg queues, as they might fill up. | ||
| * 4. an event can only be queued in one event queue at the same time. | ||
| * Notifying many queues using only one event object is impossible. |
There was a problem hiding this comment.
Wording: I doubt the impossibility of this. I might however be convinced that it is not possible with this implementation.
sys/include/event.h
Outdated
| /** | ||
| * @brief Thread flag use to notify available events in an event queue | ||
| */ | ||
| #define THREAD_FLAG_EVENT 0x1 |
There was a problem hiding this comment.
Params? Also, not sure how flag colisions are handled in thread_flags in general.
There was a problem hiding this comment.
I thought about it... making this configurable per queue adds 33% to the queue structure's size...
I hoped that we can get by with one queue per thread, in which case a globally configurable constant might be ok...
OK to leave as is and gather experience?
There was a problem hiding this comment.
Params?
That was a typo... what I meant was "parans" ;-). As such I think you misunderstood the second half: I'm actually not sure if other modules using thread_flags won't collide with the flag you define here, so can you put my mind here at ease?
There was a problem hiding this comment.
parans
fixed
I'm actually not sure if other modules using thread_flags won't collide with the flag you define here, so can you put my mind here at ease?
Maybe half. :) Users of thread_flags might actually collide by using the same thread flag. I don't see that as a huge problem (unlike crashing msg ids), as thread flags are supposed to be used in a "notifying" way, meaning "there might be something you might want to look at".
As said, I'd like to gather some experience before deciding whether the flag number needs to be changed and/or made configurable.
sys/include/event.h
Outdated
| * | ||
| * This will set the calling thread as owner of @p queue. | ||
| * | ||
| * @param[in,out] queue event queue object to initialize |
There was a problem hiding this comment.
I would argue it is just an out parameter. Or are there any fields required to be set before initialization.
sys/include/event.h
Outdated
| * | ||
| * Examples: | ||
| * | ||
| * // simple event handler |
There was a problem hiding this comment.
Guard with
~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
...
~~~~~~~~~~~~~~~~~~~~~~~~~~~
for maximum syntax flavor ;-)
sys/include/event.h
Outdated
| * | ||
| * It is pretty much defined as: | ||
| * | ||
| * while((event = event_wait(queue))) { |
There was a problem hiding this comment.
Use C-fences?
~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
...
~~~~~~~~~~~~~~~~~~~~~~~~~~~
| @@ -0,0 +1,80 @@ | |||
| /* | |||
There was a problem hiding this comment.
Please add a readme and/or a pexpect script.
3c1d721 to
65c5cee
Compare
9b50069 to
572bdc4
Compare
|
(I had a rebase mishap, that's fixed now)
|
miri64
left a comment
There was a problem hiding this comment.
Final review. Apart from a few nits in style and wording:
- I'm not happy about the usage of implicit sub-modules, better use explicit ones.
event_timeoutwork on a microsecond scale, so why are their tests on a second scale. Wastes time during testing ;-).
| @@ -0,0 +1,5 @@ | |||
| SRC := event.c | |||
|
|
|||
| SUBMODULES = 1 | |||
There was a problem hiding this comment.
I don't think that this is managed pretty transparent here. For core I was understanding of that, but in sys the sub-folders for sub-modules is already established (also you don't need pseudo-modules then ;-)).
There was a problem hiding this comment.
I don't understand transparent.
Using submodules here saves two folders and two makefiles with 2 lines each.
There was a problem hiding this comment.
But makes it harder for newcomers to understand what to include ... (that's what I meant with transparent)
sys/event/callback.c
Outdated
| event_callback->callback(event_callback->arg); | ||
| } | ||
|
|
||
| void event_callback_init(event_callback_t *event_callback, void (callback)(void*), void *arg) |
sys/event/callback.c
Outdated
| event_callback->callback(event_callback->arg); | ||
| } | ||
|
|
||
| void event_callback_init(event_callback_t *event_callback, void (callback)(void*), void *arg) |
There was a problem hiding this comment.
Missing space in-between void* in the callback parameter.
sys/event/timeout.c
Outdated
|
|
||
| #include "event/timeout.h" | ||
|
|
||
| static void _event_timeout_callback(void* arg) |
sys/include/event.h
Outdated
| * @ingroup sys | ||
| * @brief Provides an Event loop | ||
| * | ||
| * This module offers an event queue framework not unlike libevent or libuev. |
There was a problem hiding this comment.
Maybe make it a little easier on non-native speakers and remove the double negative.
| */ | ||
| typedef struct { | ||
| event_t super; /**< event_t structure that gets extended */ | ||
| void (*callback)(void*); /**< callback function */ |
sys/include/event/callback.h
Outdated
| * @param[in] callback callback to set up | ||
| * @param[in] arg callback argument to set up | ||
| */ | ||
| void event_callback_init(event_callback_t *event_callback, void (*callback)(void*), void *arg); |
sys/include/event/callback.h
Outdated
| * @param[in] callback callback to set up | ||
| * @param[in] arg callback argument to set up | ||
| */ | ||
| void event_callback_init(event_callback_t *event_callback, void (*callback)(void*), void *arg); |
There was a problem hiding this comment.
Remove one space before void *arg
sys/include/event/callback.h
Outdated
| { \ | ||
| .super.handler=_event_callback_handler, \ | ||
| .callback=_cb, \ | ||
| .arg=(void*)_arg \ |
tests/events/main.c
Outdated
| printf("posting timed callback with timeout 1sec\n"); | ||
| event_timeout_init(&event_timeout, &queue, (event_t*)&event_callback); | ||
| before = xtimer_now_usec(); | ||
| event_timeout_set(&event_timeout, 1000000); |
There was a problem hiding this comment.
I think this can be smaller by at least one magnitude (maybe 100000).
miri64
left a comment
There was a problem hiding this comment.
Running uncrustify over your code revealed some more minor coding-style related issues.
sys/include/event/callback.h
Outdated
| { \ | ||
| .super.handler=_event_callback_handler, \ | ||
| .callback=_cb, \ | ||
| .arg=(void*)_arg \ |
There was a problem hiding this comment.
Please add spaces before and after the =s
sys/event/event.c
Outdated
| void event_loop(event_queue_t *queue) | ||
| { | ||
| event_t *event; | ||
| while((event = event_wait(queue))) { |
tests/events/main.c
Outdated
|
|
||
|
|
||
| static event_t event = { .handler=callback }; | ||
| static event_t event2 = { .handler=callback }; |
There was a problem hiding this comment.
spaces missing around inner assignments.
tests/events/main.c
Outdated
| { | ||
| puts("[START] event test application.\n"); | ||
|
|
||
| event_queue_t queue = { .waiter=(thread_t*)sched_active_thread }; |
There was a problem hiding this comment.
Spaces missing around inner assignment
tests/events/main.c
Outdated
| const char *text; | ||
| } custom_event_t; | ||
|
|
||
| static custom_event_t custom_event = { .super.handler=custom_callback, .text="CUSTOM CALLBACK" }; |
tests/events/main.c
Outdated
| event_timeout_t event_timeout; | ||
|
|
||
| printf("posting timed callback with timeout 1sec\n"); | ||
| event_timeout_init(&event_timeout, &queue, (event_t*)&event_callback); |
sys/include/event.h
Outdated
| * | ||
| * This will remove a queued event from an event queue. | ||
| * | ||
| * @note: due to the underlying list implementation, this will run in O(n). |
miri64
left a comment
There was a problem hiding this comment.
I think this will be my last comment ^^"
sys/include/event.h
Outdated
| * printf("triggered custom event with text: \"%s\"\n", custom_event->text); | ||
| * } | ||
| * | ||
| * static custom_event_t custom_event = { .super.callback=custom_handler, .text="CUSTOM EVENT" }; |
sys/include/event.h
Outdated
| * printf("triggered 0x%08x\n", (unsigned)event); | ||
| * } | ||
| * | ||
| * static event_t event = { .handler=handler }; |
There was a problem hiding this comment.
Sorry, only noticed this during reading the parsed doc: spaces around inner =
|
@miri64 sorry for all the style errors.
Hm. Using submodules saves two folders and two Makefiles. Can we merge as is and discuss whether submodules should be used out of this PR?
Good idea. Done. |
Begrudgingly... |
|
Please squash |
|
PR #6000 now has 666 additions. That alone is a reason against the explicit submodules, for now ^^ |
bcfa7e3 to
27cdd54
Compare
|
and go |
|
Thanks for reviewing! |

I've been playing around with asynchronous event (callbacks). This is my current code, which I think might make it possible to write more predictable asynchronous applications, compared to using message queues.
PR'ing it now so others can take an early look.