1.RMS调度简介
任务按单调速率优先级分配(RMPA)的调度算法,称为单调速率调度(RMS)。RMPA是指任务的优先级按任务周期T来分配。它根据任务的执行周期的长短来决定调度优先级,那些具有小的执行周期的任务具有较高的优先级,周期长的任务优先级低。

2.RMS调度实现介绍
SylixOS目前关于RMS调度分为创建、删除、调度三个部分组成。创建和删除就不予介绍。重点关注下调度算法的实现。调度有两个去完成,一是计算调度前用掉的时间etime,二是睡眠剩余调度的时间temp,如程序清单 2‑1所示。

程序清单2-1 RMS实现源码

/********************************************************************************************
** 函数名称: sched_rms_period
** 功能描述: RMS 调度器
** 输 入  : prms      RMS 调度器
**           period    RMS 周期
** 输 出  : 0 表示正确
**           error == EINTR    表示被信号激活.
** 全局变量:
** 调用模块: API 函数
********************************************************************************************/
LW_API
int  sched_rms_period (sched_rms_t  *prms, const struct timespec *period)
{struct timespec temp;struct timespec etime;if (!prms || !period) {errno = EINVAL;return  (PX_ERROR);}switch (prms->PRMS_iStatus) {case PRMS_STATUS_INACTIVE:lib_clock_gettime(CLOCK_MONOTONIC, &prms->PRMS_tsSave);  prms->PRMS_iStatus = PRMS_STATUS_ACTIVE;return  (ERROR_NONE);case PRMS_STATUS_ACTIVE:lib_clock_gettime(CLOCK_MONOTONIC, &temp);etime = temp;__timespecSub(&etime, &prms->PRMS_tsSave);if (__timespecLeftTime(period, &etime)) {                       lib_clock_gettime(CLOCK_MONOTONIC, &prms->PRMS_tsSave);     errno = EOVERFLOW;return  (PX_ERROR);}temp = *period;__timespecSub(&temp, &etime);__timespecAdd(&prms->PRMS_tsSave, period);                      return  (nanosleep(&temp, LW_NULL));default:errno = ENOTSUP;return  (PX_ERROR);}
}
  1. 计算调度时间

首先通过系统函数获取准确的时间etime,在和上一次保存的时间PRMS_toSave相减获得在进入调度函数之前所用掉的时间etime。利用etime和需要调度的时间period比较进行处理。计算出需要睡眠的时间temp。

  1. 睡眠剩余的调度时间

通过函数nanosleep计算剩余的时间,函数nanosleep具体实现可参考SylixOS源码,其流程如图 2‑1所示。

图2-1 nanosleep流程图

3.RMS调度分析
3.1 RMS调度优势
调度算法中利用PRMS_tsSave保存时间点,为下一次调度作为时间参考,调度按照确定周期运行,这样可以避免因多次调度而累积的误差。代码如下:

__timespecSub(&temp, &etime);/*
*  注意: 这里直接加上周期是为了让每次测算都是以一个固定周期律进行
*        提高周期精度. (不使用 lib_clock_gettime())
*/
__timespecAdd(&prms->PRMS_tsSave, period);                      /*  以确定周期运行              */
return  (nanosleep(&temp, LW_NULL));

3.2 误差分析一
调度算法中存在这样的问题,需要延迟的时间time和延迟函数function是分开的,这就会导致一个问题,在计算出time后有可能进程被调度,而没有进入function。

等下一次调度到进程后再进入function后会导致时间不准确,该进程从被调度到再次被调度中的时间没有被计算。这种情况出现在调度函数sched_rms_period,在计算

出睡眠时间后temp后进程被调度,等下一次被调度后才进入睡眠时间。代码如下:

__timespecSub(&temp, &etime);/**  注意: 这里直接加上周期是为了让每次测算都是以一个固定周期律进行*        提高周期精度. (不使用 lib_clock_gettime())*/
__timespecAdd(&prms->PRMS_tsSave, period);                      /*  以确定周期运行              */
return  (nanosleep(&temp, LW_NULL));

nanosleep也同样会出现此类问题,在计算平滑过度时间后,也有可能出现进程调度而导致时间计算不准确。代码如下:

if (__timespecLeftTime(&tvTemp, rqtp)) {                        /*  还有剩余时间需要延迟        */struct timespec  tvNeed = *rqtp;__timespecSub(&tvNeed, &tvTemp);__timePassSpec(&tvNeed);                                   /*  平静度过                    */
}

3.3 误差分析二
同时我们在该函数中获取高精度时间没有放在函数最开始运行处,在运行到获取高精度时间前也可能出现进程调度。代码如下:

ulTick = __timespecToTick((struct timespec *)rqtp);
if (!ulTick) {                                                  /*  不到一个 tick               */__timePassSpec(rqtp);                                      /*  平静度过                    */if (rmtp) {rmtp->tv_sec  = 0;                                     /*  不存在时间差别              */rmtp->tv_nsec = 0;}return  (ERROR_NONE);}__timeGetHighResolution(&tvStart);                             /*  记录开始的时间              */

改进措施:尽量将__timeGetHighResolution获取开始延迟的时间点函数靠前,避免nanosleep在执行获取高精度时间之前出现进程调度的情况;

