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

RT_Thread内核机制学习(二)

对于RTT来说,每个线程创建时都自带一个定时器
在这里插入图片描述

rt_err_t rt_thread_sleep(rt_tick_t tick)
{register rt_base_t temp;struct rt_thread *thread;/* set to current thread */thread = rt_thread_self();RT_ASSERT(thread != RT_NULL);RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);/* disable interrupt */temp = rt_hw_interrupt_disable();/* suspend thread */rt_thread_suspend(thread); //从就绪链表移除/* reset the timeout of thread timer and start it */rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &tick); //设置定时器定时时间rt_timer_start(&(thread->thread_timer)); //开启定时器/* enable interrupt */rt_hw_interrupt_enable(temp);rt_schedule();/* clear error number of this thread to RT_EOK */if (thread->error == -RT_ETIMEOUT)thread->error = RT_EOK;return RT_EOK;
}

延时过程:

  1. 将线程从就绪链表移除。
  2. 设置/启动定时器
  3. 每个Tick判断,定时器是否超时,调用超时函数。
/*** This function is the timeout function for thread, normally which is invoked* when thread is timeout to wait some resource.** @param parameter the parameter of thread timeout function*/
void rt_thread_timeout(void *parameter)
{struct rt_thread *thread;thread = (struct rt_thread *)parameter;/* thread check */RT_ASSERT(thread != RT_NULL);RT_ASSERT((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND);RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);/* set error number */thread->error = -RT_ETIMEOUT; //表示被唤醒原因是:超时/* remove from suspend list */rt_list_remove(&(thread->tlist)); //可能因为等待队列等原因而挂起,先移除/* insert to schedule ready list */rt_schedule_insert_thread(thread);/* do schedule */rt_schedule();
}
RTM_EXPORT(rt_thread_timeout);

超时函数:

  1. 将线程放入就绪链表尾部
  2. 发起调度
void rt_schedule_remove_thread(struct rt_thread *thread)
{register rt_base_t level;RT_ASSERT(thread != RT_NULL);/* disable interrupt */level = rt_hw_interrupt_disable();RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("remove thread[%.*s], the priority: %d\n",RT_NAME_MAX, thread->name,thread->current_priority));/* remove thread from ready list */rt_list_remove(&(thread->tlist));if (rt_list_isempty(&(rt_thread_priority_table[thread->current_priority]))){
#if RT_THREAD_PRIORITY_MAX > 32rt_thread_ready_table[thread->number] &= ~thread->high_mask;if (rt_thread_ready_table[thread->number] == 0){rt_thread_ready_priority_group &= ~thread->number_mask;}
#elsert_thread_ready_priority_group &= ~thread->number_mask;
#endif}/* enable interrupt */rt_hw_interrupt_enable(level);
}

将线程从就绪链表中移除,首先从链表中删除,再判断优先级对应的链表是否空了?

在这里插入图片描述
可以快速查找到哪一位是1。

每次Tick中断还需要检查定时器

/*** This function will check timer list, if a timeout event happens, the* corresponding timeout function will be invoked.** @note this function shall be invoked in operating system timer interrupt.*/
void rt_timer_check(void)
{struct rt_timer *t;rt_tick_t current_tick;register rt_base_t level;RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check enter\n"));current_tick = rt_tick_get();/* disable interrupt */level = rt_hw_interrupt_disable();while (!rt_list_isempty(&rt_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1])){t = rt_list_entry(rt_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next,struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]); //从链表中取出定时器/** It supposes that the new tick shall less than the half duration of* tick max.*/if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2) //判断时间是否到了{RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));/* remove timer from timer list firstly */_rt_timer_remove(t);/* call timeout function */t->timeout_func(t->parameter);/* re-get tick */current_tick = rt_tick_get();RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t));RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick));if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&(t->parent.flag & RT_TIMER_FLAG_ACTIVATED)){/* start it */t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;rt_timer_start(t);}else{/* stop timer */t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;}}elsebreak;}/* enable interrupt */rt_hw_interrupt_enable(level);RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check leave\n"));
}

依次判断定时器时间是否到了,到了的话就调用定时器超时函数。
在这里插入图片描述
定时器启动后放到链表中。

Tick中断检查定时器时,也是从链表中取出判断。

相关文章:

RT_Thread内核机制学习(二)

对于RTT来说&#xff0c;每个线程创建时都自带一个定时器 rt_err_t rt_thread_sleep(rt_tick_t tick) {register rt_base_t temp;struct rt_thread *thread;/* set to current thread */thread rt_thread_self();RT_ASSERT(thread ! RT_NULL);RT_ASSERT(rt_object_get_type(…...

线性代数的学习和整理12: 矩阵与行列式,计算上的差别对比

目录 1 行列式和矩阵的比较 2 简单总结矩阵与行列式的不同 3 加减乘除的不同 3.1 加法不同 3.2 减法不同 3.3 标量乘法/数乘 3.3.1 标准的数乘对比 3.3.2 数乘的扩展 3.4 乘法 4 初等线性变换的不同 4.1 对矩阵进行线性变换 4.2 对行列式进行线性变换 1 行列式和…...

2023年MySQL核心技术面试第一篇

目录 一 . 存储&#xff1a;一个完整的数据存储过程是怎样的&#xff1f; 1.1 数据存储过程 1.1.1 创建MySQl 数据库 1.1.1.1 为什么我们要先创建一个数据库&#xff0c;而不是直接创建数据表&#xff1f; 1.1.1.2基本操作部分 1.2 选择索引问题 二 . 字段&#xff1a;这么多的…...

linux启动jar 缺失lib

linux启动jar包时&#xff0c;找不到报错 [rootebs-141185 xl-admin]# java -Djava.library.path/home/kabangke/xl-admin/lib -jar /home/kabangke/xl-admin/xl-admin.jar Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/web/se…...

【Bash】常用命令总结

文章目录 1. 文件查询1.1 查看文件夹内&#xff08;包含子文件夹&#xff09;文件数量1.2 查看文件夹大小 任务简介&#xff1a; 对bash常用命令进行总结。 任务说明&#xff1a; 对平时工作中使用bash的相关命令做一个记录和说明&#xff0c;方便以后查阅。 1. 文件查询 1.…...

小研究 - Java虚拟机性能及关键技术分析

利用specJVM98和Java Grande Forum Benchmark suite Benchmark集合对SJVM、IntelORP,Kaffe3种Java虚拟机进行系统测试。在对测试结果进行系统分析的基础上&#xff0c;比较了不同JVM实现对性能的影响和JVM中关键模块对JVM性能的影响&#xff0c;并提出了提高JVM性能的一些展望。…...

Repo manifests默认default.xml清单文件中的各个标签详解

Repo简介 “Repo” 是一个用于管理多个Git存储库的工具&#xff0c;通常与Google的Android开发项目一起使用。它允许您在一个命令下轻松地进行多个Git存储库的同步、下载和管理。 repo下载安装 从清华镜像源下载 mkdir ~/bin PATH~/bin:$PATH curl https://mirrors.tun…...

javacv基础02-调用本机摄像头并预览摄像头图像画面视频

引入架包&#xff1a; <dependency><groupId>org.openpnp</groupId><artifactId>opencv</artifactId><version>4.5.5-1</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId…...

【Nginx21】Nginx学习:FastCGI模块(三)缓冲区与响应头

Nginx学习&#xff1a;FastCGI模块&#xff08;三&#xff09;缓冲区与响应头 缓存相关的内容占了 FastCGI 模块将近一小半的内容&#xff0c;当然&#xff0c;用过的人可能不多。而今天的内容说实话&#xff0c;我平常也没怎么用过。第一个是缓冲区相关的知识&#xff0c;其实…...

正则表达式(常用字符简单版)

量词 字符类 边界匹配 分组和捕获 特殊字符 字符匹配 普通字符&#xff1a;普通字符按照字面意义进行匹配&#xff0c;例如匹配字母 "a" 将匹配到文本中的 "a" 字符。元字符&#xff1a;元字符具有特殊的含义&#xff0c;例如 \d 匹配任意数字字符&#xf…...

