Linux-rt下卡死之hrtimer分析
Linux-rt下卡死之hrtimer分析
日志
超时读过程分析
#define readl_poll_timeout(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout(readl, addr, val, cond, delay_us, timeout_us)34 #define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \
35 ({ \
36 u64 __timeout_us = (timeout_us); \
37 unsigned long __sleep_us = (sleep_us); \
38 ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
39 might_sleep_if((__sleep_us) != 0); \
40 for (;;) { \
41 (val) = op(addr); \
42 if (cond) \
43 break; \
44 if (__timeout_us && \
45 ktime_compare(ktime_get(), __timeout) > 0) { \
46 (val) = op(addr); \
47 break; \
48 } \
49 if (__sleep_us) \
50 usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
51 } \
52 (cond) ? 0 : -ETIMEDOUT; \
53 })2375 void __sched usleep_range(unsigned long min, unsigned long max)
2376 {
2377 ktime_t exp = ktime_add_us(ktime_get(), min);
2378 u64 delta = (u64)(max - min) * NSEC_PER_USEC;
2379
2380 for (;;) {
2381 __set_current_state(TASK_UNINTERRUPTIBLE); //设置当前进程为不可中断状态
2382 /* Do not return before the requested sleep time has elapsed */
2383 if (!schedule_hrtimeout_range(&exp, delta, HRTIMER_MODE_ABS)) //注意这个hrtimer_mode 在rt-linux中有很大用处
2384 break;
2385 }
2386 }
2387 EXPORT_SYMBOL(usleep_range);2172 int __sched schedule_hrtimeout_range(ktime_t *expires, u64 delta, const enum hrtimer_mode mode)
2174 {
2175 return schedule_hrtimeout_range_clock(expires, delta, mode, CLOCK_MONOTONIC); //CLOCK_MONOTONIC:clock_id
2177 }
2178 EXPORT_SYMBOL_GPL(schedule_hrtimeout_range);2275 int __sched
2276 schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta,
2277 const enum hrtimer_mode mode, clockid_t clock_id)
2278 {
2279 struct hrtimer_sleeper t;
2280
2281 /*
2282 * Optimize when a zero timeout value is given. It does not
2283 * matter whether this is an absolute or a relative time.
2284 */
2285 if (expires && *expires == 0) {
2286 __set_current_state(TASK_RUNNING);
2287 return 0;
2288 }
2289
2290 /*
2291 * A NULL parameter means "infinite"
2292 */
2293 if (!expires) {
2294 schedule();
2295 return -EINTR;
2296 }// 实时任务,设置延迟时间为0,时间更精确
2302 if (rt_task(current))
2303 delta = 0;
2304
2305 hrtimer_init_sleeper_on_stack(&t, clock_id, mode);
2306 hrtimer_set_expires_range_ns(&t.timer, *expires, delta);
2307 hrtimer_sleeper_start_expires(&t, mode);
2308
2309 if (likely(t.task))
2310 schedule();
2311
2312 hrtimer_cancel(&t.timer);
2313 destroy_hrtimer_on_stack(&t.timer);
2314
2315 __set_current_state(TASK_RUNNING);
2316
2317 return !t.task ? 0 : -EINTR;
2318 }
2319 EXPORT_SYMBOL_GPL(schedule_hrtimeout_range_clock);
hrtimer定时器分析
1、定义struct hrtimer_sleeper t;
135 struct hrtimer_sleeper {
136 struct hrtimer timer;
137 struct task_struct *task;
138 };
38 enum hrtimer_mode {
39 HRTIMER_MODE_ABS = 0x00,
40 HRTIMER_MODE_REL = 0x01,
41 HRTIMER_MODE_PINNED = 0x02,
42 HRTIMER_MODE_SOFT = 0x04,
43 HRTIMER_MODE_HARD = 0x08,2、hrtimer_init_sleeper_on_stack(&t, clock_id, mode);
443 void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl,
444 clockid_t clock_id, enum hrtimer_mode mode)
445 {
446 debug_object_init_on_stack(&sl->timer, &hrtimer_debug_descr);
447 __hrtimer_init_sleeper(sl, clock_id, mode);
448 }
449 EXPORT_SYMBOL_GPL(hrtimer_init_sleeper_on_stack);1799 static void __hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
1800 clockid_t clock_id, enum hrtimer_mode mode)
1801 {
1821 if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
1822 if (task_is_realtime(current) && !(mode & HRTIMER_MODE_SOFT))
1823 mode |= HRTIMER_MODE_HARD; //根据上边的分析,此处会设置为硬中断上下文进行回调
1824 }
1825
1826 __hrtimer_init(&sl->timer, clock_id, mode); //初始化hrtimer
1827 sl->timer.function = hrtimer_wakeup; //唤醒函数
1828 sl->task = current; //当前进程
1829 }1376 static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
1377 enum hrtimer_mode mode)
1378 {
1379 bool softtimer = !!(mode & HRTIMER_MODE_SOFT); //由上可知此处为false
1380 struct hrtimer_cpu_base *cpu_base;
1381 int base;1389 if (IS_ENABLED(CONFIG_PREEMPT_RT) && !(mode & HRTIMER_MODE_HARD))
1390 softtimer = true;
1391
1392 memset(timer, 0, sizeof(struct hrtimer));
1393
1394 cpu_base = raw_cpu_ptr(&hrtimer_bases);
1395 1401 if (clock_id == CLOCK_REALTIME && mode & HRTIMER_MODE_REL)
1402 clock_id = CLOCK_MONOTONIC;
1403
1404 base = softtimer ? HRTIMER_MAX_CLOCK_BASES / 2 : 0;
1405 base += hrtimer_clockid_to_base(clock_id);
1406 timer->is_soft = softtimer; //false
1407 timer->is_hard = !softtimer; //true
1408 timer->base = &cpu_base->clock_base[base];
1409 timerqueue_init(&timer->node); //加入定时队列
1410 }3、hrtimer_set_expires_range_ns(&t.timer, *expires, delta);
251 static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, u64 delta)
252 {
253 timer->_softexpires = time; //软超时时间
254 timer->node.expires = ktime_add_safe(time, ns_to_ktime(delta)); //超时范围
255 }4、hrtimer_sleeper_start_expires(&t, mode);
1782 void hrtimer_sleeper_start_expires(struct hrtimer_sleeper *sl,
1783 enum hrtimer_mode mode)
1784 {
1792 if (IS_ENABLED(CONFIG_PREEMPT_RT) && sl->timer.is_hard)
1793 mode |= HRTIMER_MODE_HARD;
1794
1795 hrtimer_start_expires(&sl->timer, mode);
1796 }
1797 EXPORT_SYMBOL_GPL(hrtimer_sleeper_start_expires);426 static inline void hrtimer_start_expires(struct hrtimer *timer,
427 enum hrtimer_mode mode)
428 {
429 u64 delta;
430 ktime_t soft, hard;
431 soft = hrtimer_get_softexpires(timer);
432 hard = hrtimer_get_expires(timer);
433 delta = ktime_to_ns(ktime_sub(hard, soft));
434 hrtimer_start_range_ns(timer, soft, delta, mode);
435 }
相关文章:

Linux-rt下卡死之hrtimer分析
Linux-rt下卡死之hrtimer分析 日志 超时读过程分析 #define readl_poll_timeout(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout(readl, addr, val, cond, delay_us, timeout_us)34 #define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \…...
【AI日记】25.01.24
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】【读书与思考】 AI kaggle 比赛:Forecasting Sticker Sales 读书 书名:法治的细节作者:罗翔 律己 AI:8 小时,良作息:00:30-8:30&…...
React 中hooks之useSyncExternalStore使用总结
1. 基本概念 useSyncExternalStore 是 React 18 引入的一个 Hook,用于订阅外部数据源,确保在并发渲染下数据的一致性。它主要用于: 订阅浏览器 API(如 window.width)订阅第三方状态管理库订阅任何外部数据源 1.1 基…...
C++11新特性之decltype
1.decltype的作用 decltype是C11新增的一个关键字,与auto的功能一样,都是在编译期间推导变量类型的。不了解auto的可以转到——C11新特性之auto。 为什么引入decltype?看过上边那篇博客的读者应该知道auto在有些场景中并不适用,所以引入declt…...

二叉树相关oj题 1. 检查两颗树是否相同。
二叉树相关oj题 检查两颗树是否相同。OJ链接 另一颗树的子树。OJ链接 if(rootnull)易漏掉 会导致空指针异常翻转二叉树。OJ链接...

