linux 内核接口atomic_long_try_cmpxchg_acquire/release详解

news2024/12/22 23:58:42

linux 内核接口atomic_long_try_cmpxchg_acquire详解

  • 1 atomic_long_try_cmpxchg_acquire/release
    • 1.1 atomic_long_try_cmpxchg_acquire
    • 1.2 atomic_long_try_cmpxchg_release
  • 2 arch_atomic64_cmpxchg_acquire/release
    • 2.1 arch_atomic64_cmpxchg_acquire/release定义
    • 2.2 atomic64_cmpxchg_acquire/release
    • 2.3 instrument_atomic_read_write
    • 2.4 arch_atomic64_cmpxchg_acquire/release
    • 2.5 arch_atomic_cmpxchg_acquire/release
    • 2.6 arch_cmpxchg_acquire/release
    • 2.7 __cmpxchg_wrapper
    • 2.8 __cmpxchg##sfx
    • 2.9 __xchg_case_##name##sz
    • 2.10 ldxr
      • 2.10.1 ldxr
      • 2.10.2 ldxrb
      • 2.10.3 LDXRH
    • 2.11 ldaxr
      • 2.11.1 ldaxr
      • 2.11.2 ldaxb
      • 2.11.3 LDAXRH
    • 2.12 stxr
      • 2.12.1 STXR
      • 2.12.2 STXRB
      • 2.12.3 stxrh

1 atomic_long_try_cmpxchg_acquire/release

1.1 atomic_long_try_cmpxchg_acquire

static __always_inline bool
atomic_long_try_cmpxchg_acquire(atomic_long_t *v, long *old, long new)
{
        return atomic64_try_cmpxchg_acquire(v, (s64 *)old, new);
}

1.2 atomic_long_try_cmpxchg_release

static __always_inline bool
atomic_long_try_cmpxchg_release(atomic_long_t *v, long *old, long new)
{
        return atomic64_try_cmpxchg_release(v, (s64 *)old, new);
}

2 arch_atomic64_cmpxchg_acquire/release

2.1 arch_atomic64_cmpxchg_acquire/release定义

#define arch_atomic64_cmpxchg_acquire atomic64_cmpxchg_acquire
#define arch_atomic64_cmpxchg_release atomic64_cmpxchg_release

2.2 atomic64_cmpxchg_acquire/release

#if defined(arch_atomic64_cmpxchg_acquire)
static __always_inline s64
atomic64_cmpxchg_acquire(atomic64_t *v, s64 old, s64 new)
{
        instrument_atomic_read_write(v, sizeof(*v));
        return arch_atomic64_cmpxchg_acquire(v, old, new);
}
#define atomic64_cmpxchg_acquire atomic64_cmpxchg_acquire
#endif

#if defined(arch_atomic64_cmpxchg_release)
static __always_inline s64
atomic64_cmpxchg_release(atomic64_t *v, s64 old, s64 new)
{
        instrument_atomic_read_write(v, sizeof(*v));
        return arch_atomic64_cmpxchg_release(v, old, new);
}
#define atomic64_cmpxchg_release atomic64_cmpxchg_release
#endif

2.3 instrument_atomic_read_write

原子读写访问

/**
 * instrument_atomic_read_write - instrument atomic read-write access
 *
 * Instrument an atomic read-write access. The instrumentation should be
 * inserted before the actual write happens.
 *
 * @ptr address of access
 * @size size of access
 */
static __always_inline void instrument_atomic_read_write(const volatile void *v, size_t size)
{
        kasan_check_write(v, size);
        kcsan_check_atomic_read_write(v, size);
}

2.4 arch_atomic64_cmpxchg_acquire/release

#define arch_atomic64_cmpxchg_acquire           arch_atomic_cmpxchg_acquire
#define arch_atomic64_cmpxchg_release           arch_atomic_cmpxchg_release

2.5 arch_atomic_cmpxchg_acquire/release

#define arch_atomic_cmpxchg_acquire(v, old, new) \
        arch_cmpxchg_acquire(&((v)->counter), (old), (new))