从零开始学习Python爬虫:详细指南

导言&#xff1a; 随着互联网的迅速发展&#xff0c;大量的数据可供我们利用。而Python作为一种简单易学且功能强大的编程语言&#xff0c;被广泛应用于数据分析和处理。学习Python爬虫技术&#xff0c;能够帮助我们从互联网上获取数据&#xff0c;并进行有效地分析和利用。本文…...

分布式计算框架:Spark、Dask、Ray

目录 什么是分布式计算 分布式计算哪家强&#xff1a;Spark、Dask、Ray 2 选择正确的框架 2.1 Spark 2.2 Dask 2.3 Ray 什么是分布式计算 分布式计算是一种计算方法&#xff0c;和集中式计算是相对的。 随着计算技术的发展&#xff0c;有些应用需要非常巨大的计算能力才…...

什么是伪类链(Pseudo-class Chaining)?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ Pseudo-class Chaining⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚…...

每日一题:leetcode 57 插入区间

给你一个 无重叠的 &#xff0c;按照区间起始端点排序的区间列表。 在列表中插入一个新的区间&#xff0c;你需要确保列表中的区间仍然有序且不重叠&#xff08;如果有必要的话&#xff0c;可以合并区间&#xff09;。 示例 1&#xff1a; 输入&#xff1a;intervals [[1,3…...

第五节:实现自己的第一个environment

本专栏是强化学习运用在买卖股票之上的入门学习内容。 主要解决强化学习代码落地和代码实践,不需要学习相关数学原理,直观简单的带领读者入门强化学习炒股。 查看本专栏完整内容,请访问:https://blog.csdn.net/windanchaos/category_12391143.html 本文发布地址:https://b…...

无套路,财务数据分析-多组织损益表分析分享

在报表众多的财务数据分析中&#xff0c;损益表是老板们最关注的报表&#xff0c;特别是当有多组织时&#xff0c;损益表的分析就变得更加重要了。以前受限于数据分析工具&#xff0c;做损益表分析时很难做到多维度灵活分析&#xff0c;但随着BI数据可视化工具的发展&#xff0…...

Java并发编程第6讲——线程池(万字详解)

Java中的线程池是运用场景最多的并发框架&#xff0c;几乎所有需要异步或并发执行任务的程序都可以使用线程池&#xff0c;本篇文章就详细介绍一下。 一、什么是线程池 定义&#xff1a;线程池是一种用于管理和重用线程的技术&#xff08;池化技术&#xff09;&#xff0c;它主…...

AI + Milvus:将时尚应用搭建进行到底

在上一篇文章中&#xff0c;我们学习了如何利用人工智能技术&#xff08;例如开源 AI 向量数据库 Milvus 和 Hugging Face 模型&#xff09;寻找与自己穿搭风格相似的明星。在这篇文章中&#xff0c;我们将进一步介绍如何通过对上篇文章中的项目代码稍作修改&#xff0c;获得更…...

归并排序(Java 实例代码)

目录 归并排序 一、概念及其介绍 二、适用说明 三、过程图示 四、Java 实例代码 MergeSort.java 文件代码&#xff1a; 归并排序 一、概念及其介绍 归并排序&#xff08;Merge sort&#xff09;是建立在归并操作上的一种有效、稳定的排序算法&#xff0c;该算法是采用分…...

【VUE】数字动态变化到目标值-vue-count-to

vue-count-to是一个Vue组件&#xff0c;用于实现数字动画效果。它可以用于显示从一个数字到另一个数字的过渡动画。 插件名&#xff1a;vue-count-to 官方仓库地址&#xff1a;GitHub - PanJiaChen/vue-countTo: Its a vue component that will count to a target number at a…...

Stable-Diffusion-v1-5-archive生产环境部署:异常自动拉起+日志监控+多用户隔离方案

Stable-Diffusion-v1-5-archive生产环境部署&#xff1a;异常自动拉起日志监控多用户隔离方案 1. 引言 如果你正在寻找一个稳定、可靠、易于管理的Stable Diffusion v1.5生产环境部署方案&#xff0c;那么你来对地方了。SD1.5作为文生图领域的经典模型&#xff0c;虽然新模型…...

