diff --git a/os/kernel/sched/Make.defs b/os/kernel/sched/Make.defs index 4f21f4b518..af9fde591d 100644 --- a/os/kernel/sched/Make.defs +++ b/os/kernel/sched/Make.defs @@ -62,6 +62,10 @@ CSRCS += sched_lock.c sched_unlock.c sched_lockcount.c sched_self.c CSRCS += sched_getaffinity.c sched_setaffinity.c CSRCS += sched_getcpu.c +ifeq ($(CONFIG_SW_STACK_OVERFLOW_DETECTION),y) +CSRCS += sched_checkstackoverflow.c +endif + ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) CSRCS += sched_reprioritize.c endif diff --git a/os/kernel/sched/sched.h b/os/kernel/sched/sched.h index f20d439d58..9cb1589d91 100644 --- a/os/kernel/sched/sched.h +++ b/os/kernel/sched/sched.h @@ -358,6 +358,10 @@ void sched_addblocked(FAR struct tcb_s *btcb, tstate_t task_state); void sched_removeblocked(FAR struct tcb_s *btcb); int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority); +#ifdef CONFIG_SW_STACK_OVERFLOW_DETECTION +void sched_checkstackoverflow(FAR struct tcb_s *rtcb); +#endif + #ifdef CONFIG_PRIORITY_INHERITANCE int sched_reprioritize(FAR struct tcb_s *tcb, int sched_priority); #else diff --git a/os/kernel/sched/sched_addreadytorun.c b/os/kernel/sched/sched_addreadytorun.c index 15547d21ba..a133be8670 100644 --- a/os/kernel/sched/sched_addreadytorun.c +++ b/os/kernel/sched/sched_addreadytorun.c @@ -124,14 +124,7 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) bool ret; #ifdef CONFIG_SW_STACK_OVERFLOW_DETECTION - if (*(uint32_t *)(rtcb->stack_base_ptr) != STACK_COLOR) { - dbg_noarg("############### STACK OVERFLOW at pid %d ", rtcb->pid); -#if CONFIG_TASK_NAME_SIZE > 0 - dbg_noarg("(%s) ", rtcb->name); -#endif - dbg_noarg("###################\n"); - PANIC(); - } + sched_checkstackoverflow(rtcb); #endif /* Check if pre-emption is disabled for the current running task and if * the new ready-to-run task would cause the current running task to be @@ -182,14 +175,7 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) int cpu; #ifdef CONFIG_SW_STACK_OVERFLOW_DETECTION - if (*(uint32_t *)(rtcb->stack_base_ptr) != STACK_COLOR) { - dbg_noarg("############### STACK OVERFLOW at pid %d ", rtcb->pid); -#if CONFIG_TASK_NAME_SIZE > 0 - dbg_noarg("(%s) ", rtcb->name); -#endif - dbg_noarg("###################\n"); - PANIC(); - } + sched_checkstackoverflow(rtcb); #endif /* Check if the blocked TCB is locked to this CPU */ diff --git a/os/kernel/sched/sched_checkstackoverflow.c b/os/kernel/sched/sched_checkstackoverflow.c new file mode 100644 index 0000000000..b682800266 --- /dev/null +++ b/os/kernel/sched/sched_checkstackoverflow.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * + * Copyright 2025 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include + +#include "sched/sched.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sched_checkstackoverflow + * + * Description: + * This function checks stack overflow condition for a thread. + * + * Inputs: + * rtcb - Points to the TCB that is ready-to-run + * + ****************************************************************************/ + +void sched_checkstackoverflow(FAR struct tcb_s *rtcb) +{ + irqstate_t flags = enter_critical_section(); + + if (*(uint32_t *)(rtcb->stack_base_ptr) != STACK_COLOR) { + lldbg_noarg("\n############### STACK OVERFLOW at pid %d ", rtcb->pid); +#if CONFIG_TASK_NAME_SIZE > 0 + lldbg_noarg("(%s) ", rtcb->name); +#endif + lldbg_noarg("###################\n"); + PANIC(); + } + + leave_critical_section(flags); +} diff --git a/os/kernel/sched/sched_removereadytorun.c b/os/kernel/sched/sched_removereadytorun.c index 0b3dfd3cc4..363473690d 100644 --- a/os/kernel/sched/sched_removereadytorun.c +++ b/os/kernel/sched/sched_removereadytorun.c @@ -116,15 +116,9 @@ bool sched_removereadytorun(FAR struct tcb_s *rtcb) bool ret = false; #ifdef CONFIG_SW_STACK_OVERFLOW_DETECTION - if (*(uint32_t *)(rtcb->stack_base_ptr) != STACK_COLOR) { - dbg_noarg("############### STACK OVERFLOW at pid %d ", rtcb->pid); -#if CONFIG_TASK_NAME_SIZE > 0 - dbg_noarg("(%s) ", rtcb->name); -#endif - dbg_noarg("###################\n"); - PANIC(); - } + sched_checkstackoverflow(rtcb); #endif + /* Check if the TCB to be removed is at the head of the ready to run list. * In this case, we are removing the currently active task. */ @@ -157,15 +151,9 @@ bool sched_removereadytorun(FAR struct tcb_s *rtcb) int cpu; #ifdef CONFIG_SW_STACK_OVERFLOW_DETECTION - if (*(uint32_t *)(rtcb->stack_base_ptr) != STACK_COLOR) { - dbg_noarg("############### STACK OVERFLOW at pid %d ", rtcb->pid); -#if CONFIG_TASK_NAME_SIZE > 0 - dbg_noarg("(%s) ", rtcb->name); -#endif - dbg_noarg("###################\n"); - PANIC(); - } + sched_checkstackoverflow(rtcb); #endif + /* Which CPU (if any) is the task running on? Which task list holds * the TCB */