`ll/sc` 指令在`linux`中的软件实现
2024-10-21 02:26:53
load-link与store-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_save
与raw_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_save
与raw_local_irq_restore
被实现为两个mips
的宏定义,raw_local_irq_save
对cp0
的status
寄存器进行修改,让cpu
进入kernek mode
,ERL
与EXL
置0
,同时禁止中断,从而保证了原子性。raw_local_irq_restore
将中断使能打开。
最新文章
- Java 第二次作业
- UIkit折腾
- Rhel6-tomcat+nginx+memcached配置文档
- 项目源码--JAVA基于LBS地理位置信息应用的服务端
- FreeImage裁剪示例
- Android——用户登陆及用户名和密码的保存
- js框架封装,模拟jQuery封装
- 【转载】通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?
- MySQL乐观锁为什么可以防止并发
- day319 1、正则表达式的定义及使用 2、Date类的用法 3、Calendar类的用法
- shell中输出日期的一个函数
- Python中re(正则表达式)模块学习
- A pointer is a variable whose value is the address of another variable 指针 null pointer 空指针 内存地址0 空指针检验
- Codeforce 9C - Hexadecimal&#39;s Numbers
- hadoop-处理小文件
- Ubuntu 13.04 SSH其他机器连接慢的解决办法
- 03把IL编译成可执行文件
- [app]Linux的setitimer和sleep冲突
- tcp-full.cc
- UML功能模型(用例图)