From cc4d1bd3747050e2801345ca104b472dbe617ca5 Mon Sep 17 00:00:00 2001 From: Florian Grandel Date: Mon, 28 Aug 2023 17:31:54 +0200 Subject: [PATCH] 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 --- include/zephyr/kernel_structs.h | 3 ++- kernel/sched.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index 146f6d90281..aa1379d66af 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -114,7 +114,8 @@ struct _cpu { struct _ready_q ready_q; #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 */ struct k_thread *metairq_preempted; #endif diff --git a/kernel/sched.c b/kernel/sched.c index 10fd3f07c80..fcd77c69eb7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -66,6 +66,11 @@ static inline int is_preempt(struct k_thread *thread) 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) { #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(); -#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 * cooperative thread they preempted and not whatever happens * 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) { -#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) && !is_preempt(_current)) { /* Record new preemption */