sys: add shared event threads#12474
Conversation
|
With per-thread stack sizes, the array is not so simple anymore ;(. The ifdef based configuration looks quite ugly. |
|
Hi @kaspar030 AFAIS this is a follow up of #12459 (support for multiple threads using events). The mechanism is exactly the same. The event_thread module is a tasklets implementation. Why don't we continue the discussion in #12459 first instead of opening a PR with the same principle? Or is this intended to be just a PoC? |
Well, my whole point is that "tasklets" are just event loops in dedicated threads. IMO that doesn't justify a new API. So yes, this is a PoC. |
|
As suggested, lets continue the discussion in #12459 for now. |
|
The implementations of both the tasklet/irq_handler and the shared event thread only differ very little, as they both spawn (a) worker thread(s) that work on event queues. This are the differences:
For end users the option to having a |
|
To be more concrete maybe a sketch of adding the typedef struct {
even_t event;
void *arg;
} event_with_arg_t;
static inline void event_post_with_arg(event_with_arg_t *ev, void *arg)
{
unsigned state = irq_disable();
ev->arg = arg;
event_post(&ev->event);
irq_restore(state);
}
static inline void *event_get_arg(event_t *event_with_arg)
{
event_with_arg_t *ev = (event_with_arg_t *)event_with_arg;
return ev->arg;
}This might be a bit more accessible for application developers if they actually need a |
Its already there for quite a while: |
|
OK. Then there is no need to for an additional API. |
We getting closer to the point that @kaspar030 was raising in the first place :-) |
|
@kaspar030: Mind to steal the idea of using |
See #12459 (comment) That's my point of view. But of course, that doesn't affect the way the modules work nor the problems we are trying to solve. So, I'm fine with how most people want to proceed ;) |
I think it is not that easy, as #12480 defines the stacks within the header. If we ensure that it is only included from event_threads.c, that is ok, otherwise we'll have multiple definitions. |
| #define EVENT_THREAD_LOWEST_STACKSIZE ISR_STACKSIZE | ||
| #endif | ||
| #ifndef EVENT_THREAD_LOWEST_PRIO | ||
| #define EVENT_THREAD_LOWEST_PRIO (THREAD_PRIORITY_IDLE - 1) |
There was a problem hiding this comment.
We would have at most exactly two priorities and two threads, right? Shouldn't the lowest thread priority be (THREAD_PRIORITY_MAIN - 1)? Otherwise drivers would have to use again the high priority thread to ensure that their events are at least handled before the main thread is executed.
There was a problem hiding this comment.
Otherwise drivers would have to use again the high priority thread to ensure that their events are at least handled before the main thread is executed.
Maybe they want to, as in, "do this when there is time". That's why I've made it just one higher than idle.
How about I add a third priority ("medium"), which is just one higher than main? Or does the current very-low one make sense at all?
I mean, this is just the auto configuration, cpus / boards / applications can freely launch more handler threads...
There was a problem hiding this comment.
How about I add a third priority ("medium"), which is just one higher than main? Or does the current very-low one make sense at all?
What priority should a thread have that is used by a driver to handle an interrupt from the hardware? IMHO, its priority should be at least higher than the priority of the main thread. A medium priority thread seems to be more important than a very low priority thread.
I mean, this is just the auto configuration, cpus / boards / applications can freely launch more handler threads...
Yes of course, but drivers can only use threads that are known from the auto configuration. Otherwise, they would need an additional thread parameter for the initializtion. This in turn would prevent the auto initialization.
There was a problem hiding this comment.
What priority should a thread have that is used by a driver to handle an interrupt from the hardware?
I guess that depends... It is easy to add more priorities, so I propose I add one more middle priority (one higher than main) and see how far we go with that.
There was a problem hiding this comment.
👍 The three priorities high (0), medium (main-1) and low (idle-1) probably meet the requirements of most use cases.
There was a problem hiding this comment.
added medium priority
|
(I copy&paste the comment from #12480 to continue the discussion here) I think having multiple queues for now is a good approach. Eventually everything could be represented with a couple of queues, but this gives as a lot of flexibility for now. So, this gives the developer the mechanism to adapt the OS depending of the real time requirements. |
|
can we continue with this? The netif rework is waiting for a feature for handling radio events from within the OS (: |
0eaf8bd to
3581aef
Compare
I've added a test script for the test application and license / doxygen to the main code. |
|
|
@jia200x want to take another look? |
| @@ -0,0 +1,5 @@ | |||
| include ../Makefile.tests_common | |||
|
|
|||
| USEMODULE += event_thread_highest event_thread_medium event_thread_lowest | |||
There was a problem hiding this comment.
Can we define these as configuration values (CFLAGS) that depend on the module "event_thread"? Otherwise it's hard to configure it using Kconfig.
|
Code-wise looks OK. Same for the fundamentals. I only have some comments regarding the "event_thread_***" pseudomodules. Also, it would be great if you can add the Kconfig file for this module. |
Would you be OK with keeping Kconfig out of this PR for now? Kconfig is quite new to me... |
Ok, let's do it in a follow up then |
|
@maribu @gschorcht @jia200x I think all comments (apart from Kconfig) were addressed. Mind to take another look? |
maribu
left a comment
There was a problem hiding this comment.
ACK. Very nicely boiled down the idea to small and maintainable code :-)
Some boards have to little RAM to compile the test and there is still a bug in the LPC2387 CPU (ISR_STACKSIZE is defined as ((unsigned) &__stack_irq_size), which is a super strange construct; why should an address of a variable be considered to be a size?). I suggest to blacklist that CPU for now, until that issue is fixed. (I could do so, unless @benpicco is faster ;-))
|
ACK from my side, please squash. |
c968784 to
9a93805
Compare
yup, added them to Makefile.ci.
Yeah, the linker can only provide addresses, but arbitrary values in those... I've adde arch_arm7 to FEATURES_BLACKLIST. |
|
|
All lights are green, let's go. |
|
@kaspar030 Thanks for the contribution. @maribu We should restart with the process you tried in PR #12486. |
|
Thanks everyone! |
Contribution description
Following the discussion in #12459, this PR shows how shared event threads could be implemented using sys/event.
This is basically a refactored version of https://github.com/haukepetersen/RIOT/tree/add_eventhandlerthread.
Testing procedure
Issues/PRs references