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将中断使能打开。

最新文章

  1. Java 第二次作业
  2. UIkit折腾
  3. Rhel6-tomcat+nginx+memcached配置文档
  4. 项目源码--JAVA基于LBS地理位置信息应用的服务端
  5. FreeImage裁剪示例
  6. Android——用户登陆及用户名和密码的保存
  7. js框架封装,模拟jQuery封装
  8. 【转载】通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?
  9. MySQL乐观锁为什么可以防止并发
  10. day319 1、正则表达式的定义及使用 2、Date类的用法 3、Calendar类的用法
  11. shell中输出日期的一个函数
  12. Python中re(正则表达式)模块学习
  13. A pointer is a variable whose value is the address of another variable 指针 null pointer 空指针 内存地址0 空指针检验
  14. Codeforce 9C - Hexadecimal&#39;s Numbers
  15. hadoop-处理小文件
  16. Ubuntu 13.04 SSH其他机器连接慢的解决办法
  17. 03把IL编译成可执行文件
  18. [app]Linux的setitimer和sleep冲突
  19. tcp-full.cc
  20. UML功能模型(用例图)

热门文章

  1. 英语DIAMAUND钻石指坚硬不可侵犯的物质
  2. OSX - Mac OS 10.12后Caps lock(大写键)无法使用的解决办法
  3. SQL常见的一些面试题(太有用啦)
  4. Xcode 10 Archive 时电脑卡死
  5. mysql DML 数据插入,删除,更新,回退
  6. 第一个 macOS 64位 kbmmw 服务器
  7. 【Python】异常
  8. Flask入门很轻松 (二)
  9. Linux下设置postgresql数据库开机启动
  10. Grafana+Prometheus实现Ceph监控和钉钉告警-转载(云栖社区)