* @brief Perform thread scheduling once. Select the highest priority thread and switch to it. * * @details This function: * - Disables interrupts to prevent preemption during scheduling * - Checks if scheduler is enabled (lock_nest == 0) * - Gets the highest priority ready thread * - Determines if current thread should continue running or be preempted * - Performs context switch i
| 280 | * - Handles thread yield flags and signal processing |
| 281 | */ |
| 282 | void rt_schedule(void) |
| 283 | { |
| 284 | rt_base_t level; |
| 285 | struct rt_thread *to_thread; |
| 286 | struct rt_thread *from_thread; |
| 287 | struct rt_thread *curr_thread; |
| 288 | |
| 289 | /* disable interrupt */ |
| 290 | level = rt_hw_interrupt_disable(); |
| 291 | |
| 292 | /* using local variable to avoid unnecessary function call */ |
| 293 | curr_thread = rt_thread_self(); |
| 294 | |
| 295 | /* check the scheduler is enabled or not */ |
| 296 | if (rt_scheduler_lock_nest == 0) |
| 297 | { |
| 298 | rt_ubase_t highest_ready_priority; |
| 299 | |
| 300 | if (rt_thread_ready_priority_group != 0) |
| 301 | { |
| 302 | /* need_insert_from_thread: need to insert from_thread to ready queue */ |
| 303 | int need_insert_from_thread = 0; |
| 304 | |
| 305 | to_thread = _scheduler_get_highest_priority_thread(&highest_ready_priority); |
| 306 | |
| 307 | if ((RT_SCHED_CTX(curr_thread).stat & RT_THREAD_STAT_MASK) == RT_THREAD_RUNNING) |
| 308 | { |
| 309 | if (RT_SCHED_PRIV(curr_thread).current_priority < highest_ready_priority) |
| 310 | { |
| 311 | to_thread = curr_thread; |
| 312 | } |
| 313 | else if (RT_SCHED_PRIV(curr_thread).current_priority == highest_ready_priority |
| 314 | && (RT_SCHED_CTX(curr_thread).stat & RT_THREAD_STAT_YIELD_MASK) == 0) |
| 315 | { |
| 316 | to_thread = curr_thread; |
| 317 | } |
| 318 | else |
| 319 | { |
| 320 | need_insert_from_thread = 1; |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | if (to_thread != curr_thread) |
| 325 | { |
| 326 | /* if the destination thread is not the same as current thread */ |
| 327 | rt_current_priority = (rt_uint8_t)highest_ready_priority; |
| 328 | from_thread = curr_thread; |
| 329 | rt_cpu_self()->current_thread = to_thread; |
| 330 | |
| 331 | RT_OBJECT_HOOK_CALL(rt_scheduler_hook, (from_thread, to_thread)); |
| 332 | |
| 333 | if (need_insert_from_thread) |
| 334 | { |
| 335 | rt_sched_insert_thread(from_thread); |
| 336 | } |
| 337 | |
| 338 | if ((RT_SCHED_CTX(from_thread).stat & RT_THREAD_STAT_YIELD_MASK) != 0) |
| 339 | { |