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

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,2hrtimer_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  }3hrtimer_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  }4hrtimer_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创作平台&#xff0c…...

大数据学习之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根据接口给的省市区的数据实现省市区三级联动或者省市区街道等多级联动

接口数据如上图 省市区多级联动&#xff0c;都是使用的一个接口通过传参父类的code。返回我们想要的数据 比如获取省就直接不要参数。市就把省得code传给接口&#xff0c;区就把市的code作为参数。 <picker mode"multiSelector" :range"mulSelect1" …...

Go Fx 框架使用指南:深入理解 Provide 和 Invoke 的区别

1. 什么是 Fx 框架&#xff1f; Fx 是一个基于 Go 语言的依赖注入框架&#xff0c;专注于简化应用程序的生命周期管理和依赖的构建。在复杂的应用程序中&#xff0c;Fx 通过模块化的设计方式将组件连接起来&#xff0c;使开发者能够更高效地管理依赖关系。 Fx 的核心理念是&a…...

VSCode+Continue实现AI辅助编程

Continue是一款功能强大的AI辅助编程插件&#xff0c;可连接多种大模型&#xff0c;支持代码设计优化、错误修正、自动补全、注释编写等功能&#xff0c;助力开发人员提高工作效率与代码质量。以下是其安装和使用方法&#xff1a; 一、安装VSCode 参见&#xff1a; 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开发中&#xff0c;Razor 组件具备两种重要的呈现方式&#xff0c;分别是静态呈现和交互式呈现。 静态呈现 也被称为静态渲染&#xff0c;是一种典型的服务器端方案。在这种模式下&#xff0c;组件呈现时&#xff0c;用户与.NET/C# 代码之间缺…...

14-6-2C++的list

(一&#xff09;list对象的带参数构造 1.list&#xff08;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;"…...

激光雷达和相机早期融合

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

PMP–一、二、三模–分类–12.采购管理

文章目录 技巧十二、采购管理 一模12.采购管理--3.控制采购--输出--风险登记册--每个被选中的卖方都会带来特殊的风险。随着早期风险的过时以及新风险的出现&#xff0c;在项目执行期间对风险登记册进行变更。 供应商还未开始做&#xff0c;是一个风险&#xff0c;当做风险进行…...

C++ 标准模板库 (STL, Standard Template Library)

声明&#xff1a;大佬们~这是Tubishu在追寻stl过程中偶然得到了“颢天”大佬的笔记&#xff0c;shushu感觉非常有帮助&#x1f525;又颢天佬未曾来过CSDN&#xff0c;索性在此传达颢天大佬的功德&#x1f9ce; 传送门在此➡️颢天笔记✨✨ C 标准模板库 (STL, Standard Templa…...

从spec到iso的koji使用

了解一下Linux发行版流程&#xff1a;:从spec到iso的koji使用 for Fedora 41。 Fedora 41有24235个包&#xff0c;我们选择 minimal 的几十个源码包&#xff0c;百多个rpm包构建。 配3台服务器 40C64G 48C64G 80C128G&#xff0c;有点大材小用&#xff0c;一台就够了 &#xf…...

【记录自开发的SQL工具】工具字符拼接、Excel转sql、生成编码、生成测试数据

记录自己开发的一个SQL聚合工具 功能介绍&#xff1a; 文本加引号 给多行文本前后添加引号&#xff0c;并用逗号连接&#xff0c;直接复制到 sql 中的 in 条件中 Excel转SQL 适用于将Excel表格的数据&#xff0c;批量导入到数据库的场景 此工具能快速将excel表格转换为i…...

Cesium特效——城市白模的科技动效的各种效果

最终效果图如下&#xff1a; 实现方法&#xff1a; 步骤一&#xff1a;使用cesiumlib生产白模&#xff0c;格式为3dtiles 注意事项&#xff1a;采用其他方式可能导致白模贴地&#xff0c;从而导致不能实现该效果&#xff0c;例如把步骤二的服务地址改为Cesium Sandcastle 里的…...

VS Code i18n国际化组件代码code显示中文配置 i18n ally

VUE项目做i18n国际化之后&#xff0c;代码中的中文都变成了code这时的代码就会显得非常难读&#xff0c;如果有一个插件能把code转换成中文显示就好了 vscode插件搜索“i18n ally” 在项目根文件夹下创建文件&#xff1a;.vscode/settings.json settings.json 内容如下 {"…...

C++ —— 智能指针 unique_ptr (上)

C —— 智能指针 unique_ptr &#xff08;上&#xff09; 普通指针的不足普通指针的释放智能指针智能指针 unique_ptr智能指针初始化错误用法get()方法返回裸指针智能指针不支持指针的运算&#xff08;、-、、- -&#xff09; 普通指针的不足 new和new [] 的内存需要用delete和…...

技术 · 创作 · 生活 | 我的 2024 全面复盘

目录 &#x1f31f;2024年度总结&#xff1a;回顾、成长与突破&#x1f31f;&#x1f680; 一、技术成长与突破 &#x1f680;&#x1f517; 1. 深入区块链与智能合约&#x1f50d; 2. 探索新兴技术 ✍️ 二、创作与博客历程 ✍️&#x1f4d6; 1. 内容创作的演变&#x1f3c6;…...

表的增删改查(MySQL)

1. 表的增删改查 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09; 1.1 Create 语法&#xff1a; INSERT [INTO] table_name [(column [, column] ...)] VALUES (value_list) [, (value_list)] ...value_list:…...

【设计模式】JAVA 策略 工厂 模式 彻底告别switch if 等

【设计模式】JAVA 策略 工厂 模式 彻底告别switch if 等 目录 【设计模式】JAVA 策略 工厂 模式 彻底告别switch if 等 优势 适用场景 项目结构 关键代码 优势 消除 switch&#xff1a;将分支逻辑分散到独立的策略类中。 开闭原则&#xff1a;新增类型只需添加新的 TypeHa…...