原子操作 atomic t

2021-06-22 00:37:37 字數 4277 閱讀 5762

1. atomic_t 定義及其原因:

核心定義了atomic_t 資料型別,作為對

整數計數器的原子操作的基礎。

[cpp]view plain

copy

typedef

struct  atomic_t;  

這裡引入了乙個特殊的資料型別,而不是直接使用int型別,原因如下:

a. 讓原子操作函式只接收 atomic_t 型別的運算元,可以確保原子操作只與這種特殊型別資料一起使用,進而保證了該型別資料不會被傳遞給其他非原子操作函式。

如果對乙個資料,一會採用原子操作,一會又不用原子操作,這沒什麼好處。

b. 使用 atomic_t 型別確保編譯器不對相應的值進行訪問優化,這使得原子操作最終接收到正確的記憶體位址,而不是乙個別名。

c. 最後,在不同體系結構上實現原子操作時,使用 atomic_t 可以遮蔽各類體系結構的差異。

原子本意就是不可分割的微粒,所以原子操作就是不可的指令;也就是指在執行過程中不會被別的**所中斷的操作。

各個cpu平台有各自的原子操作實現方式,基本都是通過彙編實現的。

核心提供了兩組原子操作介面: 整型原子操作和位原子操作

2. 整型原子操作

整型的原子操作只能對 atomic_t 型別的資料進行處理:

[cpp]view plain

copy

atomic_t v;     //定義 v 原子變數

void atomic_set(atomic_t *v, int i);   //設定原子變數v的值為i

[cpp]view plain

copy

/*** atomic_set - set atomic variable

* @v: pointer of type atomic_t

* @i: required value

** atomically sets the value of @v to @i.

*/#define atomic_set(v, i) (((v)->counter) = (i))

atomic_t v = atomic_init(0);            //定義原子變數v, 並初始化為0

[cpp]view plain

copy

#define atomic_init(i)  

atomic_read(atomic_t *v);              //獲得原子變數的值,並將 atomic_t 裝換位 int 型別的返回值, 應用如下:

[cpp]view plain

copy

printk("%d\n, atomic_read(&v)");   //列印v的值。

atomic_read()定義:

[cpp]view plain

copy

/*** atomic_read - read atomic variable

* @v: pointer of type atomic_t

** atomically reads the value of @v.

*/#define atomic_read(v)  (*(volatile int *)&(v)->counter)

[cpp]view plain

copy

void atomic_add(int i, atomic_t *v);    //原子變數+i

void atomic_sub(int i, atomic_t *v);    //原子變數-i

原子操作最常見的用途是實現計數器,可以用下面兩個函式來實現計數器功能:

[cpp]view plain

copy

void atomic_inc(atomic_t *v);           //原子變數+1

void atomic_dec(atomic_t *v);           //原子變數-1

還可以用原子整數操作原子的執行乙個操作,並檢查結果:

對原子變數執行自增,自減和減操作後(注意沒有加),測試其是否為0,為0則返回true,否則返回false

[cpp]view plain

copy

int atomic_inc_and_test(atomic_t *v);  

int atomic_dec_and_test(atomic_t *v);  

int atomic_sub_and_test(int i, atomic_t *v);  

[cpp]view plain

copy

int atomic_add_negative(int i, atomic_t *v); //原子的給 v 加 i, 測試結果是否為負數。如果是負數,返回真;否則返回假。

對原子變數進行加/減,自增/自減操作,並返回新的值。

[cpp]view plain

copy

int atomic_add_return(int i, atomic_t *v);  

int atomic_sub_return(int i, atomic_t *v);  

int atomic_inc_return(atomic_t *v);  

int atomic_sub_return(atomic_t *v);  

原子操作通常是內聯函式(inline),往往是通過內嵌彙編指令來實現的。

64位整型原子操作:

對於64位的原子操作,使用 atomic64_t 型別,其功能和32位一模一樣,使用方法也完全相同,就是把 atomic 變成了 atomic64。

與 atomic_t 一樣, atomic64_t 型別其實就是乙個多長整型的封裝類:

[cpp]view plain

copy

typedef

struct  atomic64_t;  

3. 位原子操作

位操作函式是對普通的記憶體位址進行操作的。

雖然原子位操作在大多數情況下,是對乙個字長的記憶體進行訪問的,因而位號位於0-31(64位機是0-63),但是對位號的範圍並沒有限制。

[cpp]view plain

copy

void set_bit(nr, void *addr);    //將addr位址的nr位 置為1

void clear_bit(nr, void *addr);  //將addr位址的nr位 清0

void change_bit(nr, void *addr);  //對addr位址的nr位 反置

int test_bit(nr, void *addr);    //返回addr位址的nr位

[cpp]view plain

copy

int test_and_set_bit(nr, void *addr);  

int test_and_clear_bit(nr, void *addr);  

int test_and_change_bit(nr, void *addr);  

[cpp]view plain

copy

int find_fist_bit(unsigned long *addr, unsigned int size);  

int find_first_zero_bit(unsigned long *addr, unsigned int size);  

第二個引數:是要搜尋的總位數。

返回值:是第乙個被置位(或未被置位)的位號

原子操作 atomic t

1.atomic t 定義及其原因 核心定義了atomic t 資料型別,作為對 整數計數器的原子操作的基礎。cpp view plain copy typedef struct atomic t 這裡引入了乙個特殊的資料型別,而不是直接使用int型別,原因如下 a.讓原子操作函式只接收 atomi...

atomic t相關操作

所謂原子操作,就是該操作絕不會在執行完畢前被任何其他任務或事件打斷,也就說,它的最小的執行單位,不可能有比它更小的執行單位,因此這裡的原子實際是使用了物理學裡的物質微粒的概念。原子操作需要硬體的支援,因此是架構相關的,其api和原子型別的定義都定義在核心原始碼樹的include asm atomic...

原子性,原子操作

舉個例子 a想要從自己的帳戶中轉1000塊錢到b的帳戶裡。那個從a開始轉帳,到轉帳結束的這乙個過程,稱之為乙個事務。在這個事務裡,要做如下操作 從a的帳戶中減去1000塊錢。如果a的帳戶原來有3000塊錢,現在就變成2000塊錢了。在b的帳戶裡加1000塊錢。如果b的帳戶如果原來有2000塊錢,現在...