嵌入式Linux驱动开发(同步与互斥专题)(二)

news2025/1/1 10:48:24

一、自旋锁spinlock的实现

自旋锁,顾名思义:自己在原地打转,等待资源可用,一旦可用就上锁霸占它。
① 原地打转的是CPU x,以后CPU y会解锁:这涉及多个CPU,适用于SMP系统;
② 对于单CPU系统,自旋锁的“自旋”功能就去掉了:只剩下禁止抢占、禁止中断

要理解spinlock,要通过2个情景来分析:
① 一开始,怎么争抢资源?不能2个程序都抢到。
这挺好解决,使用原子变量就可以实现。
② 某个程序已经获得资源,怎么防止别人来同时使用这个资源。
这是使用spinlock时要注意的地方,对应会有不同的衍生函数(_bh/_irq/_irqsave/_restore)。

1.1、自旋锁的内核结构体

在这里插入图片描述
上述__raw_tickets结构体中有owner、next两个成员,这是在SMP系统中实现spinlock的关键。

1.2、spinlock在单CUP系统中的实现

对于单CPU系统,没有“其他CPU”;如果内核不支持preempt,当前在内核态执行的线程也不可能被其他线程抢占,也就“没有其他进程/线程”。所以,对于不支持preempt的单CPU系统,spin_lock是空函数,不需要做其他事情。

如果单CPU系统的内核支持preempt,即当前线程正在执行内核态函数时,它是有可能被别的线程抢占的。这时spin_lock的实现就是调用“preempt_disable()”:你想抢我,我干脆禁止你运行。
在单CUP系统中,spin_lock函数定义如下:
在这里插入图片描述
对于spin_lock_irq(),在UP系统中就退化为local_irq_disable()和preempt_disable(),如下图所示:
在这里插入图片描述
对于spin_lock_bh(),在UP系统中就退化为禁止软件中断和preempt_disable(),如下图所示:
在这里插入图片描述
对于spin_lock_irqsave,它跟spin_lock_irq类似,只不过它是先保存中断状态再禁止中断,如下:

在这里插入图片描述

1.3、spinlock在SMP系统中的实现

在ARMv6及以上的ARM架构中,支持SMP系统。它的spinlock结构体定义如下:
在这里插入图片描述
spin_lock函数调用关系如下,核心是arch_spin_lock:
在这里插入图片描述
arch_spin_lock代码如下:
在这里插入图片描述
假设第1个程序取到了号码,它访问了临界资源后,调用spin_unlock,代码如下:
在这里插入图片描述
我借用这篇文章的例子讲解,餐厅里只有一个座位,去吃饭的人都得先取号、等叫号。注意,有2个动作:顾客从取号机取号,电子叫号牌叫号。
① 一开始取号机待取号码为0
② 顾客A从取号机得到号码0,电子叫号牌显示0,顾客A上座;
取号机显示下一个待取号码为1。
③ 顾客B从取号机得到号码1,电子叫号牌还显示为0,顾客B等待;
取号机显示下一个待取号码为2。
④ 顾客C从取号机得到号码2,电子叫号牌还显示为0,顾客C等待;
取号机显示下一个待取号码为3。
⑤ 顾客A吃完离座,电子叫号牌显示为1,顾客B的号码等于1,他上座;
⑥ 顾客B吃完离座,电子叫号牌显示为2,顾客C的号码等于2,他上座;
在这个例子中有2个号码:取号机显示的“下一个号码”,顾客取号后它会自动加1;电子叫号牌显示“当前号码”,顾客离座后它会自动加1。某个客户手上拿到的号码等于电子叫号牌的号码时,该客户上座。
在这个过程中,即使顾客B、C同时到店,只要保证他们从取号机上得到的号码不同,他们就不会打架。
所以,关键点在于:取号机的号码发放,必须互斥,保证客户的号码互不相同。而电子叫号牌上号码的变动不需要保护,只有顾客离开后它才会变化,没人争抢它。

1.4、信号量semaphore的实现

1.4.1、semaphore的内核结构体

信号量的定义及操作函数都在Linux内核文件include\linux\semaphore.h中定义,如下:
在这里插入图片描述
初始化semaphore之后,就可以使用down函数或其他衍生版本来获取信号量,使用up函数释放信号量。

1.4.2、down函数的实现

如果semaphore中的count大于0,那么down函数就可以获得信号量;否则就休眠。在读取、修改count时,要使用spinlock来实现互斥。
休眠时,要把当前进程放在semaphore的wait_list链表中,别的进程释放信号量时去wait_list中把进程取出、唤醒。
代码如下:
在这里插入图片描述

1.4.3、 up函数的实现

如果有其他进程在等待信号量,则count值无需调整,直接取出第1个等待信号量的进程,把信号量给它,共把它唤醒。
如果没有其他进程在等待信号量,则调整count。
整个过程需要使用spinlock来保护,代码如下:
在这里插入图片描述

1.5、互斥量mutex的实现

1.5.1、mutex的内核结构体

mutex的定义及操作函数都在Linux内核文件include\linux\mutex.h中定义,如下:
在这里插入图片描述
我们使用mutex的目的一般是用来保护一小段代码,这段代码运行的时间很快。这意味着一个获得mutex的进程,可能很快就会释放掉mutex。

1.5.2、mutex_lock函数的实现

1.5.2.1、fastpath

首先要知道mutex的操作函数中有fastpath、slowpath两条路径(快速、慢速):如果fastpath成功,就不必使用slowpath。

在这里插入图片描述
对于ARMv6以下的架构,使用include/asm-generic/mutex-xchg.h中的__mutex_fastpath_lock函数;对于ARMv6及以上的架构,使用include/asm-generic/mutex-dec.h中的__mutex_fastpath_lock函数。这2个文件中的__mutex_fastpath_lock函数是类似的,mutex-dec.h中的代码如下:
在这里插入图片描述
大部分情况下,mutex当前值都是1,所以通过fastpath函数可以非常快速地获得mutex。

1.5.2.1、slowpath

如果mutex当前值是0或负数,则需要调用__mutex_lock_slowpath慢慢处理:可能会休眠等待。
在这里插入图片描述
__mutex_lock_common函数也是在内核文件kernel/locking/mutex.c中实现的,下面分段讲解。

① 分析第一段代码:
在这里插入图片描述
② 分析第二段代码:
在这里插入图片描述
③ 分析第三段代码:
在这里插入图片描述
这个wait_list是FIFO(Firt In Firs Out),谁先排队,谁就可以先得到mutex。

④ 分析第四段代码:for循环,这是重点
在这里插入图片描述
⑤ 分析第五段代码:收尾工作
在这里插入图片描述

1.5.3、mutex_unlock函数的实现

mutex_unlock函数中也有fastpath、slowpath两条路径(快速、慢速):如果fastpath成功,就不必使用slowpath。
代码如下:
在这里插入图片描述

1.5.3.1、fastpath

对于ARMv6以下的架构,使用include/asm-generic/mutex-xchg.h中的__mutex_fastpath_lock函数;对于ARMv6及以上的架构,使用include/asm-generic/mutex-dec.h中的__mutex_fastpath_lock函数。这2个文件中的__mutex_fastpath_lock函数是类似的,mutex-dec.h中的代码如下:
在这里插入图片描述
大部分情况下,加1后mutex的值都是1,表示无人等待mutex,所以通过fastpath函数直接增加mutex的count值为1就可以了。
如果mutex的值加1后还是小于等于0,就表示有人在等待mutex,需要去wait_list把它取出唤醒,这需要用到slowpath的函数:__mutex_unlock_slowpath。

1.5.3.2 、slowpath

在这里插入图片描述
__mutex_unlock_common_slowpath函数代码如下,主要工作就是从wait_list中取出并唤醒第1个进程:
在这里插入图片描述

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

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

相关文章

【Vue】Router路由无法跳转问题整理

问题集 整理了部分Vue Router路由无法跳转问题: 顶层router-view只能被顶层路由配置内容使用:此问题异常表现在路由跳转但页面不变子路由跳转必需父路由对应的组件中存在router-view:此问题异常表现在路由跳转但页面不变 子路由配置路径会自…

uniapp项目实践总结(十三)封装文件操作方法

导语:在日常 APP 开发过程中,经常要进行文件的保存、读取列表以及查看和删除文件等操作,接下来就看一下具体的方法。 目录 原理分析方法实现实战演练案例展示 原理分析 主要是以下 API。 uni.saveFile:保存文件到本地缓存列表…

处理流程设计-系统设计-人机界面设计

处理流程设计-系统设计-人机界面设计 流程表示工具(重点) 流程表示工具(重点) 数据流图也是一种 IPO 图 NS图和PAD图

为什么说电子元器件采购如果不够专业就容易上当受骗

电子元器件采购如果不够专业就容易上当受骗的原因有多方面,主要包括以下几点: 众多供应商和产品:电子元器件市场涉及众多供应商和各种不同的产品。如果采购人员不具备足够的专业知识和经验,可能会难以识别哪些供应商和产品是可信赖…

flink 写入数据到 kafka 后,数据过一段时间自动删除

版本 flink 1.16.0kafka 2.3 流程描述: flink利用KafkaSource,读取kafka的数据,然后经过一系列的处理,通过KafkaSink,采用 EXACTLY_ONCE 的模式,将处理后的数据再写入到新的topic中。 问题描述&#xff1…

【SpringMVC]获取参数的六种方式

目录 1.通过ServletAPI获取 2.通过控制器方法的形参获取 3.RequestParam:将请求参数和控制器方法的形参绑定 4.RequestHeader:将请求头信息与控制器方法的形参的值进行绑定 5. CookieValue:将cookie数据和控制器方法的形参绑定 Cookie&…

