Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing shared_ptr to implement RCU (read-copy-update)?
    text
    copied!<p>I'm very interested in the user-space RCU (read-copy-update), and trying to simulate one via tr1::shared_ptr, here is the code, while I'm really a newbie in concurrent programming, would some experts help me to review? </p> <p>The basic idea is, reader calls get_reading_copy() to gain the pointer of current protected data (let's say it's generation one, or G1). writer calls get_updating_copy() to gain a copy of the G1 (let's say it's G2), and only one writer is allowed to enter the critical section. After the updating is done, writer calls update() to do a swap, and make the m_data_ptr pointing to the G2 data. The ongoing readers and the writer now hold the shared_ptr(s) of G1, and either a reader or a writer will eventually deallocate the G1 data. </p> <p>Any new readers would get the pointer to G2, and a new writer would get the copy of G2 (let's say it's G3). It's possible the G1 is not released yet, so multiple generations of data may co-exist.</p> <pre><code>template &lt;typename T&gt; class rcu_protected { public: typedef T type; typedef const T const_type; typedef std::tr1::shared_ptr&lt;type&gt; rcu_pointer; typedef std::tr1::shared_ptr&lt;const_type&gt; 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; }; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload