kernel: sched: optimize for Meta IRQs == coop prios
Combining Meta IRQs with cooperative threads requires extra care to return to pre-empted cooperative threads when returning from a Meta IRQ. This is only needed when there are cooperative threads that are not also Meta IRQs. This PR saves some space & time when the number of Meta IRQs is equal to the number of available cooperative threads. Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
This commit is contained in:
parent
0bfd20567f
commit
cc4d1bd374
2 changed files with 11 additions and 3 deletions
|
@ -114,7 +114,8 @@ struct _cpu {
|
||||||
struct _ready_q ready_q;
|
struct _ready_q ready_q;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && (CONFIG_NUM_COOP_PRIORITIES > 0)
|
#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && \
|
||||||
|
(CONFIG_NUM_COOP_PRIORITIES > CONFIG_NUM_METAIRQ_PRIORITIES)
|
||||||
/* Coop thread preempted by current metairq, or NULL */
|
/* Coop thread preempted by current metairq, or NULL */
|
||||||
struct k_thread *metairq_preempted;
|
struct k_thread *metairq_preempted;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -66,6 +66,11 @@ static inline int is_preempt(struct k_thread *thread)
|
||||||
return thread->base.preempt <= _PREEMPT_THRESHOLD;
|
return thread->base.preempt <= _PREEMPT_THRESHOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BUILD_ASSERT(CONFIG_NUM_COOP_PRIORITIES >= CONFIG_NUM_METAIRQ_PRIORITIES,
|
||||||
|
"You need to provide at least as many CONFIG_NUM_COOP_PRIORITIES as "
|
||||||
|
"CONFIG_NUM_METAIRQ_PRIORITIES as Meta IRQs are just a special class of cooperative "
|
||||||
|
"threads.");
|
||||||
|
|
||||||
static inline int is_metairq(struct k_thread *thread)
|
static inline int is_metairq(struct k_thread *thread)
|
||||||
{
|
{
|
||||||
#if CONFIG_NUM_METAIRQ_PRIORITIES > 0
|
#if CONFIG_NUM_METAIRQ_PRIORITIES > 0
|
||||||
|
@ -322,7 +327,8 @@ static ALWAYS_INLINE struct k_thread *next_up(void)
|
||||||
|
|
||||||
struct k_thread *thread = runq_best();
|
struct k_thread *thread = runq_best();
|
||||||
|
|
||||||
#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && (CONFIG_NUM_COOP_PRIORITIES > 0)
|
#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && \
|
||||||
|
(CONFIG_NUM_COOP_PRIORITIES > CONFIG_NUM_METAIRQ_PRIORITIES)
|
||||||
/* MetaIRQs must always attempt to return back to a
|
/* MetaIRQs must always attempt to return back to a
|
||||||
* cooperative thread they preempted and not whatever happens
|
* cooperative thread they preempted and not whatever happens
|
||||||
* to be highest priority now. The cooperative thread was
|
* to be highest priority now. The cooperative thread was
|
||||||
|
@ -542,7 +548,8 @@ void z_time_slice(void)
|
||||||
*/
|
*/
|
||||||
static void update_metairq_preempt(struct k_thread *thread)
|
static void update_metairq_preempt(struct k_thread *thread)
|
||||||
{
|
{
|
||||||
#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && (CONFIG_NUM_COOP_PRIORITIES > 0)
|
#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && \
|
||||||
|
(CONFIG_NUM_COOP_PRIORITIES > CONFIG_NUM_METAIRQ_PRIORITIES)
|
||||||
if (is_metairq(thread) && !is_metairq(_current) &&
|
if (is_metairq(thread) && !is_metairq(_current) &&
|
||||||
!is_preempt(_current)) {
|
!is_preempt(_current)) {
|
||||||
/* Record new preemption */
|
/* Record new preemption */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue