a82ced48ace9efb531b054dd548ecb0f278c1425
[libcds.git] / test / unit / intrusive-set / test_intrusive_split_michael_rcu.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 #ifndef CDSUNIT_SET_TEST_INTRUSIVE_SPLIT_MICHAEL_RCU_H
31 #define CDSUNIT_SET_TEST_INTRUSIVE_SPLIT_MICHAEL_RCU_H
32
33 #include "test_intrusive_set_rcu.h"
34 #include <cds/intrusive/michael_list_rcu.h>
35 #include <cds/intrusive/split_list_rcu.h>
36 #include <cds/intrusive/free_list.h>
37
38 namespace ci = cds::intrusive;
39
40 template <class RCU>
41 class IntrusiveSplitMichaelSet: public cds_test::intrusive_set_rcu
42 {
43     typedef cds_test::intrusive_set_rcu base_class;
44 public:
45     typedef cds::urcu::gc<RCU> rcu_type;
46     typedef typename base_class::base_int_item< ci::split_list::node<ci::michael_list::node<rcu_type>>>   base_item_type;
47     typedef typename base_class::member_int_item< ci::split_list::node<ci::michael_list::node<rcu_type>>> member_item_type;
48
49 protected:
50     void SetUp()
51     {
52         RCU::Construct();
53         cds::threading::Manager::attachThread();
54     }
55
56     void TearDown()
57     {
58         cds::threading::Manager::detachThread();
59         RCU::Destruct();
60     }
61 };
62
63 TYPED_TEST_CASE_P( IntrusiveSplitMichaelSet );
64
65 TYPED_TEST_P( IntrusiveSplitMichaelSet, base_cmp )
66 {
67     typedef typename TestFixture::rcu_type rcu_type;
68     typedef typename TestFixture::base_item_type base_item_type;
69     typedef typename TestFixture::mock_disposer mock_disposer;
70     typedef typename TestFixture::template cmp<base_item_type> cmp;
71     typedef typename TestFixture::hash_int hash_int;
72
73     typedef ci::MichaelList< rcu_type
74         , base_item_type
75         , typename ci::michael_list::make_traits<
76             ci::opt::hook< ci::michael_list::base_hook< ci::opt::gc< rcu_type > > >
77             , ci::opt::compare< cmp >
78             , ci::opt::disposer< mock_disposer >
79         >::type
80     > bucket_type;
81
82     typedef ci::SplitListSet< rcu_type, bucket_type,
83         typename ci::split_list::make_traits<
84             ci::opt::hash< hash_int >
85         >::type
86     > set_type;
87
88     set_type s( TestFixture::kSize, 2 );
89     this->test( s );
90 }
91
92 TYPED_TEST_P( IntrusiveSplitMichaelSet, base_less )
93 {
94     typedef typename TestFixture::rcu_type rcu_type;
95     typedef typename TestFixture::base_item_type base_item_type;
96     typedef typename TestFixture::mock_disposer mock_disposer;
97     typedef typename TestFixture::template less<base_item_type> less;
98     typedef typename TestFixture::hash_int hash_int;
99
100     typedef ci::MichaelList< rcu_type
101         , base_item_type
102         , typename ci::michael_list::make_traits<
103             ci::opt::hook< ci::michael_list::base_hook< ci::opt::gc< rcu_type >>>
104             , ci::opt::less< less >
105             , ci::opt::disposer< mock_disposer >
106         >::type
107     > bucket_type;
108
109     typedef ci::SplitListSet< rcu_type, bucket_type,
110         typename ci::split_list::make_traits<
111             ci::opt::hash< hash_int >
112             , ci::opt::item_counter< cds::atomicity::item_counter >
113         >::type
114     > set_type;
115
116     set_type s( TestFixture::kSize, 2 );
117     this->test( s );
118 }
119
120 TYPED_TEST_P( IntrusiveSplitMichaelSet, base_cmpmix )
121 {
122     typedef typename TestFixture::rcu_type rcu_type;
123     typedef typename TestFixture::base_item_type base_item_type;
124     typedef typename TestFixture::mock_disposer mock_disposer;
125     typedef typename TestFixture::hash_int hash_int;
126
127     struct list_traits : public ci::michael_list::traits
128     {
129         typedef ci::michael_list::base_hook< ci::opt::gc<rcu_type>> hook;
130         typedef typename TestFixture::template less<base_item_type> less;
131         typedef typename TestFixture::template cmp<base_item_type> compare;
132         typedef mock_disposer disposer;
133     };
134     typedef ci::MichaelList< rcu_type, base_item_type, list_traits > bucket_type;
135
136     struct set_traits : public ci::split_list::traits
137     {
138         typedef hash_int hash;
139         typedef typename TestFixture::simple_item_counter item_counter;
140         typedef ci::split_list::stat<> stat;
141     };
142     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
143
144     set_type s( TestFixture::kSize, 2 );
145     this->test( s );
146 }
147
148 TYPED_TEST_P( IntrusiveSplitMichaelSet, base_static_bucket_table )
149 {
150     typedef typename TestFixture::rcu_type rcu_type;
151     typedef typename TestFixture::base_item_type base_item_type;
152     typedef typename TestFixture::mock_disposer mock_disposer;
153     typedef typename TestFixture::hash_int hash_int;
154
155     struct list_traits: public ci::michael_list::traits
156     {
157         typedef ci::michael_list::base_hook< ci::opt::gc<rcu_type>> hook;
158         typedef typename TestFixture::template less<base_item_type> less;
159         typedef typename TestFixture::template cmp<base_item_type> compare;
160         typedef mock_disposer disposer;
161     };
162     typedef ci::MichaelList< rcu_type, base_item_type, list_traits > bucket_type;
163
164     struct set_traits: public ci::split_list::traits
165     {
166         typedef hash_int hash;
167         typedef typename TestFixture::simple_item_counter item_counter;
168         typedef ci::split_list::stat<> stat;
169         enum {
170             dynamic_bucket_table = false
171         };
172     };
173     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
174
175     set_type s( TestFixture::kSize, 2 );
176     this->test( s );
177 }
178
179 TYPED_TEST_P( IntrusiveSplitMichaelSet, base_static_bucket_table_free_list )
180 {
181     typedef typename TestFixture::rcu_type rcu_type;
182     typedef typename TestFixture::base_item_type base_item_type;
183     typedef typename TestFixture::mock_disposer mock_disposer;
184     typedef typename TestFixture::hash_int hash_int;
185
186     struct list_traits: public ci::michael_list::traits
187     {
188         typedef ci::michael_list::base_hook< ci::opt::gc<rcu_type>> hook;
189         typedef typename TestFixture::template cmp<base_item_type> compare;
190         typedef mock_disposer disposer;
191     };
192     typedef ci::MichaelList< rcu_type, base_item_type, list_traits > bucket_type;
193
194     struct set_traits: public ci::split_list::traits
195     {
196         typedef hash_int hash;
197         typedef typename TestFixture::simple_item_counter item_counter;
198         enum {
199             dynamic_bucket_table = false
200         };
201         typedef ci::FreeList free_list;
202     };
203     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
204
205     set_type s( TestFixture::kSize, 2 );
206     this->test( s );
207 }
208
209 TYPED_TEST_P( IntrusiveSplitMichaelSet, base_free_list )
210 {
211     typedef typename TestFixture::rcu_type rcu_type;
212     typedef typename TestFixture::base_item_type base_item_type;
213     typedef typename TestFixture::mock_disposer mock_disposer;
214     typedef typename TestFixture::hash_int hash_int;
215
216     struct list_traits: public ci::michael_list::traits
217     {
218         typedef ci::michael_list::base_hook< ci::opt::gc<rcu_type>> hook;
219         typedef typename TestFixture::template less<base_item_type> less;
220         typedef mock_disposer disposer;
221     };
222     typedef ci::MichaelList< rcu_type, base_item_type, list_traits > bucket_type;
223
224     struct set_traits: public ci::split_list::traits
225     {
226         typedef hash_int hash;
227         typedef typename TestFixture::simple_item_counter item_counter;
228         typedef ci::split_list::stat<> stat;
229         typedef ci::FreeList free_list;
230     };
231     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
232
233     set_type s( TestFixture::kSize, 2 );
234     this->test( s );
235 }
236
237 TYPED_TEST_P( IntrusiveSplitMichaelSet, member_cmp )
238 {
239     typedef typename TestFixture::rcu_type rcu_type;
240     typedef typename TestFixture::member_item_type member_item_type;
241     typedef typename TestFixture::mock_disposer mock_disposer;
242     typedef typename TestFixture::template cmp<member_item_type> cmp;
243     typedef typename TestFixture::hash_int hash_int;
244
245     typedef ci::MichaelList< rcu_type
246         , member_item_type
247         , typename ci::michael_list::make_traits<
248             ci::opt::hook< ci::michael_list::member_hook<
249                 offsetof( member_item_type, hMember ),
250                 ci::opt::gc<rcu_type>
251             >>
252             , ci::opt::compare< cmp >
253             , ci::opt::disposer< mock_disposer >
254         >::type
255     >    bucket_type;
256
257     typedef ci::SplitListSet< rcu_type, bucket_type,
258         typename ci::split_list::make_traits<
259             ci::opt::hash< hash_int >
260         >::type
261     > set_type;
262
263     set_type s( TestFixture::kSize, 2 );
264     this->test( s );
265 }
266
267 TYPED_TEST_P( IntrusiveSplitMichaelSet, member_less )
268 {
269     typedef typename TestFixture::rcu_type rcu_type;
270     typedef typename TestFixture::member_item_type member_item_type;
271     typedef typename TestFixture::mock_disposer mock_disposer;
272     typedef typename TestFixture::template less<member_item_type> less;
273     typedef typename TestFixture::hash_int hash_int;
274
275     typedef ci::MichaelList< rcu_type
276         , member_item_type
277         , typename ci::michael_list::make_traits<
278             ci::opt::hook< ci::michael_list::member_hook<
279                 offsetof( member_item_type, hMember ),
280                 ci::opt::gc<rcu_type>
281             > >
282             , ci::opt::less< less >
283             , ci::opt::disposer< mock_disposer >
284         >::type
285     > bucket_type;
286
287     typedef ci::SplitListSet< rcu_type, bucket_type,
288         typename ci::split_list::make_traits<
289             ci::opt::hash< hash_int >
290             , ci::opt::back_off< cds::backoff::pause >
291         >::type
292     > set_type;
293
294     set_type s( TestFixture::kSize, 2 );
295     this->test( s );
296 }
297
298 TYPED_TEST_P( IntrusiveSplitMichaelSet, member_cmpmix )
299 {
300     typedef typename TestFixture::rcu_type rcu_type;
301     typedef typename TestFixture::member_item_type member_item_type;
302     typedef typename TestFixture::mock_disposer mock_disposer;
303     typedef typename TestFixture::hash_int hash_int;
304
305     struct list_traits : public ci::michael_list::traits
306     {
307         typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<rcu_type>> hook;
308         typedef typename TestFixture::template less<member_item_type> less;
309         typedef typename TestFixture::template cmp<member_item_type> compare;
310         typedef mock_disposer disposer;
311     };
312     typedef ci::MichaelList< rcu_type, member_item_type, list_traits > bucket_type;
313
314     struct set_traits : public ci::split_list::traits
315     {
316         typedef hash_int hash;
317         typedef typename TestFixture::simple_item_counter item_counter;
318     };
319     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
320
321     set_type s( TestFixture::kSize, 2 );
322     this->test( s );
323 }
324
325 TYPED_TEST_P( IntrusiveSplitMichaelSet, member_static_bucket_table )
326 {
327     typedef typename TestFixture::rcu_type rcu_type;
328     typedef typename TestFixture::member_item_type member_item_type;
329     typedef typename TestFixture::mock_disposer mock_disposer;
330     typedef typename TestFixture::hash_int hash_int;
331
332     struct list_traits: public ci::michael_list::traits
333     {
334         typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<rcu_type>> hook;
335         typedef typename TestFixture::template less<member_item_type> less;
336         typedef typename TestFixture::template cmp<member_item_type> compare;
337         typedef mock_disposer disposer;
338     };
339     typedef ci::MichaelList< rcu_type, member_item_type, list_traits > bucket_type;
340
341     struct set_traits: public ci::split_list::traits
342     {
343         typedef hash_int hash;
344         typedef typename TestFixture::simple_item_counter item_counter;
345         enum {
346             dynamic_bucket_table = false
347         };
348     };
349     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
350
351     set_type s( TestFixture::kSize, 2 );
352     this->test( s );
353 }
354
355 TYPED_TEST_P( IntrusiveSplitMichaelSet, member_static_bucket_table_free_list )
356 {
357     typedef typename TestFixture::rcu_type rcu_type;
358     typedef typename TestFixture::member_item_type member_item_type;
359     typedef typename TestFixture::mock_disposer mock_disposer;
360     typedef typename TestFixture::hash_int hash_int;
361
362     struct list_traits: public ci::michael_list::traits
363     {
364         typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<rcu_type>> hook;
365         typedef typename TestFixture::template cmp<member_item_type> compare;
366         typedef mock_disposer disposer;
367     };
368     typedef ci::MichaelList< rcu_type, member_item_type, list_traits > bucket_type;
369
370     struct set_traits: public ci::split_list::traits
371     {
372         typedef hash_int hash;
373         typedef typename TestFixture::simple_item_counter item_counter;
374         enum {
375             dynamic_bucket_table = false
376         };
377         typedef ci::FreeList free_list;
378     };
379     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
380
381     set_type s( TestFixture::kSize, 2 );
382     this->test( s );
383 }
384
385 TYPED_TEST_P( IntrusiveSplitMichaelSet, member_free_list )
386 {
387     typedef typename TestFixture::rcu_type rcu_type;
388     typedef typename TestFixture::member_item_type member_item_type;
389     typedef typename TestFixture::mock_disposer mock_disposer;
390     typedef typename TestFixture::hash_int hash_int;
391
392     struct list_traits: public ci::michael_list::traits
393     {
394         typedef ci::michael_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<rcu_type>> hook;
395         typedef typename TestFixture::template less<member_item_type> less;
396         typedef mock_disposer disposer;
397     };
398     typedef ci::MichaelList< rcu_type, member_item_type, list_traits > bucket_type;
399
400     struct set_traits: public ci::split_list::traits
401     {
402         typedef hash_int hash;
403         typedef typename TestFixture::simple_item_counter item_counter;
404         typedef ci::FreeList free_list;
405     };
406     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
407
408     set_type s( TestFixture::kSize, 2 );
409     this->test( s );
410 }
411
412 // GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as
413 // "No test named <test_name> can be found in this test case"
414 REGISTER_TYPED_TEST_CASE_P( IntrusiveSplitMichaelSet,
415     base_cmp, base_less, base_cmpmix, base_static_bucket_table, base_static_bucket_table_free_list, base_free_list, member_cmp, member_less, member_cmpmix, member_static_bucket_table, member_static_bucket_table_free_list, member_free_list
416 );
417
418
419 #endif // CDSUNIT_SET_TEST_INTRUSIVE_SPLIT_MICHAEL_RCU_H
420