2010-05-12 3 views
4

나는 사용자 공간 RCU (read-copy-update)에 매우 흥미가 있으며, tr1 :: shared_ptr을 통해 시뮬레이트하려하고 있는데, 여기에 코드가있다. 동시 프로그래밍의 초보자이지만, 전문가가 나를 도울 수있게 도와 주나요?shared_ptr을 사용하여 RCU를 구현 (읽기 - 복사 - 업데이트) 하시겠습니까?

기본적인 아이디어는 reader가 현재 보호 된 데이터의 포인터를 얻기 위해 get_reading_copy()를 호출한다는 것입니다 (세대 1 또는 G1이라고 가정 해 봅시다). writer는 get_updating_copy()를 호출하여 G1의 복사본을 얻습니다 (G2라고 가정 해 봅시다). 단 하나의 작성자 만 중요한 섹션에 들어갈 수 있습니다. 업데이트가 완료되면 작성기는 update()를 호출하여 스왑을 수행하고 m_data_ptr이 G2 데이터를 가리 키도록합니다. 진행중인 독자와 작가는 이제 G1의 shared_ptr (s)를 보유하고 있으며 독자 또는 작성자가 결국 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

답변

1

첫 눈에서, 나는 뮤텍스를 들어, spin_until_eq 통화 및 관련 스핀 락을 교환 할 것입니다. 크리티컬 섹션 내에서 둘 이상의 작가가 허용되면 세마포어를 사용합니다. 이러한 병행 메커니즘 구현은 OS에 따라 다를 수 있으므로 성능 고려 사항도 고려해야합니다. 대개 그들은 바쁜 기다림보다 낫습니다.

관련 문제