1. 程式人生 > >linux核心部件分析(二)——原子性操作atomic_t +自我分析總結

linux核心部件分析(二)——原子性操作atomic_t +自我分析總結

在任何處理器平臺下,都會有一些原子性操作,供作業系統使用,我們這裡只講x86下面的。

原子操作的概念來自物理學中微粒的概念原子不可再分性,說明原子操作是不會被執行緒排程機制打斷的操作,不會被編譯器自動優化掉,必定執行的操作;

在單處理器情況下,每條指令的執行都是原子性的,但在多處理器情況下,只有那些單獨的讀操作或寫操作才是原子性的。為了彌補這一缺點,x86提供了附加的lock字首,使帶lock字首的讀修改寫指令也能原子性執行。帶lock字首的指令在操作時會鎖住匯流排,使自身的執行即使在多處理器間也是原子性執行的。xchg指令不帶lock字首也是原子性執行,也就是說xchg執行時預設會鎖記憶體匯流排。原子性操作是執行緒間同步的基礎,

Linux專門定義了一種只進行原子操作的型別atomic_t,並提供相關的原子讀寫呼叫API。本節就來分析這些原子操作在x86下的實現。

[cpp] view plain copy  print?
  1. typedefstruct {  
  2.     volatileint counter;  
  3. } atomic_t;  

 原子型別其實是int型別,只是禁止暫存器對其暫存。

[cpp] view plain copy  print?
  1. #define ATOMIC_INIT(i)  { (i) }

原子型別的初始化。32位x86平臺下atomic API在arch/x86/include/asm/atomic_32.h中實現。

[cpp] view plain copy  print?
  1. staticinlineint atomic_read(const atomic_t *v)  
  2. {  
  3.     return v->counter;  
  4. }  
  5. staticinlinevoid atomic_set(atomic_t *v, int i)  
  6. {  
  7.     v->counter = i;  
  8. }  

單獨的讀操作或者寫操作,在x86下都是原子性的。

[cpp] view plain copy  print?
  1. static
    inlinevoid atomic_add(int i, atomic_t *v)  
  2. {  
  3.     asm volatile(LOCK_PREFIX "addl %1,%0"
  4.              : "+m" (v->counter)  
  5.              : "ir" (i));  
  6. }  
  7. staticinlinevoid atomic_sub(int i, atomic_t *v)  
  8. {  
  9.     asm volatile(LOCK_PREFIX "subl %1,%0"
  10.              : "+m" (v->counter)  
  11.              : "ir" (i));  
  12. }  

atomic_add和atomic_sub屬於讀修改寫操作,實現時需要加lock字首。

[cpp] view plain copy  print?
  1. staticinlineint atomic_sub_and_test(int i, atomic_t *v)  
  2. {  
  3.     unsigned char c;  
  4.     asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
  5.              : "+m" (v->counter), "=qm" (c)  
  6.              : "ir" (i) : "memory");  
  7.     return c;  
  8. }  

atomic_sub_and_test執行完減操作後檢查結果是否為0。

[cpp] view plain copy  print?
  1. staticinlinevoid atomic_inc(atomic_t *v)  
  2. {  
  3.     asm volatile(LOCK_PREFIX "incl %0"
  4.              : "+m" (v->counter));  
  5. }  
  6. staticinlinevoid atomic_dec(atomic_t *v)  
  7. {  
  8.     asm volatile(LOCK_PREFIX "decl %0"
  9.              : "+m" (v->counter));  
  10. }  

atomic_inc和atomic_dec是遞增遞減操作。

[cpp] view plain copy  print?
  1. staticinlineint atomic_dec_and_test(atomic_t *v)  
  2. {  
  3.     unsigned char c;  
  4.     asm volatile(LOCK_PREFIX "decl %0; sete %1"
  5.              : "+m" (v->counter), "=qm" (c)  
  6.              : : "memory");  
  7.     return c != 0;  
  8. }  

