2010-05-12 21 views
4

我對用戶空間RCU非常感興趣,並試圖通過tr1 :: shared_ptr模擬一個,這裏是代碼,而我真的是併發編程的新手,會有一些專家幫我審查?使用shared_ptr實現RCU(讀取副本更新)?

基本思想是,閱讀器調用get_reading_copy()來獲取當前受保護數據的指針(假設它是第一代或G1)。編寫者調用get_updating_copy()來獲得G1的副本(假設它是G2),並且只有一個編寫者被允許進入關鍵部分。更新完成後,編寫器調用update()進行交換,並使m_data_ptr指向G2數據。正在進行中的讀者和作者現在持有G1的shared_ptr,讀者或作者最終將釋放G1數據。

任何新的讀者都會得到指向G2的指針,新的作者會得到G2的副本(假設它是G3)。有可能G1還沒有發佈,所以多代數據可能共存。

template <typename T> 
class rcu_protected 
{ 
public: 
    typedef T         type; 
    typedef const T        const_type; 
    typedef std::tr1::shared_ptr<type>   rcu_pointer; 
    typedef std::tr1::shared_ptr<const_type> rcu_const_pointer; 

    rcu_protected() : m_is_writing(0), 
         m_is_swapping(0), 
         m_data_ptr (new type()) 
    {} 

    rcu_const_pointer get_reading_copy() 
    { 
     spin_until_eq (m_is_swapping, 0); 

     return m_data_ptr; 
    } 

    rcu_pointer get_updating_copy() 
    { 
     spin_until_eq (m_is_swapping, 0); 

     while (!CAS (m_is_writing, 0, 1)) 
     {/* do sleep for back-off when exceeding maximum retry times */} 

     rcu_pointer new_data_ptr(new type(*m_data_ptr)); 

     // as spin_until_eq does not have memory barrier protection, 
     // we need to place a read barrier to protect the loading of 
     // new_data_ptr not to be re-ordered before its construction 
     _ReadBarrier(); 

     return new_data_ptr; 
    } 

    void update (rcu_pointer new_data_ptr) 
    { 
     while (!CAS (m_is_swapping, 0, 1)) 
     {} 

     m_data_ptr.swap (new_data_ptr); 

     // as spin_until_eq does not have memory barrier protection, 
     // we need to place a write barrier to protect the assignments of 
     // m_is_writing/m_is_swapping be re-ordered bofore the swapping 
     _WriteBarrier(); 

     m_is_writing = 0; 
     m_is_swapping = 0; 
    } 

private: 
    volatile long m_is_writing; 
    volatile long m_is_swapping; 
    rcu_pointer m_data_ptr; 
}; 
+0

我應該使用rw_mutex來保護閱讀和更新,謝謝[email protected]的審查... – yongsun 2010-06-08 08:31:20

回答

1

從第一眼,我就交換電話spin_until_eq,以及相關的自旋鎖,互斥量。如果在關鍵部分內允許有多個作者,那麼我會使用信號量。那些併發機制實現可能依賴於操作系統,所以性能考慮也應該考慮在內;通常,他們比繁忙的等待要好。