#define arch_atomic_cmpxchg_release(v, old, new) \
        arch_cmpxchg_release(&((v)->counter), (old), (new))

2.6 arch_cmpxchg_acquire/release

#define arch_cmpxchg_acquire(...)       __cmpxchg_wrapper(_acq, __VA_ARGS__)
#define arch_cmpxchg_release(...)       __cmpxchg_wrapper(_rel, __VA_ARGS__)

2.7 __cmpxchg_wrapper

  • 对于arch_cmpxchg_acquire来说,sfx指代的是_acq
  • 对于arch_cmpxchg_release来说,sfx指代的是_rel
  • sizeof(*(ptr))表示要访问地址对应的数据宽度
#define __cmpxchg_wrapper(sfx, ptr, o, n)                               \
({                                                                      \
        __typeof__(*(ptr)) __ret;                                       \
        __ret = (__typeof__(*(ptr)))                                    \
                __cmpxchg##sfx((ptr), (unsigned long)(o),               \
                                (unsigned long)(n), sizeof(*(ptr)));    \
        __ret;                                                          \
})

2.8 __cmpxchg##sfx

  • __CMPXCHG_GEN()表示为__cmpxchg
  • __CMPXCHG_GEN(_acq)表示为__cmpxchg_acq
  • __CMPXCHG_GEN(_rel)表示为__cmpxchg_rel
  • __CMPXCHG_GEN(_mb)表示为__cmpxchg_mb
#define __CMPXCHG_GEN(sfx)                                              \
static __always_inline unsigned long __cmpxchg##sfx(volatile void *ptr, \
                                           unsigned long old,           \
                                           unsigned long new,           \
                                           int size)                    \
{                                                                       \
        switch (size) {                                                 \
        case 1:                                                         \
                return __cmpxchg_case##sfx##_8(ptr, old, new);          \
        case 2:                                                         \
                return __cmpxchg_case##sfx##_16(ptr, old, new);         \
        case 4:                                                         \
                return __cmpxchg_case##sfx##_32(ptr, old, new);         \
        case 8:                                                         \
                return __cmpxchg_case##sfx##_64(ptr, old, new);         \
        default:                                                        \
                BUILD_BUG();                                            \
        }                                                               \
                                                                        \
        unreachable();                                                  \
}

__CMPXCHG_GEN()
__CMPXCHG_GEN(_acq)
__CMPXCHG_GEN(_rel)
__CMPXCHG_GEN(_mb)

2.9 _xchg_case##name##sz

  • __XCHG_CASE(w, b, , 8, , , , , , )对应着__xchg_case_8,其所对应的ld" #acq "xr" #sfx "\t%" #w "0, %2ldxrb "\t%" #w "0, %2;所对应的st" #rel "xr" #sfx "\t%w1, %" #w "3, %2stxrb "\t%w1, %" #w "3, %2;相对应的arm64汇编指令为ldxrbstxrb
  • __XCHG_CASE(w, b, acq_, 8, , , a, a, , "memory")对应着__xchg_case_acq_8,其所对应的ld" #acq "xr" #sfx "\t%" #w "0, %2ldaxrb "\t%" #w "0, %2;所对应的st" #rel "xr" #sfx "\t%w1, %" #w "3, %2stxrb "\t%w1, %" #w "3, %2;相对应的arm64汇编指令为ldaxrbstxrb
/*
 * We need separate acquire parameters for ll/sc and lse, since the full
 * barrier case is generated as release+dmb for the former and
 * acquire+release for the latter.
 */
