关中断

简介: 关中断

local_irq_enable和local_irq_disable

在单处理器不可抢占系统中,使用local_irq_enable与local_irq_disable是消除异步并发源的有效方式,虽然驱动程序中应该避免使用这两个宏(理山将在本章稍后的内容中给出),但是在spinlock等互斥机制中常常用到这两个宏,所以在此用一节的篇幅来对它们进行介绍。local_irq_enable宏用来打开本地处理器的中断,而local_irq_disable则正好相反,用来关闭处理器的中断。这两个宏的定义如下:

#define local_irq_enable() \
  do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0)
#define local_irq_disable() \
  do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0)

其中trace_hardirqs_on()和trace_hardirqs_off()用做调试,这里重点关注raw_local_irq_enable()和raw_local_irq_disable()。这两个宏的具体实现都依赖于处理器体系架构,不同处理器有不同的指令来启用或者关闭处理器响应外部中断的能力,比如在x86平台上,会最终利用sti和cli指令来分别设置和清除x86处理器中的FLAGS寄存器的IF标志,这样处理器就可以响应或者不响应外部的中断。ARM平台则使用CPSIE指令。

在单处理器不可抢占系统中,如果某段代码要访问某共享资源,那么在进入临界区前使用local_irq_disable来关闭中断,这样在临界区中可保证系统不会出现异步并发源,访问完共享数据在出临界区时,再调用local_irq_enable来启用中断。

local_irq_save与local_irq_restore

local_irq_enable与local_irq_disable还有一种变体,是local_irq_save与local_irq_restore宏定义如下:

#define local_irq_save(flags)       \
  do {            \
    raw_local_irq_save(flags);    \
    trace_hardirqs_off();     \
  } while (0)
#define local_irq_restore(flags)      \
  do {            \
    if (raw_irqs_disabled_flags(flags)) { \
      raw_local_irq_restore(flags); \
      trace_hardirqs_off();   \
    } else {        \
      trace_hardirqs_on();    \
      raw_local_irq_restore(flags); \
    }         \
  } while (0)

这两个宏相对于local_irq_enable与local_irq_disable最大的不同在于,local_irq_save会在关闭中断前,将处理器当前的标志位保存在一个unsigned long flags中,在调用local_irq_restore的时候,再将保存的fla恢复到处理器的FLAGS寄存器中。这样做的目的是,防止在一个中断关闭的环境中因为调用local_irq_disable与local_irq_enable将之前的中断响应状态破坏掉。

在单处理器不可抢占系统中,使用local_irq_enable与local_irq_disable及其变体来对共享数据保护是种简单而有效的方法。但在使用时应该注意,因为local_irq_enable与local_irq_disable是通过关中断的方式进行互斥保护,所以必须确保处于两者之间的代码执行时间不能太长,否则将影响到系统的性能。

目录
相关文章
|
关系型数据库 MySQL 数据处理
FlinkCDC 增量读取 binlog 数据比较慢
FlinkCDC 增量读取 binlog 数据比较慢
721 1
|
前端开发 搜索推荐 定位技术
GIS前端—地图标注
GIS前端—地图标注
433 1
|
存储 数据采集 数据挖掘
Python数据分析实验一:Python数据采集与存储
Python数据分析实验一:Python数据采集与存储
505 1
|
机器学习/深度学习 人工智能 算法
强化学习在游戏AI中的应用,从基本原理、优势、应用场景到具体实现方法,以及Python在其中的作用
本文探讨了强化学习在游戏AI中的应用,从基本原理、优势、应用场景到具体实现方法,以及Python在其中的作用,通过案例分析展示了其潜力,并讨论了面临的挑战及未来发展趋势。强化学习正为游戏AI带来新的可能性。
1038 4
|
关系型数据库 MySQL 数据库
实时计算 Flink版操作报错合集之任务启动后加动态表读binlog报错如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
460 6
|
消息中间件 NoSQL 中间件
中间件发布-订阅模式(Pub/Sub)
【7月更文挑战第1天】
552 2
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp微信小程序的在线问卷调查系统的详细设计和实现
基于SpringBoot+Vue+uniapp微信小程序的在线问卷调查系统的详细设计和实现
487 1
|
消息中间件 SQL Oracle
实时计算 Flink版产品使用合集之增量同步速度较慢,导致延迟增加,该如何优化
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStreamAPI、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
关系型数据库 MySQL 分布式数据库
PolarDB操作报错合集之源实例无主键表校验出现报错,该怎么办
在使用阿里云的PolarDB(包括PolarDB-X)时,用户可能会遇到各种操作报错。下面汇总了一些常见的报错情况及其可能的原因和解决办法:1.安装PolarDB-X报错、2.PolarDB安装后无法连接、3.PolarDB-X 使用rpm安装启动卡顿、4.PolarDB执行UPDATE/INSERT报错、5.DDL操作提示“Lock conflict”、6.数据集成时联通PolarDB报错、7.编译DN报错(RockyLinux)、8.CheckStorage报错(源数据库实例被删除)、9.嵌套事务错误(TDDL-4604)。
1062 0
|
JSON 人工智能 数据库
【AI大模型应用开发】【LangChain系列】1. 全面学习LangChain输入输出I/O模块:理论介绍+实战示例+细节注释
【AI大模型应用开发】【LangChain系列】1. 全面学习LangChain输入输出I/O模块:理论介绍+实战示例+细节注释
645 0
【AI大模型应用开发】【LangChain系列】1. 全面学习LangChain输入输出I/O模块:理论介绍+实战示例+细节注释