3 #ifndef CDSLIB_URCU_DETAILS_GPI_H
4 #define CDSLIB_URCU_DETAILS_GPI_H
7 #include <cds/urcu/details/gp.h>
8 #include <cds/algo/backoff_strategy.h>
10 namespace cds { namespace urcu {
12 /// User-space general-purpose RCU with immediate reclamation
14 @headerfile cds/urcu/general_instant.h
16 This is simplest general-purpose RCU implementation. When a thread calls \ref retire_ptr function
17 the RCU \p synchronize function is called that waits until all reader/updater threads end up
18 their read-side critical sections, i.e. until the RCU quiescent state will come.
19 After that the retired object is freed immediately.
20 Thus, the implementation blocks for any retired object
22 There is a wrapper \ref cds_urcu_general_instant_gc "gc<general_instant>" for \p %general_instant class
23 that provides unified RCU interface. You should use this wrapper class instead \p %general_instant
26 - \p Lock - mutex type, default is \p std::mutex
27 - \p Backoff - back-off schema, default is cds::backoff::Default
30 class Lock = std::mutex
31 ,class Backoff = cds::backoff::Default
33 class general_instant: public details::gp_singleton< general_instant_tag >
36 typedef details::gp_singleton< general_instant_tag > base_class;
40 typedef general_instant_tag rcu_tag ; ///< RCU tag
41 typedef Lock lock_type ; ///< Lock type
42 typedef Backoff back_off ; ///< Back-off schema type
44 typedef typename base_class::thread_gc thread_gc ; ///< Thread-side RCU part
45 typedef typename thread_gc::scoped_lock scoped_lock ; ///< Access lock class
47 static bool const c_bBuffered = false ; ///< This RCU does not buffer disposed elements
51 typedef details::gp_singleton_instance< rcu_tag > singleton_ptr;
60 /// Returns singleton instance
61 static general_instant * instance()
63 return static_cast<general_instant *>( base_class::instance() );
66 /// Checks if the singleton is created and ready to use
69 return singleton_ptr::s_pRCU != nullptr;
82 base_class::flip_and_wait( bkoff );
87 /// Creates singleton object
88 static void Construct()
90 if ( !singleton_ptr::s_pRCU )
91 singleton_ptr::s_pRCU = new general_instant();
94 /// Destroys singleton object
95 static void Destruct( bool bDetachAll = false )
99 instance()->m_ThreadList.detach_all();
101 singleton_ptr::s_pRCU = nullptr;
106 /// Retires \p p pointer
108 The method calls \ref synchronize to wait for the end of grace period
109 and calls \p p disposer.
111 virtual void retire_ptr( retired_ptr& p )
115 CDS_TSAN_ANNOTATE_IGNORE_RW_BEGIN;
117 CDS_TSAN_ANNOTATE_IGNORE_RW_END;
121 /// Retires the pointer chain [\p itFirst, \p itLast)
122 template <typename ForwardIterator>
123 void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
125 if ( itFirst != itLast ) {
127 while ( itFirst != itLast ) {
128 retired_ptr p( *itFirst );
136 /// Waits to finish a grace period
139 atomics::atomic_thread_fence( atomics::memory_order_acquire );
141 std::unique_lock<lock_type> sl( m_Lock );
145 atomics::atomic_thread_fence( atomics::memory_order_release );
149 // Added for uniformity
150 size_t CDS_CONSTEXPR capacity() const
157 }} // namespace cds::urcu
159 #endif // #ifndef CDSLIB_URCU_DETAILS_GPI_H