3 #ifndef _CDS_URCU_DETAILS_GPI_H
4 #define _CDS_URCU_DETAILS_GPI_H
7 #include <cds/urcu/details/gp.h>
8 #include <cds/algo/backoff_strategy.h>
9 #include <cds/lock/scoped_lock.h>
11 namespace cds { namespace urcu {
13 /// User-space general-purpose RCU with immediate reclamation
15 @headerfile cds/urcu/general_instant.h
17 This is simplest general-purpose RCU implementation. When a thread calls \ref retire_ptr function
18 the RCU \p synchronize function is called that waits until all reader/updater threads end up
19 their read-side critical sections, i.e. until the RCU quiescent state will come.
20 After that the retired object is freed immediately.
21 Thus, the implementation blocks for any retired object
23 There is a wrapper \ref cds_urcu_general_instant_gc "gc<general_instant>" for \p %general_instant class
24 that provides unified RCU interface. You should use this wrapper class instead \p %general_instant
27 - \p Lock - mutex type, default is \p std::mutex
28 - \p Backoff - back-off schema, default is cds::backoff::Default
31 class Lock = std::mutex
32 ,class Backoff = cds::backoff::Default
34 class general_instant: public details::gp_singleton< general_instant_tag >
37 typedef details::gp_singleton< general_instant_tag > base_class;
41 typedef general_instant_tag rcu_tag ; ///< RCU tag
42 typedef Lock lock_type ; ///< Lock type
43 typedef Backoff back_off ; ///< Back-off schema type
45 typedef typename base_class::thread_gc thread_gc ; ///< Thread-side RCU part
46 typedef typename thread_gc::scoped_lock scoped_lock ; ///< Access lock class
48 static bool const c_bBuffered = false ; ///< This RCU does not buffer disposed elements
52 typedef details::gp_singleton_instance< rcu_tag > singleton_ptr;
61 /// Returns singleton instance
62 static general_instant * instance()
64 return static_cast<general_instant *>( base_class::instance() );
67 /// Checks if the singleton is created and ready to use
70 return singleton_ptr::s_pRCU != nullptr;
83 base_class::flip_and_wait( bkoff );
88 /// Creates singleton object
89 static void Construct()
91 if ( !singleton_ptr::s_pRCU )
92 singleton_ptr::s_pRCU = new general_instant();
95 /// Destroys singleton object
96 static void Destruct( bool bDetachAll = false )
100 instance()->m_ThreadList.detach_all();
102 singleton_ptr::s_pRCU = nullptr;
107 /// Retires \p p pointer
109 The method calls \ref synchronize to wait for the end of grace period
110 and calls \p p disposer.
112 virtual void retire_ptr( retired_ptr& p )
119 /// Retires the pointer chain [\p itFirst, \p itLast)
120 template <typename ForwardIterator>
121 void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
123 if ( itFirst != itLast ) {
125 while ( itFirst != itLast ) {
126 retired_ptr p( *itFirst );
134 /// Waits to finish a grace period
137 atomics::atomic_thread_fence( atomics::memory_order_acquire );
139 cds::lock::scoped_lock<lock_type> sl( m_Lock );
143 atomics::atomic_thread_fence( atomics::memory_order_release );
147 // Added for uniformity
148 size_t CDS_CONSTEXPR capacity() const
155 }} // namespace cds::urcu
157 #endif // #ifndef _CDS_URCU_DETAILS_GPI_H