3030 * 2022-01-07 Gabriel Moving __on_rt_xxxxx_hook to scheduler.c
3131 * 2023-03-27 rose_man Split into scheduler upc and scheduler_mp.c
3232 * 2023-10-17 ChuShicheng Modify the timing of clearing RT_THREAD_STAT_YIELD flag bits
33+ * 2025-08-04 Pillar Add rt_scheduler_critical_switch_flag
3334 */
3435
3536#define __RT_IPC_SOURCE__
@@ -51,6 +52,11 @@ extern volatile rt_atomic_t rt_interrupt_nest;
5152static rt_int16_t rt_scheduler_lock_nest ;
5253rt_uint8_t rt_current_priority ;
5354
55+ static rt_int8_t rt_scheduler_critical_switch_flag ;
56+ #define IS_CRITICAL_SWITCH_PEND () (rt_scheduler_critical_switch_flag == 1)
57+ #define SET_CRITICAL_SWITCH_FLAG () (rt_scheduler_critical_switch_flag = 1)
58+ #define CLR_CRITICAL_SWITCH_FLAG () (rt_scheduler_critical_switch_flag = 0)
59+
5460#if defined(RT_USING_HOOK ) && defined(RT_HOOK_USING_FUNC_PTR )
5561static void (* rt_scheduler_hook )(struct rt_thread * from , struct rt_thread * to );
5662static void (* rt_scheduler_switch_hook )(struct rt_thread * tid );
@@ -236,6 +242,9 @@ void rt_system_scheduler_start(void)
236242
237243 rt_cpu_self ()-> current_thread = to_thread ;
238244
245+ /* flush critical switch flag */
246+ CLR_CRITICAL_SWITCH_FLAG ();
247+
239248 rt_sched_remove_thread (to_thread );
240249 RT_SCHED_CTX (to_thread ).stat = RT_THREAD_RUNNING ;
241250
@@ -387,6 +396,10 @@ void rt_schedule(void)
387396 }
388397 }
389398 }
399+ else
400+ {
401+ SET_CRITICAL_SWITCH_FLAG ();
402+ }
390403
391404 /* enable interrupt */
392405 rt_hw_interrupt_enable (level );
@@ -604,6 +617,7 @@ void rt_exit_critical_safe(rt_base_t critical_level)
604617
605618/**
606619 * @brief Safely exit critical section (non-debug version)
620+ * If the scheduling function is called before exiting, it will be scheduled in this function.
607621 *
608622 * @param critical_level The expected critical level (unused in non-debug build)
609623 *
@@ -657,6 +671,7 @@ RTM_EXPORT(rt_enter_critical);
657671
658672/**
659673 * @brief Exit critical section and unlock scheduler
674+ * If the scheduling function is called before exiting, it will be scheduled in this function.
660675 *
661676 * @details This function:
662677 * - Decrements the scheduler lock nesting count
@@ -685,9 +700,10 @@ void rt_exit_critical(void)
685700 /* enable interrupt */
686701 rt_hw_interrupt_enable (level );
687702
688- if (rt_current_thread )
703+ if (IS_CRITICAL_SWITCH_PEND () )
689704 {
690- /* if scheduler is started, do a schedule */
705+ CLR_CRITICAL_SWITCH_FLAG ();
706+ /* if scheduler is started and needs to be scheduled, do a schedule */
691707 rt_schedule ();
692708 }
693709 }
0 commit comments