load-linkstore-conditional (LL/SC)是一对用于并发同步访问内存的CPU指令。Load-link返回内存位置处的当前值,随后的store-conditional在该内存位置处保存新值(如果从load-link后没有被修改)。这被用于实现无锁算法与read-modify-write原子操作。

linux<asm/atomic.h><asm/system.h><asm/cmpxchg.h><asm/bitops.h><asm/local.h>中实现了多种基本的原子操作,以最简单的atomic_add来举例:

/** atomic_add - add integer to atomic variable* @i: integer value to add* @v: pointer of type atomic_t** Atomically adds @i to @v.*/
static __inline__ void atomic_add(int i, atomic_t * v)
{if (kernel_uses_llsc && R10000_LLSC_WAR) {int temp;__asm__ __volatile__("   .set    mips3                   \n""1: ll  %0, %1      # atomic_add        \n""   addu    %0, %2                  \n""   sc  %0, %1                  \n""   beqzl   %0, 1b                  \n""   .set    mips0                   \n": "=&r" (temp), "=m" (v->counter): "Ir" (i), "m" (v->counter));} else if (kernel_uses_llsc) {int temp;__asm__ __volatile__("   .set    mips3                   \n""1: ll  %0, %1      # atomic_add        \n""   addu    %0, %2                  \n""   sc  %0, %1                  \n""   beqz    %0, 2f                  \n""   .subsection 2                   \n""2: b   1b                  \n""   .previous                   \n""   .set    mips0                   \n": "=&r" (temp), "=m" (v->counter): "Ir" (i), "m" (v->counter));} else {unsigned long flags;raw_local_irq_save(flags);v->counter += i;raw_local_irq_restore(flags);}
}

其中,kernel_uses_llsc是一个宏定义,当定义为0时就需要软件实现。raw_local_irq_saveraw_local_irq_restore函数定义在<linux/irqflags.h>,对于不同的mips cpu有不同的实现,最简单的实现如下:

    .macro irq_enable_hazard; _ssnop; _ssnop; _ssnop;; .endm.macro irq_disable_hazard; nop; nop; nop; .endm.macro  raw_local_irq_save result           .set    push                        .set    reorder                     .set    noat                        mfc0    \result, $12                    ori $1, \result, 0x1f               xori    $1, 0x1f                    .set    noreorder                   mtc0    $1, $12                     irq_disable_hazard                  .set    pop                     .endm                           .macro  raw_local_irq_restore flags         .set    push                        .set    noreorder                   .set    noat                        mfc0    $1, $12                     andi    \flags, 1                   ori $1, 0x1f                    xori    $1, 0x1f                    or  \flags, $1                  mtc0    \flags, $12                 irq_disable_hazard                  .set    pop                     .endm                           

raw_local_irq_saveraw_local_irq_restore被实现为两个mips的宏定义,raw_local_irq_savecp0status寄存器进行修改,让cpu进入kernek modeERLEXL0,同时禁止中断,从而保证了原子性。raw_local_irq_restore将中断使能打开。

转载于:https://www.cnblogs.com/PowerofChoas/p/11247281.html

