fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / libcds-2.3.2 / cds / urcu / details / gp_decl.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
15     * Redistributions in binary form must reproduce the above copyright notice,
16       this list of conditions and the following disclaimer in the documentation
17       and/or other materials provided with the distribution.
18
19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef CDSLIB_URCU_DETAILS_GP_DECL_H
32 #define CDSLIB_URCU_DETAILS_GP_DECL_H
33
34 #include <cds/urcu/details/base.h>
35 #include <cds/details/static_functor.h>
36 #include <cds/details/lib.h>
37 #include <cds/user_setup/cache_line.h>
38
39 //@cond
40 namespace cds { namespace urcu { namespace details {
41
42     // We could derive thread_data from thread_list_record
43     // but in this case m_nAccessControl would have offset != 0
44     // that is not so efficiently
45 #   define CDS_GPURCU_DECLARE_THREAD_DATA(tag_) \
46     template <> struct thread_data<tag_> { \
47         atomics::atomic<uint32_t>        m_nAccessControl ; \
48         thread_list_record< thread_data >   m_list ; \
49         char pad_[cds::c_nCacheLineSize]; \
50         thread_data(): m_nAccessControl(0) {} \
51         explicit thread_data( OS::ThreadId owner ): m_nAccessControl(0), m_list(owner) {} \
52         ~thread_data() {} \
53     }
54
55     CDS_GPURCU_DECLARE_THREAD_DATA( general_instant_tag );
56     CDS_GPURCU_DECLARE_THREAD_DATA( general_buffered_tag );
57     CDS_GPURCU_DECLARE_THREAD_DATA( general_threaded_tag );
58
59 #   undef CDS_GPURCU_DECLARE_THREAD_DATA
60
61     template <typename RCUtag>
62     struct gp_singleton_instance
63     {
64         static CDS_EXPORT_API singleton_vtbl *     s_pRCU;
65     };
66 #if !( CDS_COMPILER == CDS_COMPILER_MSVC || (CDS_COMPILER == CDS_COMPILER_INTEL && CDS_OS_INTERFACE == CDS_OSI_WINDOWS))
67     template<> CDS_EXPORT_API singleton_vtbl * gp_singleton_instance< general_instant_tag >::s_pRCU;
68     template<> CDS_EXPORT_API singleton_vtbl * gp_singleton_instance< general_buffered_tag >::s_pRCU;
69     template<> CDS_EXPORT_API singleton_vtbl * gp_singleton_instance< general_threaded_tag >::s_pRCU;
70 #endif
71
72     template <typename GPRCUtag>
73     class gp_thread_gc
74     {
75     public:
76         typedef GPRCUtag                    rcu_tag;
77         typedef typename rcu_tag::rcu_class rcu_class;
78         typedef thread_data< rcu_tag >      thread_record;
79         typedef cds::urcu::details::scoped_lock< gp_thread_gc > scoped_lock;
80
81     protected:
82         static thread_record * get_thread_record();
83
84     public:
85         gp_thread_gc();
86         ~gp_thread_gc();
87     public:
88         static void access_lock();
89         static void access_unlock();
90         static bool is_locked();
91
92         /// Retire pointer \p by the disposer \p Disposer
93         template <typename Disposer, typename T>
94         static void retire( T * p )
95         {
96             retire( p, cds::details::static_functor<Disposer, T>::call );
97         }
98
99         /// Retire pointer \p by the disposer \p pFunc
100         template <typename T>
101         static void retire( T * p, void (* pFunc)(T *))
102         {
103             retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ));
104             retire( rp );
105         }
106
107         /// Retire pointer \p
108         static void retire( retired_ptr& p )
109         {
110             assert( gp_singleton_instance< rcu_tag >::s_pRCU );
111             gp_singleton_instance< rcu_tag >::s_pRCU->retire_ptr( p );
112         }
113     };
114
115 #   define CDS_GP_RCU_DECLARE_THREAD_GC( tag_ ) template <> class thread_gc<tag_>: public gp_thread_gc<tag_> {}
116
117     CDS_GP_RCU_DECLARE_THREAD_GC( general_instant_tag  );
118     CDS_GP_RCU_DECLARE_THREAD_GC( general_buffered_tag );
119     CDS_GP_RCU_DECLARE_THREAD_GC( general_threaded_tag );
120
121 #   undef CDS_GP_RCU_DECLARE_THREAD_GC
122
123     template <class RCUtag>
124     class gp_singleton: public singleton_vtbl
125     {
126     public:
127         typedef RCUtag  rcu_tag;
128         typedef cds::urcu::details::thread_gc< rcu_tag >   thread_gc;
129
130     protected:
131         typedef typename thread_gc::thread_record   thread_record;
132         typedef gp_singleton_instance< rcu_tag >    rcu_instance;
133
134     protected:
135         atomics::atomic<uint32_t>    m_nGlobalControl;
136         thread_list< rcu_tag >          m_ThreadList;
137
138     protected:
139         gp_singleton()
140             : m_nGlobalControl(1)
141         {}
142
143         ~gp_singleton()
144         {}
145
146     public:
147         static gp_singleton * instance()
148         {
149             return static_cast< gp_singleton *>( rcu_instance::s_pRCU );
150         }
151
152         static bool isUsed()
153         {
154             return rcu_instance::s_pRCU != nullptr;
155         }
156
157     public:
158         virtual void retire_ptr( retired_ptr& p ) = 0;
159
160     public: // thread_gc interface
161         thread_record * attach_thread()
162         {
163             return m_ThreadList.alloc();
164         }
165
166         void detach_thread( thread_record * pRec )
167         {
168             m_ThreadList.retire( pRec );
169         }
170
171         uint32_t global_control_word( atomics::memory_order mo ) const
172         {
173             return m_nGlobalControl.load( mo );
174         }
175
176     protected:
177         bool check_grace_period( thread_record * pRec ) const;
178
179         template <class Backoff>
180         void flip_and_wait( Backoff& bkoff );
181     };
182
183 #   define CDS_GP_RCU_DECLARE_SINGLETON( tag_ ) \
184     template <> class singleton< tag_ > { \
185     public: \
186         typedef tag_  rcu_tag ; \
187         typedef cds::urcu::details::thread_gc< rcu_tag >   thread_gc ; \
188     protected: \
189         typedef thread_gc::thread_record            thread_record ; \
190         typedef gp_singleton_instance< rcu_tag >    rcu_instance  ; \
191         typedef gp_singleton< rcu_tag >             rcu_singleton ; \
192     public: \
193         static bool isUsed() { return rcu_singleton::isUsed() ; } \
194         static rcu_singleton * instance() { assert( rcu_instance::s_pRCU ); return static_cast<rcu_singleton *>( rcu_instance::s_pRCU ); } \
195         static thread_record * attach_thread() { return instance()->attach_thread() ; } \
196         static void detach_thread( thread_record * pRec ) { return instance()->detach_thread( pRec ) ; } \
197         static uint32_t global_control_word( atomics::memory_order mo ) { return instance()->global_control_word( mo ) ; } \
198     }
199
200     CDS_GP_RCU_DECLARE_SINGLETON( general_instant_tag  );
201     CDS_GP_RCU_DECLARE_SINGLETON( general_buffered_tag );
202     CDS_GP_RCU_DECLARE_SINGLETON( general_threaded_tag );
203
204 #   undef CDS_GP_RCU_DECLARE_SINGLETON
205
206 }}} // namespace cds::urcu::details
207 //@endcond
208
209 #endif // #ifndef CDSLIB_URCU_DETAILS_GP_DECL_H