#define __XCHG_CASE(w, sfx, name, sz, mb, nop_lse, acq, acq_lse, rel, cl)       \
static inline u##sz __xchg_case_##name##sz(u##sz x, volatile void *ptr)         \
{                                                                               \
        u##sz ret;                                                              \
        unsigned long tmp;                                                      \
                                                                                \
        asm volatile(ARM64_LSE_ATOMIC_INSN(                                     \
        /* LL/SC */                                                             \
        "       prfm    pstl1strm, %2\n"                                        \
        "1:     ld" #acq "xr" #sfx "\t%" #w "0, %2\n"                           \
        "       st" #rel "xr" #sfx "\t%w1, %" #w "3, %2\n"                      \
        "       cbnz    %w1, 1b\n"                                              \
        "       " #mb,                                                          \
        /* LSE atomics */                                                       \
        "       swp" #acq_lse #rel #sfx "\t%" #w "3, %" #w "0, %2\n"            \
                __nops(3)                                                       \
        "       " #nop_lse)                                                     \
        : "=&r" (ret), "=&r" (tmp), "+Q" (*(u##sz *)ptr)                        \
        : "r" (x)                                                               \
        : cl);                                                                  \
                                                                                \
        return ret;                                                             \
}

__XCHG_CASE(w, b,     ,  8,        ,    ,  ,  ,  ,         )
__XCHG_CASE(w, h,     , 16,        ,    ,  ,  ,  ,         )
__XCHG_CASE(w,  ,     , 32,        ,    ,  ,  ,  ,         )
__XCHG_CASE( ,  ,     , 64,        ,    ,  ,  ,  ,         )
__XCHG_CASE(w, b, acq_,  8,        ,    , a, a,  , "memory")
__XCHG_CASE(w, h, acq_, 16,        ,    , a, a,  , "memory")
__XCHG_CASE(w,  , acq_, 32,        ,    , a, a,  , "memory")
__XCHG_CASE( ,  , acq_, 64,        ,    , a, a,  , "memory")
__XCHG_CASE(w, b, rel_,  8,        ,    ,  ,  , l, "memory")
__XCHG_CASE(w, h, rel_, 16,        ,    ,  ,  , l, "memory")
__XCHG_CASE(w,  , rel_, 32,        ,    ,  ,  , l, "memory")
__XCHG_CASE( ,  , rel_, 64,        ,    ,  ,  , l, "memory")
__XCHG_CASE(w, b,  mb_,  8, dmb ish, nop,  , a, l, "memory")
__XCHG_CASE(w, h,  mb_, 16, dmb ish, nop,  , a, l, "memory")
__XCHG_CASE(w,  ,  mb_, 32, dmb ish, nop,  , a, l, "memory")
__XCHG_CASE( ,  ,  mb_, 64, dmb ish, nop,  , a, l, "memory")

2.10 ldxr

2.10.1 ldxr

加载排他寄存器从基本寄存器值获取地址,从内存中加载32位字或64位双字,并将其写入寄存器。内存访问是原子式的。PE将被访问的物理地址标记为独家访问。此独家访问标记是由独占存储指令检查的。
在这里插入图片描述

2.10.2 ldxrb

加载排他寄存器字节从一个基本寄存器值派生一个地址,从内存加载一个字节,零扩展它,并将其写入一个寄存器。内存访问是原子式的。PE将被访问的物理地址标记为独家访问。此独家访问标记是由独占存储指令检查的。
在这里插入图片描述

2.10.3 LDXRH

加载排他寄存器半字从基本寄存器值获得地址,从内存加载半字,零扩展它并将其写入寄存器。内存访问是原子式的。PE将被访问的物理地址标记为独家访问。此独家访问标记是由独占存储指令检查的。
在这里插入图片描述

2.11 ldaxr

2.11.1 ldaxr

加载-获取独占寄存器从基本寄存器值获取地址,从内存中加载32位字或64位双字,并将其写入寄存器。内存访问是原子式的。PE将被访问的物理地址标记为独家访问。此独家访问标记是由独占存储指令检查的。

2.11.2 ldaxb

加载-获取独占寄存器字节从一个基本寄存器值派生一个地址,从内存加载一个字节,零扩展它,并将其写入一个寄存器。内存访问是原子式的。PE将被访问的物理地址标记为独家访问。此独家访问标记是由存储独占指令检查的。
在这里插入图片描述

2.11.3 LDAXRH

加载获取独占寄存器半字从基本寄存器值获得地址,从内存加载半字,零扩展它并将其写入寄存器。内存访问是原子式的。PE将被访问的物理地址标记为独家访问。此独家访问标记是由存储独占指令检查的。
在这里插入图片描述

2.12 stxr

2.12.1 STXR

如果PE对内存地址具有独占访问权限,则独家存储器从寄存器存储32位字或64位双字,如果存储成功,返回状态值为0,如果没有执行存储,则返回状态值为1。
在这里插入图片描述
在这里插入图片描述

2.12.2 STXRB

存储独占寄存器字节如果PE只访问内存地址,则存储从寄存器到内存的字节,如果存储成功,则返回状态值为0,如果没有执行存储,则返回状态值为1。内存访问是原子式的。
在这里插入图片描述

2.12.3 stxrh

如果PE对内存地址有独占访问,则存储寄存器存储到内存,如果存储成功,返回状态值为0,如果没有执行存储,返回状态值为1。内存访问是原子式的。
在这里插入图片描述

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

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

相关文章

移远通信携手中国电信等伙伴重磅发布5G NTN试验成果,共促卫星物联网产业发展

6月29日,在MWC上海展期间,以“5G云网新科技 数字经济新动能”为主题的2023中国电信5G/6G科技创新成果发布会顺利举行。 会上,中国电信联合合作伙伴重磅发布了多项科技创新成果和科技创新应用,作为中国电信在卫星物联网领域重要的合…

ArcGIS SDE空间数据库 镶嵌数据集白边压盖及不显示问题

首先,在Oracle SDE空间数据库中新建了镶嵌数据集(Mosaic Dataset) ,这里通过程序导入影像数据以后出现了 影像不显示(得放到很小比例尺才显示)及影像之间互相压盖 第一,解决影像互相压盖问题 在Calalog中右键镶嵌数据…

操作系统6——文件管理

本系列博客重点在深圳大学操作系统课程的核心内容梳理,参考书目《计算机操作系统》(有问题欢迎在评论区讨论指出,或直接私信联系我)。 梗概 本篇博客主要介绍操作系统第七章文件管理和第八章磁盘储存器的管理的相关知识。 目录 …

智谱AI-算法实习生(知识图谱方向)实习面试记录

岗位描述 没错和我的经历可以说是match得不能再match了,但是还是挂了hh。 面试内容 给我面试的是唐杰老师的博士生,方向是社交网络数据挖掘,知识图谱。不cue名了,态度很友好的 ,很赞。 date:6.28 Q1 自…

【算法之双指针I】leetcode344.反转字符串

344.反转字符串 力扣题目链接 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间,你必须**原地修改输入数组**、使用 O(1) 的额外空间解决这一问题。 输入:s ["h…

【代理服务器】Squid代理服务器应用

目录 一、Squid代理服务器1.1代理的工作机制1.2代理服务器的概念1.3代理服务器的作用1.4Squid 代理的类型 二、安装Squid服务2.1编译安装Squid2.2修改 Squid 的配置文件2.3Squid运行控制2.4创建Squid服务脚本2.5 构建传统代理服务器2.6更改防火墙规则2.7验证 三、构建透明代理服…

Keil MDK 5 仿真STM32F4报错no ‘read‘ permission

问题描述 MDK软件模拟仿真提示没有读写权限,只能单步运行。error提示: *** error 65: access violation at 0x40023C00 : no read permission 关于Keil MDK 5 仿真STM32F4报错no ‘read’ permission的解决方法 Vision 调试器为所有 ARM7、ARM9、Corte…

怎样在文章末尾添加尾注(将尾注的数字变为方括号加数字)

在进行文章编写或者需要添加注解时,需要进行尾注的添加,下面将详细说明如何进行尾注的添加 操作 首先打开需要进行添加尾注的文档,将光标移动至需要进行添加尾注的文字后。 紧接着在上方工具栏中,选择引用,在引用页…

4.FreeRTOS系统配置文件详解(FreeRTOSConfig.h)

目录 一、基础配置选项 二、内存分配相关定义 三、钩子函数的相关定义 四、运行时间和任务状态统计相关定义 五、软件定时器相关配置 FreeRTOSConfig.h配置文件的作用: 对FreeRTOS进行功能配合和裁剪,以及API函数的使能 对于FreeRTOS配置文件主要…

如果制作投票选举投票制作制作一个投票在线制作投票

用户在使用微信投票的时候,需要功能齐全,又快捷方便的投票小程序。 而“活动星投票”这款软件使用非常的方便,用户可以随时使用手机微信小程序获得线上投票服务,很多用户都很喜欢“活动星投票”这款软件。 “活动星投票”小程序在…

CORS如何实现跨域(前端+后端代码实例讲解)

书接上回,上一篇文章讲解了用 jsonp 来解决跨域问题,这篇文章讲解另外一种方法也可以解决跨域问题,那就是CORS(跨源资源共享)。 什么是CORS? 下面是官方的解释:跨源资源共享(CORS&a…

刚去了家新公司,发现个个都是卷王 , 想离职了。。

个个都说想躺平了,可是有一说一,该卷的还是卷。这不,前段时间我们公司来了个00后,才工作一年,跳槽到我们公司起薪15K,都快接近我了。后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了。…

性能测试什么时候开始?性能测试流程介绍

目录 性能测试什么时候开始? 一、制定性能测试目标 二、性能测试场景获取 三、性能测试数据确定 四、性能测试用例设计 五、性能测试环境准备与搭建 六、做脚本 七、跑场景 八、做监控 九、分析调优 十、回归测试 十一、出图写报告 总结: 性能测试什么…

STM32——建工程

文章目录 一、建工程步骤1. 创建一个工程文件2. 里面创建四个文件3. Lib:存放标准库的.c和.h文件,其中inc放置.h文件,src放置.c文件4. Startup中存放驱动文件5.User文件中包含以下路径以下文件6.创建工程Project 一、建工程步骤 以STM32F10X…

若依不分离,弹层自定义按钮

记录下遇到的两种情况 第一种:点击按钮,打开第三方链接去支付,因为只需要显示一个关闭按钮 代码: // 表格操作列 {title: 操作,align: center,formatter: function (value, row, index) {var actions [];if (row.status1) {acti…

NAMD分子动力学模拟在生物及材料计算中的应用专题

第一天 时间 :第一天上午 内容:一:分子动力学相关软件及Linux入门 目标:了解NAMD软件,掌握NAMD安装环境,了解Linux语言 二:VMD可视化软件的安装和使用 三:研究对象模型获取,构建以及优化 主要…

7-WebApis-5

Web APIs - 5 目标: 能够利用JS操作浏览器,具备利用本地存储实现学生就业表的能力 BOM操作综合案例 js组成 JavaScript的组成 ECMAScript: 规定了js基础语法核心知识。比如:变量、分支语句、循环语句、对象等等 Web APIs : DOM 文档对象模型&#xff…

LeetCode 445.两数相加 II

给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外,这两个数字都不会以零开头。 https://leetcode.cn/problems/add-two-numbers-ii/description/ c…

Elasticsearch全⽂检索

以下说明&#xff1a;其中比喻都是以mysql为模板进行比较说明 一.lucene 1.jar包环境准备 <!-- 引入Lucene核心包及分词器包 --><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-core</artifactId><version>…

82、基于stm32单片机音乐喷泉设计播放器频谱彩灯系统设计(程序+原理图+参考论文+开题报告+任务书+设计资料+元器件清单等)

摘 要 随着人们生活水平的提高和建立绿色城市的向往&#xff0c;音乐喷泉以其独特的魅力和特殊的功能&#xff0c;愈来愈成为休闲娱乐产业中的一项重要产品,音乐喷泉的兴建也越来越多。 根据目前音乐喷泉的发展现状&#xff0c;介绍了一个以STM32单片机为核心的小型音乐喷泉控…