一、原子操作 所謂原子操作,就是該操作絕不會在執行完畢前被任何其他任務或事件打斷,也就說,它是最小的執行單位,不可能有比它更小的執行單位,因此這裡的原子實際是使用了物理學裡的物質微粒的概念。 原子操作需要硬體的支援,因此是架構相關的,其API和原子類型的定義都定義於核心源碼樹的 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實現)。 |