atomic_dec_and_test在遞減後檢查結果是否為0。

[cpp] view plain copy  print?
  1. staticinlineint atomic_inc_and_test(atomic_t *v)  
  2. {  
  3.     unsigned char c;  
  4.     asm volatile(LOCK_PREFIX "incl %0; sete %1"
  5.              : "+m" (v->counter), "=qm" (c)  
  6.              : : "memory");  
  7.     return c != 0;  
  8. }  

atomic_inc_and_test在遞增後檢查結果是否為0。

[cpp] view plain copy  print?
  1. staticinlineint atomic_add_negative(int i, atomic_t *v)  
  2. {  
  3.     unsigned char c;  
  4.     asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
  5.              : "+m" (v->counter), "=qm" (c)  
  6.              : "ir" (i) : "memory");  
  7.     return c;  
  8. }  

atomic_add_negative在加操作後檢查結果是否為負數。

[cpp] view plain copy  

相關推薦

linux核心部件分析——原子操作atomic_t +自我分析總結

在任何處理器平臺下,都會有一些原子性操作,供作業系統使用,我們這裡只講x86下面的。 原子操作的概念來自物理學中微粒的概念原子不可再分性,說明原子操作是不會被執行緒排程機制打斷的操作,不會被編譯器自動優化掉,必定執行的操作; 在單處理器情況下,每條

Linux核心驅動學習----根檔案系統的構成 (root filesystem)

1、建立根檔案系統目錄和檔案 1.1建立目錄 1.2建立裝置檔案(命令mknod);必須建立裝置檔案---consle\null 1.3建立配置檔案---複製已有的/etc目錄下的檔案

Linux核心--網路棧實現分析--資料包的傳遞過程

本文分析基於Linux Kernel 1.2.13作者:閆明注:標題中的”(上)“,”(下)“表示分析過程基於資料包的傳遞方向:”(上)“表示分析是從底層向上分析、”(下)“表示分析是從上向下分析。上一篇博文中我們從巨集觀上分析了Linux核心中網路棧的初始化過程,這裡我們再

linux設備驅動之misc驅動框架源碼分析

linux驅動開發misc設備驅動1、misc_open函數分析 該函數在driver/char/misc.c中,misc.c是驅動框架實現的,這裏面的misc_Open函數是misc驅動框架為應用層提供的一個打開misc設備的一個接口。 1、首先我們要知道在misc.c中的misc_init函數

Linux入侵分析分析SSH登錄日誌

入侵分析 雲安全 SSH日誌 SSH登錄情況分析 1.wtmp日誌 last last -x -F 2.查看在線用戶情況 (1)w 命令用於顯示已經登陸系統的用戶列表,並顯示用戶正在執行的指令。單獨執行w命令會顯示所有的用戶,您也可指定用戶名稱,僅顯示某位用戶的相關信息。 (2)who am i

Generic Netlink核心實現分析:通訊

前一篇博文中分析了Generic Netlink的訊息結構及核心初始化流程,本文中通過一個示例程式來了解Generic Netlink在核心和應用層之間的單播通訊流程。 示例程式:demo_genetlink_kern.c(核心模組)、demo_genetlink_

嵌入式 Linux開發Kernel移植——kernel核心配置和編譯

嵌入式 Linux開發Kernel移植(二)——kernel核心配置和編譯    本文選擇linux 2.6.35.7版本kernel進行實踐。一、linux kernel原始碼目錄分析Kbuild,K

Linux 驅動開發之核心模組開發 —— 核心模組編譯 Makefile 入門

一、模組的編譯  我們在前面核心編譯中驅動移植那塊,講到驅動編譯分為靜態編譯和動態編譯;靜態編譯即為將驅動直接編譯進核心,動態編譯即為將驅動編譯成模組。 而動態編譯又分為兩種: a -- 內部編譯        在核心原始碼目錄內編譯 b -- 外部編譯        在核

Linux程序分析 父子程序與程序組