element tbas增加下拉框
使用Tabs 标签页的label插槽,嵌入Dropdown 下拉菜单,实现Tabs 标签页增加下拉切换功能 Tabs 标签页 tab-click"事件"(这个事件当中到拥有下拉框的tab里时,可以存一下Dropdown 第一个菜单的id,实现点击到拥有…...
新浪安卓(Android)开发面试题及参考答案(68道题,9道手撕题)
链表判环,找入口 思路: 判断是否有环:使用快慢指针,快指针每次走两步,慢指针每次走一步,如果它们相遇,说明有环。找出环入口:当判断出有环后,将慢指针重新指向头节点,然后快慢指针同时以相同速度移动,再次相遇的节点就是环的入口。以下是判断链表是否有环以及找出环…...

Zbrush导入笔刷
Zbrush笔刷目录: ...\Zbrush\ZStartup\BrushPresets...

实战演示:利用ChatGPT高效撰写论文
在当今学术界,撰写论文是一项必不可少的技能。然而,许多研究人员和学生在写作过程中常常感到困惑和压力。幸运的是,人工智能的快速发展为我们提供了新的工具,其中ChatGPT便是一个优秀的选择。本文将通过易创AI创作平台,…...

大数据学习之SCALA分布式语言三
7.集合类 111.可变set一 112.可变set二 113.不可变MAP集合一 114.不可变MAP集合二 115.不可变MAP集合三 116.可变map一 package com . itbaizhan . chapter07 //TODO 2. 使用 mutable.Map 前导入如下包 import scala . collection . mutable // 可变 Map 集合 object Ma…...

k8s简介,k8s环境搭建
目录 K8s简介环境搭建和准备工作修改主机名(所有节点)配置静态IP(所有节点)关闭防火墙和seLinux,清除iptables规则(所有节点)关闭交换分区(所有节点)修改/etc/hosts文件&…...

深入理解MySQL事务(万字详)
文章目录 什么是事务为什么会出现事务事务的版本支持事务的提交方式事务常见操作方式正常演示 - 证明事务的开始与回滚非正常演示1 - 证明未commit,客户端崩溃,MySQL自动会回滚(隔离级别设置为读未提交)非正常演示2 - 证明commit了…...

微信小程序使用picker根据接口给的省市区的数据实现省市区三级联动或者省市区街道等多级联动
接口数据如上图 省市区多级联动,都是使用的一个接口通过传参父类的code。返回我们想要的数据 比如获取省就直接不要参数。市就把省得code传给接口,区就把市的code作为参数。 <picker mode"multiSelector" :range"mulSelect1" …...
Go Fx 框架使用指南:深入理解 Provide 和 Invoke 的区别
1. 什么是 Fx 框架? Fx 是一个基于 Go 语言的依赖注入框架,专注于简化应用程序的生命周期管理和依赖的构建。在复杂的应用程序中,Fx 通过模块化的设计方式将组件连接起来,使开发者能够更高效地管理依赖关系。 Fx 的核心理念是&a…...

VSCode+Continue实现AI辅助编程
Continue是一款功能强大的AI辅助编程插件,可连接多种大模型,支持代码设计优化、错误修正、自动补全、注释编写等功能,助力开发人员提高工作效率与代码质量。以下是其安装和使用方法: 一、安装VSCode 参见: vscode安…...

阿里云服务器在Ubuntu上安装redis并使用
1、redis安装 sudo apt install lsb-release curl gpgcurl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpgecho "deb [signed-by/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.…...
Blazor-Blazor呈现概念
静态和交互式呈现概念 在Blazor开发中,Razor 组件具备两种重要的呈现方式,分别是静态呈现和交互式呈现。 静态呈现 也被称为静态渲染,是一种典型的服务器端方案。在这种模式下,组件呈现时,用户与.NET/C# 代码之间缺…...

14-6-2C++的list
(一)list对象的带参数构造 1.list(elem);//构造函数将n个elem拷贝给本身 #include <iostream> #include <list> using namespace std; int main() { list<int> lst(3,7); list<int>::iterator it; for(itlst.begi…...
StarRocks常用命令
目录 1、StarRocks 集群管理&配置命令 2、StarRocks 常用操作命令 3、StarRocks 数据导入和导出 1、StarRocks 集群管理&配置命令 查询 FE 节点信息 SHOW frontends; SHOW PROC /frontends; mysql -h192.168.1.250 -P9030 -uroot -p -e "SHOW PROC /dbs;"…...

激光雷达和相机早期融合
通过外参和内参的标定将激光雷达的点云投影到图像上。 • 传感器标定 首先需要对激光雷达和相机(用于获取 2D 图像)进行外参和内参标定。这是为了确定激光雷达坐标系和相机坐标系之间的转换关系,包括旋转和平移。通常采用棋盘格等标定工具&…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...