Removed signal_threaded uRCU
[libcds.git] / test / stress / set / set_type_ellen_bintree.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 CDSUNIT_SET_TYPE_ELLEN_BINTREE_H
32 #define CDSUNIT_SET_TYPE_ELLEN_BINTREE_H
33
34 #include "set_type.h"
35
36 #include <cds/container/ellen_bintree_set_rcu.h>
37 #include <cds/container/ellen_bintree_set_hp.h>
38 #include <cds/container/ellen_bintree_set_dhp.h>
39
40 #include <cds_test/stat_ellenbintree_out.h>
41 #include "framework/ellen_bintree_update_desc_pool.h"
42
43 namespace set {
44
45     template <class GC, typename Key, typename T, typename Traits = cc::ellen_bintree::traits >
46     class EllenBinTreeSet : public cc::EllenBinTreeSet< GC, Key, T, Traits >
47     {
48         typedef cc::EllenBinTreeSet< GC, Key, T, Traits > base_class;
49     public:
50         template <typename Config>
51         EllenBinTreeSet( Config const& /*cfg*/ )
52         {}
53
54         // for testing
55         static CDS_CONSTEXPR bool const c_bExtractSupported = true;
56         static CDS_CONSTEXPR bool const c_bLoadFactorDepended = false;
57         static CDS_CONSTEXPR bool const c_bEraseExactKey = false;
58     };
59
60     struct tag_EllenBinTreeSet;
61
62     template <typename Key, typename Val>
63     struct set_type< tag_EllenBinTreeSet, Key, Val >: public set_type_base< Key, Val >
64     {
65         typedef set_type_base< Key, Val > base_class;
66         typedef typename base_class::key_type key_type;
67         typedef typename base_class::key_val key_val;
68         typedef typename base_class::compare compare;
69         typedef typename base_class::less less;
70         typedef typename base_class::key_less key_less;
71
72         struct ellen_bintree_props {
73             struct key_extractor {
74                 void operator()( key_type& dest, key_val const& src ) const
75                 {
76                     dest = src.key;
77                 }
78             };
79
80             struct less {
81                 bool operator()( key_val const& v1, key_val const& v2 ) const
82                 {
83                     return key_less()( v1.key, v2.key );
84                 }
85                 bool operator()( key_type const& k, key_val const& v ) const
86                 {
87                     return key_less()( k, v.key );
88                 }
89                 bool operator()( key_val const& v, key_type const& k ) const
90                 {
91                     return key_less()( v.key, k );
92                 }
93                 bool operator()( key_type const& k1, key_type const& k2 ) const
94                 {
95                     return key_less()( k1, k2 );
96                 }
97             };
98
99             struct hp_gc {
100                 typedef cc::ellen_bintree::node<cds::gc::HP, key_val>               leaf_node;
101                 typedef cc::ellen_bintree::internal_node< key_type, leaf_node >     internal_node;
102                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
103             };
104
105             struct dhp_gc {
106                 typedef cc::ellen_bintree::node<cds::gc::DHP, key_val>              leaf_node;
107                 typedef cc::ellen_bintree::internal_node< key_type, leaf_node >     internal_node;
108                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
109             };
110
111             struct gpi {
112                 typedef cc::ellen_bintree::node<rcu_gpi, key_val>                   leaf_node;
113                 typedef cc::ellen_bintree::internal_node< key_type, leaf_node >     internal_node;
114                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
115             };
116             struct gpb {
117                 typedef cc::ellen_bintree::node<rcu_gpb, key_val>                   leaf_node;
118                 typedef cc::ellen_bintree::internal_node< key_type, leaf_node >     internal_node;
119                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
120             };
121             struct gpt {
122                 typedef cc::ellen_bintree::node<rcu_gpt, key_val>                   leaf_node;
123                 typedef cc::ellen_bintree::internal_node< key_type, leaf_node >     internal_node;
124                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
125             };
126 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
127             struct shb {
128                 typedef cc::ellen_bintree::node<rcu_shb, key_val>                   leaf_node;
129                 typedef cc::ellen_bintree::internal_node< key_type, leaf_node >     internal_node;
130                 typedef cc::ellen_bintree::update_desc< leaf_node, internal_node >  update_desc;
131             };
132 #endif
133         };
134
135         struct traits_EllenBinTreeSet: public cc::ellen_bintree::make_set_traits<
136             cc::ellen_bintree::key_extractor< typename ellen_bintree_props::key_extractor >
137             ,co::less< typename ellen_bintree_props::less >
138             ,co::node_allocator< ellen_bintree_pool::internal_node_allocator< int > >
139         >::type
140         {};
141
142         struct traits_EllenBinTreeSet_hp : public traits_EllenBinTreeSet
143         {
144             typedef cds::memory::pool_allocator< typename ellen_bintree_props::hp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
145         };
146         typedef EllenBinTreeSet< cds::gc::HP, key_type, key_val, traits_EllenBinTreeSet_hp > EllenBinTreeSet_hp;
147
148         struct traits_EllenBinTreeSet_dhp : public traits_EllenBinTreeSet
149         {
150             typedef cds::memory::pool_allocator< typename ellen_bintree_props::dhp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
151         };
152         typedef EllenBinTreeSet< cds::gc::DHP, key_type, key_val, traits_EllenBinTreeSet_dhp > EllenBinTreeSet_dhp;
153
154         struct traits_EllenBinTreeSet_gpi : public traits_EllenBinTreeSet
155         {
156             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpi::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
157         };
158         typedef EllenBinTreeSet< rcu_gpi, key_type, key_val, traits_EllenBinTreeSet_gpi > EllenBinTreeSet_rcu_gpi;
159
160         struct traits_EllenBinTreeSet_gpb : public traits_EllenBinTreeSet
161         {
162             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
163         };
164         typedef EllenBinTreeSet< rcu_gpb, key_type, key_val, traits_EllenBinTreeSet_gpb > EllenBinTreeSet_rcu_gpb;
165
166         struct traits_EllenBinTreeSet_gpt : public traits_EllenBinTreeSet
167         {
168             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpt::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
169         };
170         typedef EllenBinTreeSet< rcu_gpt, key_type, key_val, traits_EllenBinTreeSet_gpt > EllenBinTreeSet_rcu_gpt;
171
172 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
173         struct traits_EllenBinTreeSet_shb : public traits_EllenBinTreeSet
174         {
175             typedef cds::memory::pool_allocator< typename ellen_bintree_props::shb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
176         };
177         typedef EllenBinTreeSet< rcu_shb, key_type, key_val, traits_EllenBinTreeSet_shb > EllenBinTreeSet_rcu_shb;
178 #endif
179
180         //
181         struct traits_EllenBinTreeSet_yield : public traits_EllenBinTreeSet
182         {
183             typedef cds::backoff::yield back_off;
184         };
185
186         struct traits_EllenBinTreeSet_yield_hp : public traits_EllenBinTreeSet_yield
187         {
188             typedef cds::memory::pool_allocator< typename ellen_bintree_props::hp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
189         };
190         typedef EllenBinTreeSet< cds::gc::HP, key_type, key_val, traits_EllenBinTreeSet_yield_hp > EllenBinTreeSet_yield_hp;
191
192         struct traits_EllenBinTreeSet_yield_dhp : public traits_EllenBinTreeSet_yield
193         {
194             typedef cds::memory::pool_allocator< typename ellen_bintree_props::dhp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
195         };
196         typedef EllenBinTreeSet< cds::gc::DHP, key_type, key_val, traits_EllenBinTreeSet_yield_dhp > EllenBinTreeSet_yield_dhp;
197
198
199         struct traits_EllenBinTreeSet_yield_gpb : public traits_EllenBinTreeSet_yield
200         {
201             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
202         };
203         typedef EllenBinTreeSet< rcu_gpb, key_type, key_val, traits_EllenBinTreeSet_yield_gpb > EllenBinTreeSet_yield_rcu_gpb;
204
205
206         struct traits_EllenBinTreeSet_stat: public cc::ellen_bintree::make_set_traits<
207             cc::ellen_bintree::key_extractor< typename ellen_bintree_props::key_extractor >
208             ,co::less< typename ellen_bintree_props::less >
209             ,co::node_allocator< ellen_bintree_pool::internal_node_allocator< int > >
210             ,co::stat< cc::ellen_bintree::stat<> >
211         >::type
212         {};
213
214         struct traits_EllenBinTreeSet_stat_hp : public traits_EllenBinTreeSet_stat
215         {
216             typedef cds::memory::pool_allocator< typename ellen_bintree_props::hp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
217         };
218         typedef EllenBinTreeSet< cds::gc::HP, key_type, key_val, traits_EllenBinTreeSet_stat_hp > EllenBinTreeSet_hp_stat;
219
220         struct traits_EllenBinTreeSet_stat_dhp : public traits_EllenBinTreeSet_stat
221         {
222             typedef cds::memory::pool_allocator< typename ellen_bintree_props::dhp_gc::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
223         };
224         typedef EllenBinTreeSet< cds::gc::DHP, key_type, key_val, traits_EllenBinTreeSet_stat_dhp > EllenBinTreeSet_dhp_stat;
225
226         struct traits_EllenBinTreeSet_stat_gpi : public traits_EllenBinTreeSet_stat
227         {
228             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpi::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
229         };
230         typedef EllenBinTreeSet< rcu_gpi, key_type, key_val, traits_EllenBinTreeSet_stat_gpi > EllenBinTreeSet_rcu_gpi_stat;
231
232         struct traits_EllenBinTreeSet_stat_gpb : public traits_EllenBinTreeSet_stat
233         {
234             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
235         };
236         typedef EllenBinTreeSet< rcu_gpb, key_type, key_val, traits_EllenBinTreeSet_stat_gpb > EllenBinTreeSet_rcu_gpb_stat;
237
238         struct traits_EllenBinTreeSet_stat_gpt : public traits_EllenBinTreeSet_stat
239         {
240             typedef cds::memory::pool_allocator< typename ellen_bintree_props::gpt::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
241         };
242         typedef EllenBinTreeSet< rcu_gpt, key_type, key_val, traits_EllenBinTreeSet_stat_gpt > EllenBinTreeSet_rcu_gpt_stat;
243
244 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
245         struct traits_EllenBinTreeSet_stat_shb : public traits_EllenBinTreeSet_stat
246         {
247             typedef cds::memory::pool_allocator< typename ellen_bintree_props::shb::update_desc, ellen_bintree_pool::update_desc_pool_accessor > update_desc_allocator;
248         };
249         typedef EllenBinTreeSet< rcu_shb, key_type, key_val, traits_EllenBinTreeSet_stat_shb > EllenBinTreeSet_rcu_shb_stat;
250 #endif
251
252     };
253
254     template <typename GC, typename Key, typename T, typename Traits>
255     static inline void print_stat( cds_test::property_stream& o, EllenBinTreeSet<GC, Key, T, Traits> const& s )
256     {
257         o << s.statistics();
258     }
259
260     namespace ellen_bintree_check {
261         static inline void check_stat( cds::intrusive::ellen_bintree::empty_stat const& /*s*/ )
262         {
263             // Not true for threaded RCU
264             /*
265             EXPECT_EQ( ellen_bintree_pool::internal_node_counter::m_nAlloc.get(), ellen_bintree_pool::internal_node_counter::m_nFree.get());
266             */
267         }
268         static inline void check_stat( cds::intrusive::ellen_bintree::stat<> const& stat )
269         {
270             EXPECT_EQ( stat.m_nInternalNodeCreated, stat.m_nInternalNodeDeleted );
271             EXPECT_EQ( stat.m_nUpdateDescCreated, stat.m_nUpdateDescDeleted );
272             //EXPECT_EQ( ellen_bintree_pool::internal_node_counter::m_nAlloc.get(), ellen_bintree_pool::internal_node_counter::m_nFree.get());
273             EXPECT_EQ( ellen_bintree_pool::internal_node_counter::m_nAlloc.get(), stat.m_nInternalNodeCreated );
274             // true if RCU is not threaded
275             //EXPECT_EQ( stat.m_nInternalNodeDeleted, ellen_bintree_pool::internal_node_counter::m_nFree.get());
276         }
277     }   // namespace ellen_bintree_check
278
279     template <typename GC, typename Key, typename T, typename Traits>
280     static inline void additional_check( EllenBinTreeSet<GC, Key, T, Traits>& s )
281     {
282         //typedef EllenBinTreeSet<GC, Key, T, Traits> set_type;
283         GC::force_dispose();
284         ellen_bintree_check::check_stat( s.statistics());
285     }
286
287     template <typename GC, typename Key, typename T, typename Traits>
288     static inline void additional_cleanup( EllenBinTreeSet<GC, Key, T, Traits>& /*s*/ )
289     {
290         ellen_bintree_pool::internal_node_counter::reset();
291     }
292
293     template <typename GC, typename Key, typename T, typename Traits>
294     static inline void check_before_clear( cds::container::EllenBinTreeSet<GC, Key, T, Traits>& s )
295     {
296         EXPECT_TRUE( s.check_consistency());
297     }
298 } // namespace set
299
300 #define CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, ellen_set_type, key_type, value_type ) \
301     TEST_F( fixture, ellen_set_type ) \
302     { \
303         typedef set::set_type< tag_EllenBinTreeSet, key_type, value_type >::ellen_set_type set_type; \
304         test_case<set_type>(); \
305     }
306
307 #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED
308 #   define CDSSTRESS_EllenBinTreeSet_SHRCU( fixture, test_case, key_type, value_type ) \
309         CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_rcu_shb,      key_type, value_type ) \
310         CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_rcu_shb_stat, key_type, value_type ) \
311
312 #else
313 #   define CDSSTRESS_EllenBinTreeSet_SHRCU( fixture, test_case, key_type, value_type )
314 #endif
315
316
317 #if defined(CDS_STRESS_TEST_LEVEL) && CDS_STRESS_TEST_LEVEL > 0
318 #   define CDSSTRESS_EllenBinTreeSet_HP_1( fixture, test_case, key_type, value_type ) \
319         CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_yield_hp,       key_type, value_type ) \
320         CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_yield_dhp,      key_type, value_type ) \
321         CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_yield_rcu_gpb,  key_type, value_type ) \
322
323 #   define CDSSTRESS_EllenBinTreeSet_RCU_1( fixture, test_case, key_type, value_type ) \
324         CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_rcu_gpi,        key_type, value_type ) \
325         CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_rcu_gpi_stat,   key_type, value_type ) \
326         CDSSTRESS_EllenBinTreeSet_SHRCU( fixture, test_case, key_type, value_type )
327
328 #else
329 #   define CDSSTRESS_EllenBinTreeSet_HP_1( fixture, test_case, key_type, value_type )
330 #   define CDSSTRESS_EllenBinTreeSet_RCU_1( fixture, test_case, key_type, value_type )
331 #endif
332
333 #define CDSSTRESS_EllenBinTreeSet_HP( fixture, test_case, key_type, value_type ) \
334     CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_hp,             key_type, value_type ) \
335     CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_dhp,            key_type, value_type ) \
336     CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_hp_stat,        key_type, value_type ) \
337     CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_dhp_stat,       key_type, value_type ) \
338     CDSSTRESS_EllenBinTreeSet_HP_1( fixture, test_case, key_type, value_type ) \
339
340 #define CDSSTRESS_EllenBinTreeSet_RCU( fixture, test_case, key_type, value_type ) \
341     CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_rcu_gpb,        key_type, value_type ) \
342     CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_rcu_gpt,        key_type, value_type ) \
343     CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_rcu_gpb_stat,   key_type, value_type ) \
344     CDSSTRESS_EllenBinTreeSet_case( fixture, test_case, EllenBinTreeSet_rcu_gpt_stat,   key_type, value_type ) \
345     CDSSTRESS_EllenBinTreeSet_RCU_1( fixture, test_case, key_type, value_type ) \
346
347 #define CDSSTRESS_EllenBinTreeSet( fixture, test_case, key_type, value_type ) \
348     CDSSTRESS_EllenBinTreeSet_HP( fixture, test_case, key_type, value_type ) \
349     CDSSTRESS_EllenBinTreeSet_RCU( fixture, test_case, key_type, value_type ) \
350
351 #endif // #ifndef CDSUNIT_SET_TYPE_ELLEN_BINTREE_H