`ll/sc` 指令在`linux`中的软件实现相关推荐

  1. Linux中常用软件安装

    Linux中常用软件安装 0 软件安装命令 rpm命令 yum命令 1 JDK安装 2 Mysql安装 0 MySQL安装与卸载 (新增于 2021-06-06) 1 卸载 yum方式 rpm方式 2 ...

  2. debian linux如何安装软件,怎样在Debian Linux中安装软件?

    Debian Linux附带了超过 29000 个软件包,这些预先编译好的软件被包裹成一种良好的格式以便于在您的机器上进行安装.如果您使用的是Debian的桌面版本,则可以使用Synaptic通过点击 ...

  3. Linux中常见软件安装方法及常见管理方法

    软件安装及管理 一.软件的类型 二.Tar包安装.升级.卸载(必须会) 三.RPM软件包安装及管理(必须会) 四.脚本安装.升级.卸载 五.SRPM包安装(知道就行,很少用) 一.软件的类型 1.软件 ...

  4. RH124(12)----Linux中的软件管理

    文章目录 前言 一.Linux软件包的基本介绍 1.软件包类型 2.软件包的名称结构 二.rpm软件包管理命令 三.本地软件仓库的搭建 四.dnf软件管理命令 五.网络软件库的搭建 1.网络软件库的搭 ...

  5. Linux中常用软件安装(基于Ubuntu)

    安装软件对于初学者来说都是比较困难的,刚刚接触Linux时,初学者会因为软件安装的不正确而花费大量的时间,本文为了更加方便地为初学者提供参考: ============================ ...

  6. linux中的软件管理(包括配置本地yum源、配置共享yum源、第三方仓库的搭建、yum命令、rpm命令)

    1.什么是yum源? yum源就是一个软件集合地,你只需要搜索并安装你想要的软件,它会帮你解决大部分软件的依赖问题 本地yum源:比如说光盘里面一般会附带一些软件,这个时候就可以把光盘当成本地源来安装 ...

  7. 如何查看linux安装了那些软件下载,linux中安装软件,查看、卸载已安装软件方法...

    各种主流Linux发行版都采用了某种形式的包管理系统(PMS)来控制软件和库的安装. 软件包存储在服务器上,可以利用本地Linux系统上的PMS工具通过互联网访问.这些服务器称为仓库. 由于Linux ...

  8. linux 显示软件,Linux中的软件管理

    在Linux中,会涉及到相关软件的使用来方便我们,那么软件如何下载呢,如下将做详细的介绍. ####一.软件名称识别#### [abrt-addon-ccpp]-[2.1.11-19].[el7].[ ...

  9. 【Linux操作系统基础】第八章 Linux中的软件管理

    目录 一.linux中软件包的类型 软件包类型: 二.软件包的名称结构 三. rpm命令管理软件包 -ivh安装 -qa查看所有已安装软件 -ql查看软件安装文件列表​编辑 -qf查看/mnt/在哪个 ...

最新文章

  1. linux看php安装路径,linux下查找php安装路径的方法是什么
  2. 三步更改win7开机密码
  3. swiper去除滑动设置
  4. SOC/LM在台湾的2011年发展趋势研判
  5. ★ 让你的虚机飞起来 ★
  6. java面试题三十一
  7. 第9章 中断和动态时钟显示
  8. AcWing 2041. 干草堆(差分)
  9. 自然语言处理——TF-IDF文本表示
  10. 阿里云--域名,主机,备案都配置好了,就是不能访问网站的解决方案
  11. 织梦 - PHP开源网站管理系统
  12. 下载蓝盒插件_bilibili哔哩哔哩下载助手
  13. Android Studio导入安卓源码
  14. postgresql 导出单张表
  15. mtk android 关机充电,MTK充电开机关机过程
  16. Linux如何用link命令停网卡,如何使用 ethtool 命令管理以太网卡 | Linux 中国
  17. Soul聊天记录备份和恢复(旧机迁移至新机)
  18. 深度挖掘新闻营销带给企业的好处和优势
  19. MATLAB学习笔记-IEEE802.16d模型
  20. 微信小程序将身份证隐藏、手机号、姓名用****代替

热门文章

  1. linux deploy下载地址,Linux部署 Linux Deploy
  2. Oracle→数字函数、字符函数、时间函数、SYSDATE、TO_CHAR()、TO_DATE()、TO_NUMBER()、NVLNVL2NULLIF、ROW_NUMBER()
  3. poj 3280 区间dp
  4. $(document).ready()和onload区别
  5. pycharm下自建python包引入失败解决方案
  6. 白帽子讲Web安全(对看书之后的一点笔记)
  7. Unity3D基础9:获取鼠标键盘输入
  8. 有下界的最小费用可行流2.0(bzoj 3876: [Ahoi2014]支线剧情)
  9. OPNET网络仿真分析-1.2、OPNET安装教程
  10. Quartus报错Error (170040): Can‘t place all RAM cells in design Info (170034)的解决办法