rt-thread icon indicating copy to clipboard operation
rt-thread copied to clipboard

rt_schedule中need_insert_from_thread的问题

Open blta opened this issue 3 years ago • 3 comments

            to_thread = _scheduler_get_highest_priority_thread(&highest_ready_priority);
            if ((rt_current_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_RUNNING)
            {
                if (rt_current_thread->current_priority < highest_ready_priority)
                {
                    to_thread = rt_current_thread;
                }
                else if (rt_current_thread->current_priority == highest_ready_priority && (rt_current_thread->stat & RT_THREAD_STAT_YIELD_MASK) == 0)
                {
                    to_thread = rt_current_thread;
                }
                else
                {
                    need_insert_from_thread = 1;
                }
                rt_current_thread->stat &= ~RT_THREAD_STAT_YIELD_MASK;
            }

在rt_schedule种有这一段关于YIELD的处理,在else条件里包含了下面这种情况

if (rt_current_thread->current_priority > highest_ready_priority && (rt_current_thread->stat & RT_THREAD_STAT_YIELD_MASK) == 0)

即新就绪的任务优先级大于当前任务,但当前任务的tick还没有用完, 这时需要切换,并把当前任务插入到其优先级就绪列表

                if (need_insert_from_thread)
                {
                    rt_schedule_insert_thread(from_thread);
                }

根据need_insert_from_thread把当前任务插入到其优先级list的前面,即最后一个。这样做,是不是对其太不公平? 毕竟是高优先级的任务打断了它,应该使用rt_list_insert_after把它插在list->next位置,下次轮到该优先级时,首先执行,直到其时间片用完! More info, refer to https://club.rt-thread.org/ask/question/67e5da9b4f0149e7.html

blta avatar May 16 '22 02:05 blta

可否提一个PR?

mysterywolf avatar May 16 '22 02:05 mysterywolf

可以的,如果只是单纯地加一个rt_schedule_insert_thread_next,确实可以解决 但总感觉调度还是太冗余的,我准备优化一下调度策略:

  1. 把running thread保留在readylist,只是状态位发生变化
  2. 如果最高的任务处于YIELD状态, list后移一次(6次指针移动)
  3. 上诉操作后会保证_scheduler_get_highest_priority_thread返回的就是需要的to_read:
  • 不需要条件判断了,
  • 也不需要need_insert_from_thread标记
  1. 后面在switch前更新一下状态:如果from_thread == to_thread, to_thread状态为 running; 否则from_thread的状态为ready, to_thread状态为 running;
  • rt_schedule_remove_thread也不需要在调度器里使用了,只有因延时,资源阻塞时才会从readylist移除

这样会简化很多,不存在来回remove ,insert问题,顺便把这个问题也解决了。 @mysterywolf 帮忙看看有没有问题

blta avatar May 16 '22 03:05 blta

@Guozhanxin 郭老师麻烦看看😁

mysterywolf avatar May 16 '22 03:05 mysterywolf

你好请ping我一下邮箱 我拉你进群 [email protected]

mysterywolf avatar Sep 13 '22 19:09 mysterywolf