晶体塑性损伤模型的魔改日常——手把手拆解应力更新核心

基于huang晶体塑性有限元损伤演化代码&#xff0c;包含应力更新&#xff0c;送inp文件. (包含损伤演化&#xff09;(损伤后应力更新&#xff09;最近在折腾Huang的晶体塑性框架&#xff0c;发现原版代码在损伤处理上还是太"干净"了。趁着周末撸了个损伤演化模块&…...

数字健康时代的“价值共生“:APP如何用技术重新定义身体数据的意义

一、从"数字佃农"到"价值共创者"&#xff1a;健康数据经济的范式转移2024年&#xff0c;全球健康经济规模达到6.8万亿美元&#xff0c;数字健康板块增速领跑全行业。在这场变革中&#xff0c;一个核心命题浮出水面&#xff1a;当我们的身体数据成为驱动AI进…...

为什么事故复盘总是写到很晚?

这两天和几个做运维/后端的朋友聊了下事故复盘&#xff0c;发现一个很真实的情况&#xff1a; &#x1f449; 大家都知道复盘很重要 &#x1f449; 但几乎没人愿意写 我问了一个问题&#xff1a; “为什么一份复盘总是要写那么久&#xff1f;” 总结下来基本都是这几个原因&…...

openclaw喂饭教程!在 Linux 环境下快速完成安装、初始化与 Web UI 配置

基础示例&#xff1a;单工作表 Excel 转 TXT 以下是将一个 Excel 文件中的第一个工作表转换为 TXT 的完整步骤&#xff1a; 1. 加载并读取Excel文件 from spire.xls import * from spire.xls.common import * workbook Workbook() workbook.LoadFromFile("示例.xlsx"…...

避坑指南:华三vFW2000在ESXI虚拟机中的常见安装错误与解决方案

华三vFW2000虚拟防火墙在ESXI环境部署的深度排错手册 当你在深夜的机房盯着ESXI控制台里反复报错的vFW2000安装界面时&#xff0c;那种焦灼感我深有体会。去年某金融客户数据中心迁移项目中&#xff0c;我们团队连续遭遇了镜像校验失败、存储空间分配异常、虚拟网卡绑定错误等…...

从智能家居到工业传感:实战解析蓝牙Mesh组网与BLE定位(蓝牙5.x新特性避坑指南)

从智能家居到工业传感&#xff1a;实战解析蓝牙Mesh组网与BLE定位&#xff08;蓝牙5.x新特性避坑指南&#xff09; 在智能家居设备遍地开花的今天&#xff0c;蓝牙技术早已突破耳机、手环等消费电子产品的局限&#xff0c;悄然渗透到工业自动化、资产追踪和智慧楼宇等专业领域。…...

Z-Image-Turbo-辉夜巫女材质与光影专题:金属、玻璃、织物等不同质感的极致渲染

Z-Image-Turbo-辉夜巫女材质与光影专题&#xff1a;金属、玻璃、织物等不同质感的极致渲染 你有没有想过&#xff0c;为什么有些AI生成的图片看起来“假假的”&#xff0c;一眼就能认出来&#xff1f;很多时候&#xff0c;问题就出在“质感”上。金属不像金属&#xff0c;玻璃…...

CodeHub:解锁3大效率革命,重新定义GitHub项目管理体验

CodeHub&#xff1a;解锁3大效率革命&#xff0c;重新定义GitHub项目管理体验 【免费下载链接】CodeHub A UWP GitHub Client 项目地址: https://gitcode.com/gh_mirrors/code/CodeHub 作为开发者&#xff0c;你是否曾在GitHub网页版中迷失于多标签页切换的混乱&#x…...

如何实现Android视频下载器的高效协程调度:Seal下载器的性能优化终极指南

如何实现Android视频下载器的高效协程调度&#xff1a;Seal下载器的性能优化终极指南 【免费下载链接】Seal &#x1f9ad; Video/Audio Downloader for Android, based on yt-dlp, designed with Material You 项目地址: https://gitcode.com/gh_mirrors/se/Seal Seal是…...