MCPcopy Create free account
hub / github.com/RT-Thread/rt-thread / _prepare_context_switch_locked

Function _prepare_context_switch_locked

src/scheduler_mp.c:625–713  ·  view source on GitHub ↗

* @brief Pick the highest runnable thread, and pass the control to it * * @note caller should hold the scheduler context lock. lock will be released * before return from this routine */

Source from the content-addressed store, hash-verified

623 * before return from this routine
624 */
625static rt_thread_t _prepare_context_switch_locked(int cpu_id,
626 struct rt_cpu *pcpu,
627 rt_thread_t current_thread)
628{
629 rt_thread_t to_thread = RT_NULL;
630 rt_ubase_t highest_ready_priority;
631
632 /* quickly check if any other ready threads queuing */
633 if (rt_thread_ready_priority_group != 0 || pcpu->priority_group != 0)
634 {
635 /* pick the highest ready thread */
636 to_thread = _scheduler_get_highest_priority_thread(&highest_ready_priority);
637
638 /* detach current thread from percpu scheduling context */
639 RT_SCHED_CTX(current_thread).oncpu = RT_CPU_DETACHED;
640
641 /* check if current thread should be put to ready queue, or scheduling again */
642 if ((RT_SCHED_CTX(current_thread).stat & RT_THREAD_STAT_MASK) == RT_THREAD_RUNNING)
643 {
644 /* check if current thread can be running on current core again */
645 if (RT_SCHED_CTX(current_thread).bind_cpu == RT_CPUS_NR
646 || RT_SCHED_CTX(current_thread).bind_cpu == cpu_id)
647 {
648 /* if current_thread is the highest runnable thread */
649 if (RT_SCHED_PRIV(current_thread).current_priority < highest_ready_priority)
650 {
651 to_thread = current_thread;
652 }
653 /* or no higher-priority thread existed and it has remaining ticks */
654 else if (RT_SCHED_PRIV(current_thread).current_priority == highest_ready_priority &&
655 (RT_SCHED_CTX(current_thread).stat & RT_THREAD_STAT_YIELD_MASK) == 0)
656 {
657 to_thread = current_thread;
658 }
659 /* otherwise give out the core */
660 else
661 {
662 _sched_insert_thread_locked(current_thread);
663 }
664 }
665 else
666 {
667 /* put current_thread to ready queue of another core */
668 _sched_insert_thread_locked(current_thread);
669 }
670
671 /* consume the yield flags after scheduling */
672 RT_SCHED_CTX(current_thread).stat &= ~RT_THREAD_STAT_YIELD_MASK;
673 }
674
675 /**
676 * Now destination thread is determined, core is passed to it. Though
677 * the percpu scheduling context is not updated here, since the cpu
678 * is locked contiguously before all the scheduling works are done, it's
679 * safe to observe that current thread as the running thread on this
680 * core for any observers if they properly do the synchronization
681 * (take the SCHEDULER_LOCK).
682 */

Callers 3

rt_scheduleFunction · 0.85

Tested by

no test coverage detected