2014-10-30 56 views
0

我有一個關於在Linux內核中使用循環緩衝區宏的問題。從Linux內核使用循環緩衝區宏

我想從include/linux/circ_buf.h中使用循環緩衝區宏。

ACCESS_ONCE()宏用於確保編譯器從內存中讀取值,而不是嘗試優化訪問。

在循環緩衝區的文檔下面的代碼被賦予作爲製片人的例子:

 spin_lock(&producer_lock); 

     unsigned long head = buffer->head; 
     /* The spin_unlock() and next spin_lock() provide needed ordering. */ 
     unsigned long tail = ACCESS_ONCE(buffer->tail); 

     if (CIRC_SPACE(head, tail, buffer->size) >= 1) { 
      /* insert one item into the buffer */ 
      struct item *item = buffer[head]; 

      produce_item(item); 

      smp_store_release(buffer->head, 
         (head + 1) & (buffer->size - 1)); 

      /* wake_up() will make sure that the head is committed before 
      * waking anyone up */ 
      wake_up(consumer); 
     } 

     spin_unlock(&producer_lock); 

我有3個問題:

  1. 我不肯定的是,如果有什麼在讀取buffer-> tail的值時,我需要使用ACCESS_ONCE,因爲在我的函數中,我只需要讀取buffer-> tail一次。我在函數的開始處讀取該值,然後在整個函數中使用該值。 我假設這個示例代碼的編寫思路是它運行在一個循環中,並且每次迭代都必須從內存中讀取新的尾部值。

  2. 我想如果你有一個生產者和一個消費者,你不需要使用自旋鎖。 爲什麼在這裏使用自旋鎖?

  3. 也有這樣的評論在這裏:

    /* WAKE_UP()將確保頭部被提交之前 *醒來的人了*/

    如果我不使用WAKE_UP我代碼,我需要使用內存屏障嗎? 不是smp_store_release()已經發出內存障礙嗎?

+0

1.您的假設可能是正確的。 2.對於單一生產者/消費者而言,你是正確的,因爲你不需要螺旋鎖,但擁有它們可以使未來更容易。 – 2014-10-30 14:48:51

+0

1.所以我不需要ACCESS_ONCE,如果我只讀取一次該值? 你知道嗎如果我不使用wake_up,而是使用smp_store_release(),如果我需要內存屏障? – Diurpaneus 2014-10-30 15:00:12

+0

對於你的第一個問題,我會這樣想。至於內存障礙,我對SMP Linux不太熟悉 – 2014-10-30 15:03:38

回答

0
  1. 沒有ACCESS_ONCE,編譯器將允許優化代碼,以便它讀取所述可變多次。

  2. 當生產者和消費者可以同時運行,並且共享變量必須以原子方式更新時,您需要自旋鎖。

  3. 無論您使用什麼機制喚醒用戶,都必須確保先前的寫入和喚醒命令是有序的。