入门人工智能 —— 学习一门编程语言 python 基础代码编写和运算符介绍(1)

入门人工智能 —— 学习一门编程语言 python(1) 入门流程1.安装pythonwindowslinux ubuntu 代码编写打印输出结果 基本加减法介绍基本运算符 随着人工智能技术的快速发展,越来越多的年轻人开始关注这个领域。作为入门者,学习人工智…

文心一言 VS 讯飞星火 VS chatgpt (88)-- 算法导论8.3 1题

一、用go语言,参照图 8-3 的方法,说明 RADIX-SORT在下列英文单词上的操作过程:COW,DOG,SEA,RUG,ROW,MOB, BOX, TAB, BAR, EAR,TAR&…

Java基于 SpringBoot 的车辆充电桩系统

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 1、效果演示效果图技术栈 2、 前言介绍(完整源码请私聊)3、主要技术3.4.1 …

AI人工智能Mojo语言:AI的新编程语言

推荐:使用 NSDT场景编辑器 快速搭建3D应用场景 Mojo的主要功能包括: 类似Python的语法和动态类型使Python开发人员易于学习Mojo,因为Python是现代AI / ML开发背后的主要编程语言。使用Mojo,您可以导入和使用任何Python库&#xf…

2.8 PE结构:资源表详细解析

在Windows PE中,资源是指可执行文件中存放的一些固定不变的数据集合,例如图标、对话框、字符串、位图、版本信息等。PE文件中每个资源都会被分配对应的唯一资源ID,以便在运行时能够方便地查找和调用它们。PE文件中的资源都被组织成一个树形结…

“链主品牌”竞争战略四大误区

在《财富》500 强企业名单中,2008 年中国企业仅有 37 家,而 2019 年攀升至 119 家,与美国仅相差两家。2008 年,中国关注的问题是其在世界 500 强榜单上的企业数量太少。而如今的讨论则集中在为何中国企业规模大却实力不强。原因在…

有哪些做流程图的软件?分享一些制作方法和注意事项

流程图是一种常用的图表,可以用于表示各种工作流程、系统架构、决策流程等。在现代工作生活中,制作流程图已经成为了必备的技能之一。本文将介绍一些常用的做流程图的工具,并分享一些制作方法和注意事项。 做流程图的工具 1.迅捷画图&#x…

Node.js安装教程图文详解

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 下载Node.js 请下载Node.js并保存至本地,官方网址:https://nodejs.org/zh-cn/ 在此,选择windows系统64位的16.13.1版本进行下载。 下载…

【SLAM】Sophus库的超详细解析

在视觉SLAM中,李群李代数是描述位姿比较常用的一种表达形式。但是,在Eigen中并不提供对它的支持,一个较好的李群和李代数的库是Sophus库,它很好的支持了SO3、so3、SE3、se3。 Sophus简介 代码仓库:https://github.com…

laravel系列(二) Dcat admin框架开发工具使用

开发工具可以非常好的帮助我们去快速的开发CURD等操作,但也是有部分框架有些不是太便捷操作,这篇博客主要为大家介绍Dcat admin的开发工具详细使用. 如何创建页面: 在联表我们首先要去.env文件中去找连接数据库方法: APP_NAMELaravel APP_ENVlocal APP_KEYbase64:thO0lOVlzj0…

机器学习入门教学——人工智能、机器学习、深度学习

1、人工智能 人工智能相当于人类的代理人,我们现在所接触到的人工智能基本上都是弱AI,主要作用是正确解释从外部获得的数据,并对这些数据加以学习和利用,以便灵活的实现特定目标和任务。例如: 阿尔法狗、智能汽车简单…

苹果跨入“迷你超级周期”:iPhone15Pro占比提升75%,性价比高?

据美国投行韦德布什证券的分析师Daniel Ives最近发布的投资者报告,苹果公司今年推出的iPhone 15机型比例已经从往年的3:2调整为了3:1,这标志着苹果公司跨入了“迷你超级周期”。 分析师郭明錤曾预测,今年iPhone 15系列…

【深度学习】 Python 和 NumPy 系列教程(二):Python基本数据类型:3、字符串(索引、切片、运算、格式化)

目录 一、前言 二、实验环境 三、Python基本数据类型 3. 字符串(Strings) 1. 初始化 2. 索引 3. 切片 4. 运算 a. 拼接运算 b. 复制运算 c. 子串判断 d. 取长度 5. 格式化 a. 使用位置参数 b. 使用关键字参数 c. 使用属性访问 f-string…

在家也能轻松使用用友畅捷通T3管理财务,实现高效率远程办公!

文章目录 前言1. 用友畅捷通T3借助cpolar实现远程办公1.1 在被控端电脑上,点击开始菜单栏,打开设置——系统1.2 找到远程桌面1.3 启用远程桌面 2. 安装cpolar内网穿透2.1 注册cpolar账号2.2 下载cpolar客户端 3. 获取远程桌面公网地址3.1 登录cpolar web…