可以将要延迟的时间起始点以参数的形式传递给要睡眠的函数,比如nanosleep这类函数就可以在调用者处确定延迟的时间点tvStart,而不是在nanosleep中去获取

SylixOS --- RMS调度详解相关推荐

  1. Quartz.Net实现作业定时调度详解

    Quartz.Net实现作业定时调度详解 原文:Quartz.Net实现作业定时调度详解 1.Quartz.NET介绍 Quartz.NET是一个强大.开源.轻量的作业调度框架,你能够用它来为执行一个 ...

  2. Kubernetes K8S之固定节点nodeName和nodeSelector调度详解

    Kubernetes K8S之固定节点nodeName和nodeSelector调度详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-mas ...

  3. RTEMS线程调度算法(RMS)详解

    RTEMS是以线程为基本调度单位的,调度算法基于优先级的抢占式线程调度,支持256个线程优先级.当然RTEMS值hi创建同等优先级线程,相同优先级的线程采用时间片轮转调度.调度器寻找下一个最高优先级就 ...

  4. goroutine调度详解,以及进程、线程、协程区别

    转载地址:https://blog.csdn.net/Arlingtonroad/article/details/106952053?utm_medium=distribute.pc_relevant ...

  5. 操作系统-处理机调度详解(调度层次及FCFS、SPF、RR等算法)

    目录 调度层次 处理机调度算法 评价指标 非剥夺式/抢占式 非抢占式优先级调度算法 先来先服务(FCFS) 短进程优先(SPF) 响应比优先算法(HRRN) 剥夺式/抢占式 最短剩余时间优先(SRTN ...

  6. php swoole实现定时任务,Swoole实现任务定时自动化调度详解,来学习下

    问题描述 这几天做银行对帐接口时,踩了一个坑,具体需求大致描述一下. 银行每天凌晨后,会开始准备昨天的交易流水数据,需要我们这边请求拿到. 因为他们给的是一个base64加密的zip压缩流,解开以后可 ...

  7. 【连载】从单片机到操作系统⑥——FreeRTOS任务切换机制详解

    大家晚上好,我是杰杰,最近挺忙的,好久没有更新了,今天周末就吐血更新一下吧! 前言 FreeRTOS是一个是实时内核,任务是程序执行的最小单位,也是调度器处理的基本单位,移植了FreeRTOS,则避免 ...

  8. Go 官方进程诊断工具 gops 详解 | 周末送书

    K8s已经成为一线大厂分布式平台的标配技术.你是不是还在惆怅怎么掌握它?来这里,大型互联网公司一线工程师亲授,不来虚的,直接上手实战,3天时间带你搭建K8s平台,快速学会K8s,点击下方图片可了解培训 ...

  9. R语言rms包生存分析之限制性立方样条(RCS, Restricted cubic spline)分析详解实战:拟合连续性自变量和事件风险之间的关系:基于survival包lung数据

    R语言rms包生存分析之限制性立方样条(RCS, Restricted cubic spline)分析详解实战:拟合连续性自变量和事件风险之间的关系:基于survival包lung数据 目录

  10. Linux进程退出详解(do_exit)--Linux进程的管理与调度(十四)

    Linux进程的退出 linux下进程退出的方式 正常退出 从main函数返回return 调用exit 调用_exit 异常退出 调用abort 由信号终止 _exit, exit和_Exit的区别 ...

最新文章

  1. 移动平台的meta标签-----神奇的功效
  2. 机器学习(6)--化无限为有限(二)
  3. Java的自动装箱与拆箱
  4. 服务注册发现consul之五:Consul移除失效服务的正确姿势
  5. leetcode 397. Integer Replacement | 397. 整数替换(动态规划,记忆化搜搜)
  6. javascript的全局变量
  7. bootstrap table 列拖动变宽
  8. CentOS7中MongoDB备份与恢复,配置远程访问
  9. android 时间计划软件,时间规划局专业版
  10. SAP License:值字段更改注意事项
  11. 通达信波段王指标公式主图_通达信波段王主图指标公式
  12. GRBL学习笔记2--grbl Arduino烧写
  13. ASAP光学设计软件
  14. 0X00000000指令引用的0x00000000内存该内存不能为read或written
  15. 云服务器win10系统初始密码,win10忘记系统密码?教你重置-
  16. atomic原子类实现机制_atomic实现原理
  17. java media player 设置音量_SoundPlayer可调音量 - c#
  18. java基础知识-----转
  19. ERROR 1010 (HY000): Error dropping database (can't rmdir './library', errno:
  20. 小编我使用 Vue3+Ts+Vite2 写了一个美女小黄站

热门文章

  1. bugzilla mysql_Centos 7 搭建Bugzilla5.0.4
  2. python1~10阶乘_阶乘python怎么打
  3. WIN7 KB4516065 安装失败
  4. 笔记本计算机无法开机,笔记本电脑无法开机黑屏?故障分析大全,及时解决办法...
  5. 计算机应用个人职业发展规划简短,个人职业生涯规划
  6. WPS如何隔列填充背景颜色
  7. 收藏 90+深度学习开源数据集整理|包括目标检测、工业缺陷、图像分割等多个方向
  8. MacPro自带浏览器Safari假死状态(无法操作)处理办法 Safari浏览器开发模式打开
  9. 创建对象的几种常用写法
  10. Windows Server 2019/2022域控制器网络位置变为“专用网络”或“公共网络”