当前位置: 首页 > news >正文

deadline调度学习

本篇通过几个方面来看deadline调度器:
1、deadline的设置
2、deadline的任务的添加
3、deadline的任务的调度

deadline的设置

deadline调度器不允许直接通过kernel_clone的方式创建,需要通过sched_setattr的方式将指定pid task修改为deadline调度器并进行必要参加的赋值,大体流程图如下:

首先通过系统调用sched_setattr主动来设置指定pid task的优先级别

SYSCALL_DEFINE3(sched_setattr,pid_t,pid,structsched_attr__user*,uattr,unsignedint,flags){structsched_attrattr;structtask_struct*p;intretval;if(!uattr||pid<0||flags)return-EINVAL;retval=sched_copy_attr(uattr,&attr);if(retval)returnretval;if((int)attr.sched_policy<0)return-EINVAL;if(attr.sched_flags&SCHED_FLAG_KEEP_POLICY)attr.sched_policy=SETPARAM_POLICY;rcu_read_lock();retval=-ESRCH;p=find_process_by_pid(pid);if(likely(p))get_task_struct(p);rcu_read_unlock();if(likely(p)){if(attr.sched_flags&SCHED_FLAG_KEEP_PARAMS)get_params(p,&attr);retval=sched_setattr(p,&attr);put_task_struct(p);}returnretval;}

__setscheduler_params:

void__setparam_dl(structtask_struct*p,conststructsched_attr*attr){structsched_dl_entity*dl_se=&p->dl;dl_se->dl_runtime=attr->sched_runtime;dl_se->dl_deadline=attr->sched_deadline;dl_se->dl_period=attr->sched_period?:dl_se->dl_deadline;dl_se->flags=attr->sched_flags&SCHED_DL_FLAGS;dl_se->dl_bw=to_ratio(dl_se->dl_period,dl_se->dl_runtime);dl_se->dl_density=to_ratio(dl_se->dl_deadline,dl_se->dl_runtime);}

__setscheduler_prio:

staticvoid__setscheduler_prio(structtask_struct*p,intprio){//根据优先级设定调度策略if(dl_prio(prio))p->sched_class=&dl_sched_class;elseif(rt_prio(prio))p->sched_class=&rt_sched_class;elsep->sched_class=&fair_sched_class;p->prio=prio;}

上述动作做完后,就将task加到指定的调度器任务中

staticinlinevoidenqueue_task(structrq*rq,structtask_struct*p,intflags){if(!(flags&ENQUEUE_NOCLOCK))update_rq_clock(rq);if(!(flags&ENQUEUE_RESTORE)){sched_info_enqueue(rq,p);psi_enqueue(p,(flags&ENQUEUE_WAKEUP)&&!(flags&ENQUEUE_MIGRATED));}uclamp_rq_inc(rq,p);p->sched_class->enqueue_task(rq,p,flags);if(sched_core_enabled(rq))sched_core_enqueue(rq,p);}

deadline的任务的添加

大概调用流程如下:
enqueue_task_dl -> enqueue_dl_entity -> __enqueue_dl_entity
-> rb_add_cached
这里对调用细节不作论述,只关注几个重要点:
一、deadline的设置
在上面已经有相关的配置了,但是相对值。还需要转化成需要数据

这里需要把设置的相对时间变成绝对截止时间
二、deadline核心的任务添加过程


从上面可知,deadline调用器。使用的红黑二叉树,左子树优先级最高。根据deadline值大小进行插入。插入完成后需要对二叉树作相关处理 ,以满足红黑二叉树特性。

deadline的任务的调度

在进行任务调度时候,如果deadline调度器有任务可供调度则会调用其pick_next_task_dl的回调函数

staticstructtask_struct*pick_next_task_dl(structrq*rq){structtask_struct*p;p=pick_task_dl(rq);//获取一个优化级最高的task就是上面所说的rb_leftmost//#define rb_first_cached(root) (root)->rb_leftmostif(p)set_next_task_dl(rq,p,true);returnp;}staticvoidset_next_task_dl(structrq*rq,structtask_struct*p,bool first){structsched_dl_entity*dl_se=&p->dl;structdl_rq*dl_rq=&rq->dl;p->se.exec_start=rq_clock_task(rq);//记录开始执行的时间if(on_dl_rq(&p->dl))update_stats_wait_end_dl(dl_rq,dl_se);/* You can't push away the running task */dequeue_pushable_dl_task(rq,p);//将此task从二叉树上移除,不能老是占位if(!first)return;if(hrtick_enabled_dl(rq))start_hrtick_dl(rq,p);//启动高精度定时器if(rq->curr->sched_class!=&dl_sched_class)update_dl_rq_load_avg(rq_clock_pelt(rq),rq,0);deadline_queue_push_tasks(rq);}#ifdefCONFIG_SCHED_HRTICKstaticvoidstart_hrtick_dl(structrq*rq,structtask_struct*p){//定时器的超时时间为runtime,也就是说task运行时间为runtime大小hrtick_start(rq,p->dl.runtime);}#else/* !CONFIG_SCHED_HRTICK */staticvoidstart_hrtick_dl(structrq*rq,structtask_struct*p){}#endif

下面来看看定时器超时的处理
一、定时器的初始化

staticvoidhrtick_rq_init(structrq*rq){#ifdefCONFIG_SMPINIT_CSD(&rq->hrtick_csd,__hrtick_start,rq);#endifhrtimer_init(&rq->hrtick_timer,CLOCK_MONOTONIC,HRTIMER_MODE_REL_HARD);rq->hrtick_timer.function=hrtick;//超时回调函数}
staticenumhrtimer_restarthrtick(structhrtimer*timer){structrq*rq=container_of(timer,structrq,hrtick_timer);structrq_flagsrf;WARN_ON_ONCE(cpu_of(rq)!=smp_processor_id());rq_lock(rq,&rf);update_rq_clock(rq);//调用到了调度器的task_tick回调函数rq->curr->sched_class->task_tick(rq,rq->curr,1);rq_unlock(rq,&rf);returnHRTIMER_NORESTART;}

这里需要注意的是 task_tick这个函数在系统的tick 定时器里面也会调用

二、定时器超时处理

staticvoidtask_tick_dl(structrq*rq,structtask_struct*p,intqueued){//更新当前状态,并修改runtime值大小为剩下时间update_curr_dl(rq);update_dl_rq_load_avg(rq_clock_pelt(rq),rq,1);/* * Even when we have runtime, update_curr_dl() might have resulted in us * not being the leftmost task anymore. In that case NEED_RESCHED will * be set and schedule() will start a new hrtick for the next task. */if(hrtick_enabled_dl(rq)&&queued&&p->dl.runtime>0&&is_leftmost(p,&rq->dl))//如果runtime时间大于0,则会restart此定时器,并使用最新的超时时间start_hrtick_dl(rq,p);}


上面的处理比较清晰,由于tick定时器会不断触发这里的runtime值为持续减少。如果runtime小于等于0或者调用yield_task_dl回调函数,都会将当前处理的task移除二叉树。并重新进行任务调度。

deadline任务调度器核心是任务的添加、移除、调度。这里的二叉树的使用策略搞清楚,大体就能明白deadline的调度器使用逻辑了

http://www.jsqmd.com/news/900928/

相关文章:

  • 从Hello World到用户注册页:一个HTML新手的Educoder闯关全记录
  • C166中断管道问题解析与解决方案
  • 别再傻傻分不清了!华为ENSP里堆叠(iStack)和集群(CSS)到底有啥区别?
  • AI安全新威胁:间接提示注入攻击与IPI-Scanner防御实战
  • Kibana 仪表板即代码:在 Elastic 9.4 中用于 Kibana 仪表板的 GitOps、漂移检测与 Terraform
  • 2026年 哈尔滨国家开放大学报名指南:国开高起专/专升本热门专业与免试入学深度解析及学历价值推荐 - 品牌企业推荐师(官方)
  • HarmonyOS vibrator API 封装解析:DeviceUtil 振动工具函数从入门到实战
  • 用Unity Embedded Browser插件打造混合应用:本地HTML图表(ECharts)与Unity 3D场景实时交互实战
  • ChatGPT能听懂巴赫赋格吗?:实测12款提示词模板,3分钟生成专业级和声分析报告(附MIT音乐认知实验室验证数据)
  • SLANeXt_wireless_onnx深度解析:革新表格识别的终极AI模型
  • ChatGPT写诗总像说明书?——从古典格律到自由诗体的12种结构化提示模板(含平仄校验与意象密度优化公式)
  • 数据主权时代:如何构建个人AI记忆中心的完整技术方案
  • 如何用Arduino-ESP32快速构建智能物联网设备:从入门到实战的完整指南
  • HarmonyOS 屏幕信息获取入门:getDefaultDisplaySync 与 getAllDisplays 详解
  • 用CloudCompare和Python处理DublinCityDataSet点云数据,我踩过的那些坑(附完整代码)
  • ppf-contact-solver故障排除:安装依赖冲突的终极解决指南
  • AdelaiDepth深度解析:从单张图像重建3D场景的完整指南
  • E5-small常见问题解答:解决使用过程中的10个典型问题
  • 别再拍脑袋定样本量了!用Excel手把手教你搞定市场调研问卷的样本容量(附置信区间计算模板)
  • 如何永久保存微信聊天记录:WeChatMsg完整操作指南
  • AI优化建议:让AI帮你优化代码性能
  • 别再手动转IMU了!用MATLAB实现椭球拟合自动校准加速度计(附完整代码)
  • 从MLM到RTD:一文读懂DeBERTa V3的预训练任务革新与HuggingFace快速上手
  • 鸿蒙刘海屏、水滴屏、瀑布屏适配:用 DisplayUtil 获取不可用区域
  • 从PC到AI,联想中国一场必打的仗
  • 如何快速上手AdelaiDepth:5分钟实现单目深度估计 [特殊字符]
  • HarmonyOS FoldStatus 与 FoldDisplayMode 枚举深度解析:折叠屏开发不再难
  • 多家对比才知道!机闸一体式钢制闸门哪家好、哪家优惠?认准河北闸之都实体厂家,可定制,品质价格双保障 - 栗子测评
  • 10个免费VMware Workstation Pro 17许可证密钥:专业虚拟化快速激活指南
  • LightRAG 入门指南:手把手教你用图增强 RAG 系统