atomic_inc 原子操作

atomic_inc(&v)對變量v用鎖定總線的單指令進行不可分解的"原子"級增量操作,避免v的值由於中斷或多處理器同時操作造成不確定狀態。
原子操作
  所謂原子操作,就是該操作絕不會在執行完畢前被任何其他任務或事件打斷,也就說,它的最小的執行單位,不可能有比它更小的執行單位,因此這裏的原子實際是使用了物理學裏的物質微粒的概念。
  原子操作需要硬件的支持,因此是架構相關的,其API和原子類型的定義都定義在內核源碼樹的include/asm/atomic.h文件中,它們都使用彙編語言實現,因爲C語言並不能實現這樣的操作。

  原子操作主要用於實現資源計數,很多引用計數(refcnt)就是通過原子操作實現的。原子類型定義如下:      

     typedef struct { volatile int counter; } atomic_t;

  volatile修飾字段告訴gcc不要對該類型的數據做優化處理,對它的訪問都是對內存的訪問,而不是對寄存器的訪問。 
  原子操作API包括: atomic_read(atomic_t * v);
  該函數對原子類型的變量進行原子讀操作,它返回原子類型的變量v的值。 
       atomic_set(atomic_t * v, int i);
  該函數設置原子類型的變量v的值爲i。 
       void atomic_add(int i, atomic_t *v);
  該函數給原子類型的變量v增加值i。 
        atomic_sub(int i, atomic_t *v);
  該函數從原子類型的變量v中減去i。 
       int atomic_sub_and_test(int i, atomic_t *v);
  該函數從原子類型的變量v中減去i,並判斷結果是否爲0,如果爲0,返回真,否則返回假。 
       void atomic_inc(atomic_t *v);
  該函數對原子類型變量v原子地增加1。 
        void atomic_dec(atomic_t *v);
  該函數對原子類型的變量v原子地減1。
       int atomic_dec_and_test(atomic_t *v);
  該函數對原子類型的變量v原子地減1,並判斷結果是否爲0,如果爲0,返回真,否則返回假。 
        int atomic_inc_and_test(atomic_t *v);
  該函數對原子類型的變量v原子地增加1,並判斷結果是否爲0,如果爲0,返回真,否則返回假。 
        int atomic_add_negative(int i, atomic_t *v);
  該函數對原子類型的變量v原子地增加I,並判斷結果是否爲負數,如果是,返回真,否則返回假。 
       int atomic_add_return(int i, atomic_t *v);
  該函數對原子類型的變量v原子地增加i,並且返回指向v的指針。 
       int atomic_sub_return(int i, atomic_t *v);
  該函數從原子類型的變量v中減去i,並且返回指向v的指針。 
       int atomic_inc_return(atomic_t * v);
  該函數對原子類型的變量v原子地增加1並且返回指向v的指針。 
        int atomic_dec_return(atomic_t * v);
  該函數對原子類型的變量v原子地減1並且返回指向v的指針。 
  原子操作通常用於實現資源的引用計數,在TCP/IP協議棧的IP碎片處理中,就使用了引用計數,碎片隊列結構struct ipq描述了一個IP碎片,字段refcnt就是引用計數器,它的類型爲atomic_t,當創建IP碎片時(在函數ip_frag_create中),使用atomic_set函數把它設置爲1,當引用該IP碎片時,就使用函數atomic_inc把引用計數加1。 
  當不需要引用該IP碎片時,就使用函數ipq_put來釋放該IP碎片,ipq_put使用函數atomic_dec_and_test把引用計數減1並判斷引用計數是否爲0,如果是就釋放IP碎片。函數ipq_kill把IP碎片從ipq隊列中刪除,並把該刪除的IP碎片的引用計數減1(通過使用函數atomic_dec實現)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章