Using shared_ptr to implement RCU (read-copy-update)?

I really like RCU (read-copy-update) in user space and trying to simulate one via tr1 :: shared_ptr, here is the code, while I'm really new to parallel programming, do some experts help me revise?

The basic idea is that the reader calls get_reading_copy () to get a pointer to the current protected data (let's say this is generation one or G1). the writer calls get_updating_copy () to get a copy of G1 (say, G2), and only one author is allowed to enter the critical section. After the update is completed, the author calls update () to perform the exchange, and do m_data_ptr pointing to the G2 data. Current readers and the writer now hold shared_ptr (s) G1, and either the reader or author will eventually release the G1 data.

Any new readers will receive a pointer to G2, and the new author will receive a copy of G2 (say, G3). Perhaps G1 has not yet been released, so several generations of data can coexist.

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; }; 
+4
source share
1 answer

At a glance, I exchanged calls to spin_until_eq and their associated locks for the mutex. If more than one writer was allowed in the critical section, I would use a semaphore. These concurrency implementation mechanisms may be OS dependent, so performance considerations should be considered; they are usually better than busy.

+1
source

Source: https://habr.com/ru/post/1309606/


All Articles