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  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/68121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux的基本指令(上)

1.ls指令 语法:ls [选项] [目录或文件] 功能:对于⽬录,该命令列出该⽬录下的所有⼦⽬录与⽂件。对于⽂件,将列出⽂件名以及其他信息。 常用选项: -a 列出⽬录下的所有⽂件,包括以 . 开头的隐含⽂件。 -d 将…

基于Springboot用axiospost请求接收字符串参数为null的解决方案

问题 ​ 今天在用前端 post 请求后端时发现,由于是以 Json对象的形式传输的,后端用两个字符串形参无法获取到对应的参数值 前端代码如下: axios.post(http://localhost:8083/test/postParams,{a: 1, b:2} ,{Content-Type: application/jso…

ios打包:uuid与udid

ios的uuid与udid混乱的网上信息 新人开发ios,发现uuid和udid在网上有很多帖子里是混淆的,比如百度下,就会说: 在iOS中使用UUID(通用唯一识别码)作为永久签名,通常是指生成一个唯一标识&#xf…

【豆包MarsCode 蛇年编程大作战】蛇形烟花

项目体验地址:项目体验地址 官方活动地址:活动地址 目录 【豆包MarsCode 蛇年编程大作战】蛇形烟花演示 引言 豆包 MarsCode介绍 项目准备 第一步:安装插件 第二步:点击豆包图标来进行使用豆包 使用豆包 MarsCodeAI助手实…

leetcode151-反转字符串中的单词

leetcode 151 思路 时间复杂度:O(n) 空间复杂度:O(n) 首先将字符串转为数组,这样可以方便进行操作,然后定义一个新的数组来存放从后到前的单词,由于arr中转换以后可能会出现有些项是空格的情况,所以需要判…

Precharge和Self-refresh的区别

一、区别说明 操作目标: Precharge(预充电):此操作的主要目标是关闭存储器中某个或所有Bank中现有的工作行(active row),并准备打开新的工作行。这是为了确保存储器的连续访问能够高效、可靠地进…

基于本地事务表+MQ实现分布式事务

基于本地事务表MQ实现分布式事务 引言1、原理2、本地消息表优缺点3、代码实现3.1、代码执行流程3.2、项目结构3.3、项目源码 引言 本地消息表的方案最初由ebay的工程师提出,核心思想是将分布式事务拆分成本地事务进行处理。本地消息表实现最终一致性。本文主要学习…

HTML<label>标签

例子 三个带标签的单选按钮&#xff1a; <form action"/action_page.php"> <input type"radio" id"html" name"fav_language" value"HTML"> <label for"html">HTML</label><br&…

2025,“鱿鱼游戏”闯入AI赛道

文 | 智能相对论 作者 | 叶远风 “鱿鱼游戏”一词随着同名剧集的火爆而持续走红&#xff0c;在全球范围掀起了广泛热议。而这种无限生存流的游戏模式&#xff0c;既残酷又现实&#xff0c;像极了商业市场的搏杀与淘汰。 1月20日&#xff0c;DeepSeek发布了全新的开源推理大模…

Prometheus+grafana实践:Doris数据库的监控

文章来源&#xff1a;乐维社区 Doris数据库背景 Doris&#xff08;Apache Doris&#xff09;是一个现代化的MPP&#xff08;Massive Parallel Processing&#xff0c;大规模并行处理&#xff09;数据库&#xff0c;主要用于在线分析处理&#xff08;OLAP&#xff09;场景。 D…

【unity游戏开发之InputSystem——02】InputAction的使用介绍(基于unity6开发介绍)

文章目录 前言一、InputAction简介1、InputAction是什么&#xff1f;2、示例 二、监听事件started 、performed 、canceled1、启用输入检测2、操作监听相关3、关键参数 CallbackContext4、结果 三、InputAction参数相关1、点击齿轮1.1 Actions 动作&#xff08;1&#xff09;动…

从Spring请求处理到分层架构与IOC:注解详解与演进实战

引言 在Spring开发中&#xff0c;请求参数处理、统一响应格式、分层架构设计以及依赖管理是构建可维护应用的核心要素。然而&#xff0c;许多开发者在实践中常面临以下问题&#xff1a; 如何规范接收不同格式的请求参数&#xff1f; 为何要引入分层架构&#xff1f; 什么是控…

详解Redis的Zset类型及相关命令

目录 Zset简介 ZADD ZCARD ZCOUNT ZRANGE ZREVRANGE ZRANGEBYSCORE ZPOPMAX BZPOPMAX ZPOPMIN BZPOPMIN ZRANK ZREVRANK ZSCORE ZREM ZREMRANGEBYRANK ZREMRANGEBYSCORE ZINCRBY ZINTERSTORE 内部编码 应用场景 Zset简介 有序集合相对于字符串、列表、哈希…

Node.js下载安装及环境配置教程 (详细版)

Node.js&#xff1a;是一个基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;用于构建可扩展的网络应用程序。Node.js 使用事件驱动、非阻塞 I/O 模型&#xff0c;使其非常适合构建实时应用程序。 Node.js 提供了一种轻量、高效、可扩展的方式来构建网络应用程序&#xff0…

日志收集Day005

1.filebeat的input类型之filestream实战案例: 在7.16版本中已经弃用log类型,之后需要使用filebeat,与log不同&#xff0c;filebeat的message无需设置就是顶级字段 1.1简单使用&#xff1a; filebeat.inputs: - type: filestreamenabled: truepaths:- /tmp/myfilestream01.lo…

Vue中设置报错页面和“Uncaught runtime errors”弹窗关闭

文章目录 前言操作步骤大纲1.使用Vue自带的报错捕获机制添加报错信息2.在接口报错部分添加相同机制3.把报错信息添加到Vuex中方便全局使用4.添加报错页面备用5.app页面添加if判断替换报错界面 效果备注&#xff1a;vue项目中Uncaught runtime errors:怎样关闭 前言 在开发Vue项…

01、硬件设计常用经典电路

前言 一直想入职嵌入式软件&#xff0c;但是25年作为学历一般的应届生真是太难了&#xff0c;于是今年实习就不想跑太远了&#xff0c;就在老家5线小城市进入了一家小企业&#xff0c;当电子工程师实习&#xff08;学徒&#xff09;。 抱着入职什么&#xff0c;就学习什么的态…

使用Cline+deepseek实现VsCode自动化编程

不知道大家有没有听说过cursor这个工具&#xff0c;类似于AIVsCode的结合体&#xff0c;只要绑定chatgpt、claude等大模型API&#xff0c;就可以实现对话式自助编程&#xff0c;简单闲聊几句便可开发一个软件应用。 但cursor受限于外网&#xff0c;国内用户玩不了&#xff0c;…

微信小程序中常见的 跳转方式 及其特点的表格总结(wx.navigateTo 适合需要返回上一页的场景)

文章目录 详细说明总结wx.navigateTo 的特点为什么 wx.navigateTo 最常用&#xff1f;其他跳转方式的使用频率总结 以下是微信小程序中常见的跳转方式及其特点的表格总结&#xff1a; 跳转方式API 方法特点适用场景wx.navigateTowx.navigateTo({ url: 路径 })保留当前页面&…

[Unity 热更方案] 使用Addressable进行打包管理, 使用AssetBundle进行包的加载管理.70%跟练

在正常的开发过程中我们经常遇到一些关于热更的方案,有一些已有的方案供我们选择,但是实机情况往往不尽如人意,各有优缺点. 现在我们同样有一个热更的需求,但是要求打包简单,加载过程可查,防止出现一些资源和流程的问题. 下面介绍我在项目中使用的方案. 打包方面使用Addressabl…