日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ARM下的原子操作实现原理

發(fā)布時間:2025/4/5 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ARM下的原子操作实现原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

ARM下的原子操作實現(xiàn)原理

本文的重點是學(xué)習(xí)C內(nèi)嵌匯編的語法和ldrex/strex指令。


1、atomic_t類型定義
typedef struct {
?? ?int counter;
} atomic_t;
把整型原子操作定義為結(jié)構(gòu)體,讓原子函數(shù)只接收atomic_t類型的參數(shù)進而確保原子操作只與這種特殊類型數(shù)據(jù)一起使用,同時也保證了該類型的數(shù)據(jù)不會被傳遞給非原子函數(shù)。

2、定義并初始化一個atomic_t變量
atomic_t v = ATOMIC_INIT(0);
#define ATOMIC_INIT(i)?? ?{ (i) }

3、基本操作
atomic_inc(v); // 原子變量自增1
atomic_dec(v); // 原子變量自減1
4、atomic_inc()函數(shù)的實現(xiàn)
static inline void atomic_inc(atomic_t *v)
{
atomic_add_return(1, v);
}

#define atomic_inc_return(v)?? ?atomic_add_return(1, (v))
static inline int atomic_add_return(int i, atomic_t *v)
{
?? ?unsigned long tmp;
?? ?int result;
?? ?smp_mb();
?
?? ?__asm__ __volatile__("@ atomic_add_return\n"
?? ??? ?"1:?? ?ldrex?? ?%0, [%3]\n"
?? ??? ?"?? ?add?? ?%0, %0, %4\n"
?? ??? ?"?? ?strex?? ?%1, %0, [%3]\n"
?? ??? ?"?? ?teq?? ?%1, #0\n"
?? ??? ?"?? ?bne?? ?1b"
?? ??? ?: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
?? ??? ?: "r" (&v->counter), "Ir" (i)
?? ??? ?: "cc");
?
?? ?smp_mb();
?? ?return result;
}

4.1 C函數(shù)內(nèi)嵌匯編
4.1.1 內(nèi)嵌匯編語法
__asm__內(nèi)嵌匯編關(guān)鍵字,告知編譯器下述語句為匯編代碼
__volatile__告知編譯器不要優(yōu)化(比如重組優(yōu)化)下述匯編語句
語法的格式:
__asm__ (
?? ?"asm code 1\n" // instruction list
?? ?"asm code 2\n"
?? ?"asm code n"
?? ?: Output Operands // 把匯編指令的數(shù)值輸出到C代碼的變量中
?? ?: Input ?Operands
?? ?: clobbers // 告知編譯器這條指令會修改什么值
);

變量列表中常見符號:
"+":操作數(shù)可讀可寫
"=":操作數(shù)只寫
"&":常用于輸出操作,表示輸出操作不能使用輸入操作使用過的寄存器,只能+&或=&方式使用
"r":操作數(shù)是任何可用的通用寄存器
"m":操作數(shù)是內(nèi)存變量
"p":操作數(shù)是一個合法的內(nèi)存地址
"I":0~31之間的立即數(shù)
"i":操作數(shù)是立即數(shù)
"Q":A memory address which uses a single base register with no offset
"o":操作數(shù)是內(nèi)存變量,但其尋址方式必須是偏移量類型的,即基址尋址或基址加變址尋址
"V":操作數(shù)是內(nèi)存變量,但其尋址方式非偏移量類型

4.1.2 atomic_add_return中匯編分析
__asm__ __volatile__("@ atomic_add_return\n"
?? ?"1:?? ?ldrex?? ?%0, [%3]\n"
?? ?"?? ?add?? ?%0, %0, %4\n"
?? ?"?? ?strex?? ?%1, %0, [%3]\n"
?? ?"?? ?teq?? ?%1, #0\n"
?? ?"?? ?bne?? ?1b"
?? ?: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
?? ?: "r" (&v->counter), "Ir" (i)
?? ?: "cc");
%0 <-- result
%1 <-- tmp
%3 <-- v->counter的地址
%4 <-- i
注意:此時C變量的數(shù)據(jù)都已經(jīng)放至寄存器中
(1) ldrex %0, [%3]
獨占式地加載(Load-Exclusive)v->counter的地址,把它的值放到result中,并更新exclusive monitor(s)
用C描述就是:
result = v->counter
(2) add %0, %0, %4
result = result + i
(3) strex %1, %0, [%3]
獨占式地保存(Store-Exclusive)數(shù)據(jù)至v->counter的地址,數(shù)據(jù)來自result,操作結(jié)果(成功/失敗)保存在tmp中
用C描述就是:
v->counter = result
(4) teq %1, #0
檢測strex的操作是否成功
(5) bne 1b
strex的操作失敗的話,向后跳轉(zhuǎn)到指定標(biāo)號(jump to 1 label backward)處重新執(zhí)行
(6) "cc"

"cc"是一個特殊的參數(shù),用來標(biāo)明匯編代碼會修改標(biāo)志寄存器(flags register)
在某些機器平臺上,GCC通過一個特殊的硬件寄存器表征條件類型的代碼,"cc"就是這個特殊寄存器的名字
某些機器平臺沒有上述功能,"cc"會被忽略,不起作用。

附:

1、How to Use Inline Assembly Language in C Code

2、ldrex和strex簡介

LDREX and STREX
The LDREX and STREX instructions split the operation of atomically updating memory into
two separate steps. Together, they provide atomic updates in conjunction with exclusive
monitors that track exclusive memory accesses.
Load-Exclusive and Store-Exclusive must only access memory regions marked as
Normal.


LDREX
The LDREX instruction loads a word from memory, initializing the state of the exclusive
monitor(s) to track the synchronization operation. For example, LDREX R1, [R0]
performs a Load-Exclusive from the address in R0, places the value into R1 and updates
the exclusive monitor(s).


STREX
The STREX instruction performs a conditional store of a word to memory. If the exclusive
monitor(s) permit the store, the operation updates the memory location and returns the
value 0 in the destination register, indicating that the operation succeeded. If the
exclusive monitor(s) do not permit the store, the operation does not update the memory
location and returns the value 1 in the destination register. This makes it possible to
implement conditional execution paths based on the success or failure of the memory
operation. For example, STREX R2, R1, [R0] performs a Store-Exclusive operation to the
address in R0, conditionally storing the value from R1 and indicating success or failure
in R2.

詳見ARM Synchronization Primitives
————————————————
版權(quán)聲明:本文為CSDN博主「__2017__」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u013686019/article/details/78235624

總結(jié)

以上是生活随笔為你收集整理的ARM下的原子操作实现原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。