1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
RT-Thread支持时间片调度算法,相同优先级的thread按其设定的ticks 轮流执行。 先上rt_schedule代码 need_insert_from_thread 标志主要是用来标记是否从当前任务切换到其他任务,切出意味着需要把当前任务插入到对应优先级的readylist。 情况1 这个很好理解:没有和当前任务task1优先级相同的任务,其优先级readylist为空。 假如有一个低优先级task2任务, systic中断里 rt_timer_check()发现超时;或者资源就绪把它唤醒,都会发起一次调度,把它插入对应readylist,这时_scheduler_get_highest_priority_thread得到的是task2,无需切换。 或者当前任务时间片用完,主动发起调度,发现自己还是老大,那就继续运行吧 task主动调用rt_thread_yield,礼让CPU资源,结果和上面一样 情况2 假设还有一个task2和当前任务task1优先级相同, 同样可能因为超时;或者资源就绪把它唤醒,发起一次调度,把它插入对readylist。 这时task1的时间片还未用完,依旧无需切换,让它等着吧。 情况3 可以直接列出剩余的三种情况, 1) if (rt_current_thread->current_priority == highest_ready_priority && (rt_current_thread->stat & RT_THREAD_STAT_YIELD_MASK) != 0) 和情况2相同,当前任务的时间片用完了或者主动礼让,把自己插入对应readylist前 2) if (rt_current_thread->current_priority > highest_ready_priority && (rt_current_thread->stat & RT_THREAD_STAT_YIELD_MASK) != 0) 这个情况实际是不存在的,因为在SysTick_Handler 调用 的rt_tick_increase,一旦发现时间片用完或者主动礼让就会发起一次调度,清除了RT_THREAD_STAT_YIELD 再次因超时或者资源唤醒进来,也不满足这个条件 /**
*/ void rt_tick_increase(void) { struct rt_thread *thread; rt_base_t level; RT_OBJECT_HOOK_CALL(rt_tick_hook, ()); level = rt_hw_interrupt_disable(); /* increase the global tick */ #ifdef RT_USING_SMP rt_cpu_self()->tick ++; #else ++ rt_tick; #endif /* RT_USING_SMP */ /* check time slice */ thread = rt_thread_self(); -- thread->remaining_tick; if (thread->remaining_tick == 0) { /* change to initialized tick */ thread->remaining_tick = thread->init_tick; thread->stat |= RT_THREAD_STAT_YIELD; rt_hw_interrupt_enable(level); rt_schedule(); } else { rt_hw_interrupt_enable(level); } /* check timer */ rt_timer_check(); 3) if (rt_current_thread->current_priority > highest_ready_priority && (rt_current_thread->stat & RT_THREAD_STAT_YIELD_MASK) == 0) 新就绪的任务优先级高于当前任务,虽然当前任务时间片有剩余,也必须切出,同时保留剩余时间片 插入到readylist void rt_schedule_insert_thread(struct rt_thread *thread) { register rt_base_t temp; RT_ASSERT(thread != RT_NULL); /* disable interrupt */ temp = rt_hw_interrupt_disable(); /* it's current thread, it should be RUNNING thread */ if (thread == rt_current_thread) { thread->stat = RT_THREAD_RUNNING | (thread->stat & ~RT_THREAD_STAT_MASK); goto __exit; } /* READY thread, insert to ready queue */ thread->stat = RT_THREAD_READY | (thread->stat & ~RT_THREAD_STAT_MASK); /* insert thread to ready list */ rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]), &(thread->tlist)); RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("insert thread[%.*s], the priority: %d\n", RT_NAME_MAX, thread->name, thread->current_priority)); /* set priority mask */ #if RT_THREAD_PRIORITY_MAX > 32 rt_thread_ready_table[thread->number] |= thread->high_mask; #endif /* RT_THREAD_PRIORITY_MAX > 32 */ rt_thread_ready_priority_group |= thread->number_mask; __exit: /* enable interrupt */ rt_hw_interrupt_enable(temp); } 问题 问题出在情况3的第三种情景下: 新就绪的任务优先级高于当前任务,当前任务时间片有剩余, 插入动作没有问题,但是使用rt_list_insert_before把未执行完时间片的任务插入到其优先级readylist的最后面,是不是对其不太公平,毕竟是高优先级的任务打断了它。 是不是应该按下面分类处理比较好, 使用rt_list_insert_after把它插在list->next位置,下次轮到该优先级时,首先执行,直到其时间片用完!
// else if (rt_current_thread->current_priority > highest_ready_priority && (rt_current_thread->stat & RT_THREAD_STAT_YIELD_MASK) != 0) // { // need_insert_from_thread = 1; // } |
|
相关推荐
2个回答
|
|
分析得有道理,按这分析,我觉得正常逻辑应该是,高优先级打断了它,它住后等,等高优先级执行完后,就应该再执行它
|
|
|
|
和task1优先级相同的任务task3,则先插入task1,再插入task3到readylist中。那么_scheduler_get_highest_priority_thread得到的是task1,需要切换到task1执行。总的来说,需要插入的情况主要是在当前任务需要切出时,需要把当前任务插入到对应优先级的readylist中。
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
830 浏览 0 评论
AI模型部署边缘设备的奇妙之旅:如何在边缘端部署OpenCV
2916 浏览 0 评论
tms320280021 adc采样波形,为什么adc采样频率上来波形就不好了?
1391 浏览 0 评论
2006 浏览 0 评论
1553 浏览 0 评论
75039 浏览 21 评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 22:54 , Processed in 0.392510 second(s), Total 38, Slave 33 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号