前言

在软件世界里面,超时是一个非常重要的概念。比如

● 当前线程暂时休眠1秒钟,休眠结束后继续执行

● 每5秒钟采集一下CPU利用率

● 数据发送失败,2秒钟以后再试一试

● 等待某种数据,但最多等待50毫秒

应用

//将当前任务休眠若干tick数,tick为时间单位,常见值为10毫秒

LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)

//获取信号量semHandle, 如果当前信号量不可用且timeout不为0,则最多等待timeout所指定的时间,在这段时间内如果信号量可用,则获取成功,否则获取失败。

LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)

//从空的消息队列读取消息,或者向满的消息队列写消息时,如果timeout不为0,则最多等待timeout指定的时间,在这段时间内消息队列可读或可写,则进行对应的读写并返回成功,否则返回失败。

LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeOut)

LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeOut)

//获取互斥锁,如果当前互斥锁被其它线程占用,则最多等待timeout指定的时间,此时间内其它线程释放了互斥锁并被本线程抢到则返回成功,否则返回失败。

LITE_OS_SEC_TEXT UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout)

//等待其它线程向本线程发送事件,最多等待timout指定的时间

LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeOut)

上述这些函数都是超时概念在OpenHarmony中liteos_m内核里的具体应用。

具体而言,liteos_m内核如何实现这个超时逻辑的呢,我们接着看下一个章节

原理

如上图所示。在时间轴上,黄色圆点代表需要进行某种操作的时间点,而绿色圆点为检查系统是否有超时事件需要处理的检查时间点。系统周期性的进行检查(周期单位为tick)。在2个检查点之间可能有超时事件,也可能无超时事件。

例如,根据上图展示的情况。当前在第一个检查点,发现了2个超时事件,那么这次处理这2个超时事件;随着时间流逝,箭头来到第2个检查点,又发现2个超时事件,继续处理;在第3个检查点时,本段时间内无超时事件,所以是空操作。后续的检查以此类推。

代码实现

为了准确性以及时效性,本文选取了最新的版本的代码来描述。上述检查点和时间点由链表结构进行定义。具体在kernel/liteos_m/include/los_sortlink.h文件中。

由于原理图中的超时事件发生是非均匀的,且存在有序依次发生的逻辑,所以,这些信息被维护在双向链表中(对删除操作更友好)。

SortLinkList代表了链表中的每一个需要处理事件的时间点,responseTime代表具体的时间值(从启机开始的cpu cycle数目)。SortLinkAttribute代表链表的头部(哑头)。从名称也能看出,这个是一个排序的双向链表,排序的依据即responseTime这个数值。

需要注意的一个细节是:系统支持2个链表,其中一个是TASK链表,另一个是SWTMR链表。这2个链表实现方式一致,主要区别是,SWTMR链表超时处理是唤醒swtmr线程来处理超时事件,而task链表唤醒的是每个具体的task(sleep,ipc超时等场景)。使用swtmr线程来处理若干超时的机制,可以有效减少系统需要的线程数目,从而节省系统资源的占用。

总结

本文描述了超时逻辑在OpenHarmony中的实现,从原理,使用以及具体实现细节上进行了详尽讨论,并归纳整理了当前这种实现方式所带来的益处。

对OpenHarmony中LiteOS的内核分析——超时原理和应用的更多相关文章

  1. linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    系统调用:库函数封装了系统调用,通过库函数和系统调用打交道 用户态:低级别执行状态,代码的掌控范围会受到限制. 内核态:高执行级别,代码可移植性特权指令,访问任意物理地址 为什么划分级别:如果全部特权 ...

  2. 分析Linux内核中进程的调度(时间片轮转)-《Linux内核分析》Week2作业

    1.环境的搭建: 这个可以参考孟宁老师的github:mykernel,这里不再进行赘述.主要是就是下载Linux3.9的代码,然后安装孟宁老师编写的patch,最后进行编译. 2.代码的解读 课上的 ...

  3. LInux内核分析--使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    实验者:江军 ID:fuchen1994 实验描述: 选择一个系统调用(13号系统调用time除外),系统调用列表参见http://codelab.shiyanlou.com/xref/linux-3 ...

  4. linux内核分析作业8:理解进程调度时机跟踪分析进程调度与进程切换的过程

    1. 实验目的 选择一个系统调用(13号系统调用time除外),系统调用列表,使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 分析汇编代码调用系统调用的工作过程,特别是参数的传递的方 ...

  5. Linux内核分析作业7:Linux内核如何装载和启动一个可执行程序

            1.可执行文件的格式 在 Linux 平台下主要有以下三种可执行文件格式: 1.a.out(assembler and link editor output 汇编器和链接编辑器的输出) ...

  6. linux内核分析作业6:分析Linux内核创建一个新进程的过程

    task_struct结构: struct task_struct {   volatile long state;进程状态  void *stack; 堆栈  pid_t pid; 进程标识符  u ...

  7. linux内核分析作业5:分析system_call中断处理过程

    1.增加 Menu 内核命令行 调试系统调用. 步骤:删除menu git clone        (tab) make rootfs 这就是我们将 fork 函数写入 Menu 系统内核后的效果, ...

  8. linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作

    一.实验 使用gcc –S –o main.s main.c -m32 命令编译成汇编代码,如下代码中的数字请自行修改以防与他人雷同 int g(int x) { return x + 3; } in ...

  9. linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核代码

    计算机如何工作 三个法宝:存储程序计算机.函数调用堆栈.中断机制. 堆栈 函数调用框架 传递参数 保存返回地址 提供局部变量空间 堆栈相关的寄存器 Esp 堆栈指针  (stack pointer) ...

  10. linux内核分析作业3:跟踪分析Linux内核的启动过程

    内核源码目录 1. arch:录下x86重点关注 2. init:目录下main.c中的start_kernel是启动内核的起点 3. ipc:进程间通信的目录 实验 使用实验楼的虚拟机打开shell ...

随机推荐

  1. sort.interface接口

    一个内置的排序算法需要知道三个东西:序列的长度,表示两个元素比较的结果,一种交换两个元素的方式:这就是sort.Interface的三个方法: package sort type Interface ...

  2. OpenCV计数应用 c++(QT)

    一.前言 为了挑战一下OpenCV的学习成果,最经一直在找各类项目进行实践.机缘巧合之下,得到了以下的需求: 要求从以下图片中找出所有的近似矩形的点并计数,重叠点需要拆分单独计数. 二.解题思路 1. ...

  3. iOS的Runtime知识点繁杂难啃,真的理解它的思想,你就豁然开朗了

    一.Runtime 1.概念: 概念:Runtime是Objective-c语言动态的核心,即运行时.在面向对象的基础上增加了动态运行,达到很多在编译时确定方法推迟到了运行时,从而达到动态修改.确定. ...

  4. HashMap,TreeMap,LinkedHashMap的默认排序

    简单描述 Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,HashTable以及LinkedHashMap等. TreeMap:能够把它保存的记录根据键(key)排序,默 ...

  5. 【Azure Fabric Service】怎样关闭 Azure Service Fabric?

    问题描述 怎样关闭Azure Service Fabric服务呢?在Azure门户上没有找到 Stop 按钮. 问题回答 Azure Service Fabric 默认是无法停止的,可以删除. 虽然可 ...

  6. mysql-批量修改表的主键id,修改成联合主键

    1.sql脚本 一. 通过sql脚本,查出所有表的功能,并编写插入修改的联合主键,sql select concat('ALTER table ', TABLE_NAME, ' DROP PRIMAR ...

  7. C++//vector存放自定义数据类型

    1 //vector存放自定义数据类型 2 3 #include <iostream> 4 #include <string> 5 #include<fstream> ...

  8. 深入浅出Java多线程(十):CAS

    引言 大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第十篇内容:CAS.大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!! 在多线程编程中,对共享资源的安全访问和同步 ...

  9. Spring与微服务

    Spring与微服务 微服务论文 Melvyn Conway 的意识是,像下图所展示的,设计一个系统时,将人员划分为 UI 团队,中间件团队,DBA 团队,那么相应地,软件系统也就会自然地被划分为 U ...

  10. vue-helper 导致找到2个函数定义,跳转需要多点一下,禁用vue-helper即可

    vue-helper 导致找到2个函数定义,跳转需要多点一下,禁用vue-helper即可