ps命令一般用來顯示終端資訊和程序資訊,執行命令ps -eo pid,comm,cmd可以輸出所有程序的資訊,e代表所有程序,後面三個引數是需要輸出的資訊。 第一列PID是一個整數,每一個程序都有一個唯一的PID來代表自己的身份,程序也可以根據PID來識別其他

【原創】Linux虛擬化KVM-Qemu分析之ARMv8虛擬化

# 背景 - `Read the fucking source code!` --By 魯迅 - `A picture is worth a thousand words.` --By 高爾基 說明: 1. KVM版本:5.9.1 2. QEMU版本:5.0.0 3. 工具:Source Insight

【原創】Linux PCI驅動框架分析

# 背 景 - `Read the fucking source code!` --By 魯迅 - `A picture is worth a thousand words.` --By 高爾基 說明: 1. Kernel版本:4.14 2. ARM64處理器 3. 使用工具:Source Insight

【雷電】源代碼分析-- 進入遊戲攻擊

engine 場景 aud 初始 cto onf 不變 addchild ems 效果圖: 程序分析: 初始化GameLayer場景觸摸。背景、音樂、UI及定時間器 bool GameLayer::init() { if (!CCLayer::init())

Linux 系統目錄結構

執行文件 icm sel 系統管理員 修改 tmp win 開始 通用 Linux 系統目錄結構 登錄系統後,在當前命令窗口下輸入命令: ls / 你會看到如下圖所示: 樹狀目錄結構: 以下是對這些目錄的解釋: /bin:bin是Binary的縮寫, 這個目錄存

J2SE核心開發實戰——字符串與包裝類

刪除 i++ cnblogs amp 分支語句 核心 最大 用途 else 字符串與包裝類 一、實驗簡單介紹 在本章。我們將學習一些用於處理字符串的API以及包裝類的相關知識。 本章知識點 字符串API 包裝類及其應用 二、認識字符

vlc源碼分析 播放流程

.net ges bmp pre https 學習 ref lock 流媒體 http://www.cnblogs.com/jiayayao/p/6752388.html   當點擊播放文件或者輸入要播放的文件後,vlc會執行一系列的流程。   首先需要了解視頻以及流媒體處

java代碼實現highchart與數據庫數據結合完整案例分析---折線圖

end idt 。。 客戶端 屬性 hid pla 循環 scrip 作者原創:未經博主允許不許轉載 在上一篇的博客中,展示和分析了如何做一個餅狀圖,有疑問可以參考上一篇博客。 現在分析和展示折線圖的繪制和案例分析, 先展示效果圖: 與餅狀圖不同的是,折線圖展現更多的數據

使用Apriori進行關聯分析

lis 過程 pre alt lock 不一定 根據 返回 req   書接上文(使用Apriori進行關聯分析(一)),介紹如何挖掘關聯規則。 發現關聯規則   我們的目標是通過頻繁項集挖掘到隱藏的關聯規則,換句話說就是關聯規則。   所謂關聯規則,指通過某個元素集推導出

Linux命令匯總

text user 但是 font pda space ech update spa 登錄用戶設置 新創建了一個用戶,用useradd指令,但是發現通過終端無法登陸; echo password | passwd --stdin username 或者 passwd

python的引用計數分析

裏的 %20 賦值 手動 計數 python 作用域 新的 pri python所有對象引用計數被減少1的情況: 一.對象的別名被賦予新的對象; a = 23345455 # 增加了一個引用 b = a # 增加了一個引用 print(sys.getrefcount(

Linux用戶管理Linux系統安裝

linux安裝 1、RedHatLinux安裝前準備硬件要求CPU:Intel、ADM、VIA兼營內存:SDRAM、EDO和DDR,建議容量在128MB以上,最大4GB硬盤:接口類型(IDE、SCSI、USB)、自由空間(最小:500MB、完全安裝:4.5G)網卡:一塊或多塊顯卡:VGAhttp://hard