issue #11: replace _CDS_ header guard prefix with CDSLIB_
[libcds.git] / cds / urcu / general_instant.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_URCU_GENERAL_INSTANT_H
4 #define CDSLIB_URCU_GENERAL_INSTANT_H
5
6 #include <cds/urcu/details/gpi.h>
7
8 namespace cds { namespace urcu {
9
10     /// User-space general-purpose RCU with immediate reclamation
11     /** @anchor cds_urcu_general_instant_gc
12
13         This is a wrapper around general_instant class used for metaprogramming.
14
15         Template arguments:
16         - \p Lock - mutex type, default is \p std::mutex
17         - \p Backoff - back-off schema, default is cds::backoff::Default
18     */
19     template <
20 #ifdef CDS_DOXGEN_INVOKED
21         class Lock = std::mutex
22        ,class Backoff = cds::backoff::Default
23 #else
24         class Lock
25        ,class Backoff
26 #endif
27     >
28     class gc< general_instant< Lock, Backoff > >: public details::gc_common
29     {
30     public:
31         typedef general_instant< Lock, Backoff >        rcu_implementation   ;   ///< Wrapped URCU implementation
32
33         typedef typename rcu_implementation::rcu_tag     rcu_tag     ;   ///< URCU tag
34         typedef typename rcu_implementation::thread_gc   thread_gc   ;   ///< Thread-side RCU part
35         typedef typename rcu_implementation::scoped_lock scoped_lock ;   ///< Access lock class
36
37         using details::gc_common::atomic_marked_ptr;
38
39     public:
40         /// Creates URCU \p %general_instant singleton
41         gc()
42         {
43             rcu_implementation::Construct();
44         }
45
46         /// Destroys URCU \p %general_instant singleton
47         ~gc()
48         {
49             rcu_implementation::Destruct( true );
50         }
51
52     public:
53         /// Waits to finish a grace period
54         static void synchronize()
55         {
56             rcu_implementation::instance()->synchronize();
57         }
58
59         /// Frees the pointer \p p invoking \p pFunc after end of grace period
60         /**
61             The function calls \ref synchronize to wait for end of grace period
62             and then evaluates disposing expression <tt>pFunc( p )</tt>
63         */
64         template <typename T>
65         static void retire_ptr( T * p, void (* pFunc)(T *) )
66         {
67             retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ) );
68             retire_ptr( rp );
69         }
70
71         /// Frees the pointer \p using \p Disposer after end of grace period
72         /**
73             The function calls \ref synchronize to wait for end of grace period
74             and then evaluates disposing expression <tt>Disposer()( p )</tt>
75         */
76         template <typename Disposer, typename T>
77         static void retire_ptr( T * p )
78         {
79             retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
80         }
81
82         /// Frees the pointer \p after the end of grace period
83         /**
84             The function calls \ref synchronize to wait for end of grace period
85             and then evaluates disposing expression <tt>p.m_funcFree( p.m_p )</tt>
86         */
87         static void retire_ptr( retired_ptr& p )
88         {
89             rcu_implementation::instance()->retire_ptr(p);
90         }
91
92         /// Frees chain [ \p itFirst, \p itLast) in one synchronization cycle
93         template <typename ForwardIterator>
94         static void batch_retire( ForwardIterator itFirst, ForwardIterator itLast )
95         {
96             rcu_implementation::instance()->batch_retire( itFirst, itLast );
97         }
98
99         /// Acquires access lock (so called RCU reader-side lock)
100         /**
101             For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
102         */
103         static void access_lock()
104         {
105             thread_gc::access_lock();
106         }
107
108         /// Releases access lock (so called RCU reader-side lock)
109         /**
110             For safety reasons, it is better to use \ref scoped_lock class for locking/unlocking
111         */
112         static void access_unlock()
113         {
114             thread_gc::access_unlock();
115         }
116
117         /// Checks if the thread is inside read-side critical section (i.e. the lock is acquired)
118         /**
119             Usually, this function is used internally to be convinced
120             that subsequent remove action is not lead to a deadlock.
121         */
122         static bool is_locked()
123         {
124             return thread_gc::is_locked();
125         }
126
127         /// Forced GC cycle call.
128         /**
129             This method does nothing and is introduced only for uniformity with other
130             garbage collectors.
131         */
132         static void force_dispose()
133         {}
134     };
135
136 }} // namespace cds::urcu
137
138 #endif // #ifndef CDSLIB_URCU_GENERAL_INSTANT_H