3 #ifndef _CDS_URCU_DETAILS_GPI_H
4 #define _CDS_URCU_DETAILS_GPI_H
6 #include <cds/urcu/details/gp.h>
7 #include <cds/backoff_strategy.h>
8 #include <cds/lock/scoped_lock.h>
10 #include <cds/details/std/mutex.h>
12 namespace cds { namespace urcu {
14 /// User-space general-purpose RCU with immediate reclamation
16 @headerfile cds/urcu/general_instant.h
18 This is simplest general-purpose RCU implementation. When a thread calls \ref retire_ptr function
19 the RCU \p synchronize function is called that waits until all reader/updater threads end up
20 their read-side critical sections, i.e. until the RCU quiescent state will come.
21 After that the retired object is freed immediately.
22 Thus, the implementation blocks for any retired object
24 There is a wrapper \ref cds_urcu_general_instant_gc "gc<general_instant>" for \p %general_instant class
25 that provides unified RCU interface. You should use this wrapper class instead \p %general_instant
28 - \p Lock - mutex type, default is \p std::mutex
29 - \p Backoff - back-off schema, default is cds::backoff::Default
32 class Lock = cds_std::mutex
33 ,class Backoff = cds::backoff::Default
35 class general_instant: public details::gp_singleton< general_instant_tag >
38 typedef details::gp_singleton< general_instant_tag > base_class;
42 typedef general_instant_tag rcu_tag ; ///< RCU tag
43 typedef Lock lock_type ; ///< Lock type
44 typedef Backoff back_off ; ///< Back-off schema type
46 typedef typename base_class::thread_gc thread_gc ; ///< Thread-side RCU part
47 typedef typename thread_gc::scoped_lock scoped_lock ; ///< Access lock class
49 static bool const c_bBuffered = false ; ///< This RCU does not buffer disposed elements
53 typedef details::gp_singleton_instance< rcu_tag > singleton_ptr;
62 /// Returns singleton instance
63 static general_instant * instance()
65 return static_cast<general_instant *>( base_class::instance() );
68 /// Checks if the singleton is created and ready to use
71 return singleton_ptr::s_pRCU != nullptr;
84 base_class::flip_and_wait( bkoff );
89 /// Creates singleton object
90 static void Construct()
92 if ( !singleton_ptr::s_pRCU )
93 singleton_ptr::s_pRCU = new general_instant();
96 /// Destroys singleton object
97 static void Destruct( bool bDetachAll = false )
101 instance()->m_ThreadList.detach_all();
103 singleton_ptr::s_pRCU = nullptr;
108 /// Retires \p p pointer
110 The method calls \ref synchronize to wait for the end of grace period
111 and calls \p p disposer.
113 virtual void retire_ptr( retired_ptr& p )
120 /// Retires the pointer chain [\p itFirst, \p itLast)
121 template <typename ForwardIterator>
122 void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
124 if ( itFirst != itLast ) {
126 while ( itFirst != itLast ) {
127 retired_ptr p( *itFirst );
135 /// Waits to finish a grace period
138 CDS_ATOMIC::atomic_thread_fence( CDS_ATOMIC::memory_order_acquire );
140 cds::lock::scoped_lock<lock_type> sl( m_Lock );
144 CDS_ATOMIC::atomic_thread_fence( CDS_ATOMIC::memory_order_release );
148 // Added for uniformity
149 size_t CDS_CONSTEXPR capacity() const
156 }} // namespace cds::urcu
158 #endif // #ifndef _CDS_URCU_DETAILS_GPI_H