33ab6fd502efc89a76bb4fedcf2493b843c0a754
[libcds.git] / test / unit / intrusive-set / test_intrusive_split_lazy_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-2016
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_LAZY_RCU_H
31 #define CDSUNIT_SET_TEST_INTRUSIVE_SPLIT_LAZY_RCU_H
32
33 #include "test_intrusive_set_rcu.h"
34 #include <cds/intrusive/lazy_list_rcu.h>
35 #include <cds/intrusive/split_list_rcu.h>
36
37 namespace ci = cds::intrusive;
38
39 template <class RCU>
40 class IntrusiveSplitLazySet: public cds_test::intrusive_set_rcu
41 {
42     typedef cds_test::intrusive_set_rcu base_class;
43 public:
44     typedef cds::urcu::gc<RCU> rcu_type;
45     typedef typename base_class::base_int_item< ci::split_list::node<ci::lazy_list::node<rcu_type>>>   base_item_type;
46     typedef typename base_class::base_int_item< ci::split_list::node<ci::lazy_list::node<rcu_type, std::mutex>>>   base_mutex_item_type;
47     typedef typename base_class::member_int_item< ci::split_list::node<ci::lazy_list::node<rcu_type>>> member_item_type;
48     typedef typename base_class::member_int_item< ci::split_list::node<ci::lazy_list::node<rcu_type, std::mutex>>> member_mutex_item_type;
49
50 protected:
51     void SetUp()
52     {
53         RCU::Construct();
54         cds::threading::Manager::attachThread();
55     }
56
57     void TearDown()
58     {
59         cds::threading::Manager::detachThread();
60         RCU::Destruct();
61     }
62 };
63
64 TYPED_TEST_CASE_P( IntrusiveSplitLazySet );
65
66 TYPED_TEST_P( IntrusiveSplitLazySet, base_cmp )
67 {
68     typedef typename TestFixture::rcu_type rcu_type;
69     typedef typename TestFixture::base_item_type base_item_type;
70     typedef typename TestFixture::mock_disposer mock_disposer;
71     typedef typename TestFixture::template cmp<base_item_type> cmp;
72     typedef typename TestFixture::hash_int hash_int;
73
74     typedef ci::LazyList< rcu_type
75         , base_item_type
76         , typename ci::lazy_list::make_traits<
77             ci::opt::hook< ci::lazy_list::base_hook< ci::opt::gc< rcu_type > > >
78             , ci::opt::compare< cmp >
79             , ci::opt::disposer< mock_disposer >
80         >::type
81     > bucket_type;
82
83     typedef ci::SplitListSet< rcu_type, bucket_type,
84         typename ci::split_list::make_traits<
85             ci::opt::hash< hash_int >
86         >::type
87     > set_type;
88
89     set_type s( TestFixture::kSize, 2 );
90     this->test( s );
91 }
92
93 TYPED_TEST_P( IntrusiveSplitLazySet, base_less )
94 {
95     typedef typename TestFixture::rcu_type rcu_type;
96     typedef typename TestFixture::base_item_type base_item_type;
97     typedef typename TestFixture::mock_disposer mock_disposer;
98     typedef typename TestFixture::template less<base_item_type> less;
99     typedef typename TestFixture::hash_int hash_int;
100
101     typedef ci::LazyList< rcu_type
102         , base_item_type
103         , typename ci::lazy_list::make_traits<
104             ci::opt::hook< ci::lazy_list::base_hook< ci::opt::gc< rcu_type >>>
105             , ci::opt::less< less >
106             , ci::opt::disposer< mock_disposer >
107         >::type
108     > bucket_type;
109
110     typedef ci::SplitListSet< rcu_type, bucket_type,
111         typename ci::split_list::make_traits<
112             ci::opt::hash< hash_int >
113             , ci::opt::item_counter< cds::atomicity::item_counter >
114         >::type
115     > set_type;
116
117     set_type s( TestFixture::kSize, 2 );
118     this->test( s );
119 }
120
121 TYPED_TEST_P( IntrusiveSplitLazySet, base_cmpmix )
122 {
123     typedef typename TestFixture::rcu_type rcu_type;
124     typedef typename TestFixture::base_item_type base_item_type;
125     typedef typename TestFixture::mock_disposer mock_disposer;
126     typedef typename TestFixture::hash_int hash_int;
127
128     struct list_traits : public ci::lazy_list::traits
129     {
130         typedef ci::lazy_list::base_hook< ci::opt::gc<rcu_type>> hook;
131         typedef typename TestFixture::template less<base_item_type> less;
132         typedef typename TestFixture::template cmp<base_item_type> compare;
133         typedef mock_disposer disposer;
134     };
135     typedef ci::LazyList< rcu_type, base_item_type, list_traits > bucket_type;
136
137     struct set_traits : public ci::split_list::traits
138     {
139         typedef hash_int hash;
140         typedef typename TestFixture::simple_item_counter item_counter;
141         typedef ci::split_list::stat<> stat;
142     };
143     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
144
145     set_type s( TestFixture::kSize, 2 );
146     this->test( s );
147 }
148
149 TYPED_TEST_P( IntrusiveSplitLazySet, base_mutex )
150 {
151     typedef typename TestFixture::rcu_type rcu_type;
152     typedef typename TestFixture::base_mutex_item_type base_mutex_item_type;
153     typedef typename TestFixture::mock_disposer mock_disposer;
154     typedef typename TestFixture::hash_int hash_int;
155
156     struct list_traits : public ci::lazy_list::traits
157     {
158         typedef ci::lazy_list::base_hook< ci::opt::gc<rcu_type>, ci::opt::lock_type<std::mutex>> hook;
159         typedef typename TestFixture::template less<base_mutex_item_type> less;
160         typedef typename TestFixture::template cmp<base_mutex_item_type> compare;
161         typedef mock_disposer disposer;
162     };
163     typedef ci::LazyList< rcu_type, base_mutex_item_type, list_traits > bucket_type;
164
165     struct set_traits : public ci::split_list::traits
166     {
167         typedef hash_int hash;
168         typedef typename TestFixture::simple_item_counter item_counter;
169         typedef cds::backoff::empty back_off;
170     };
171     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
172
173     set_type s( TestFixture::kSize, 2 );
174     this->test( s );
175 }
176
177
178 TYPED_TEST_P( IntrusiveSplitLazySet, member_cmp )
179 {
180     typedef typename TestFixture::rcu_type rcu_type;
181     typedef typename TestFixture::member_item_type member_item_type;
182     typedef typename TestFixture::mock_disposer mock_disposer;
183     typedef typename TestFixture::template cmp<member_item_type> cmp;
184     typedef typename TestFixture::hash_int hash_int;
185
186     typedef ci::LazyList< rcu_type
187         , member_item_type
188         , typename ci::lazy_list::make_traits<
189             ci::opt::hook< ci::lazy_list::member_hook<
190                 offsetof( member_item_type, hMember ),
191                 ci::opt::gc<rcu_type>
192             >>
193             , ci::opt::compare< cmp >
194             , ci::opt::disposer< mock_disposer >
195         >::type
196     >    bucket_type;
197
198     typedef ci::SplitListSet< rcu_type, bucket_type,
199         typename ci::split_list::make_traits<
200             ci::opt::hash< hash_int >
201         >::type
202     > set_type;
203
204     set_type s( TestFixture::kSize, 2 );
205     this->test( s );
206 }
207
208 TYPED_TEST_P( IntrusiveSplitLazySet, member_less )
209 {
210     typedef typename TestFixture::rcu_type rcu_type;
211     typedef typename TestFixture::member_item_type member_item_type;
212     typedef typename TestFixture::mock_disposer mock_disposer;
213     typedef typename TestFixture::template less<member_item_type> less;
214     typedef typename TestFixture::hash_int hash_int;
215
216     typedef ci::LazyList< rcu_type
217         , member_item_type
218         , typename ci::lazy_list::make_traits<
219             ci::opt::hook< ci::lazy_list::member_hook<
220                 offsetof( member_item_type, hMember ),
221                 ci::opt::gc<rcu_type>
222             > >
223             , ci::opt::less< less >
224             , ci::opt::disposer< mock_disposer >
225         >::type
226     > bucket_type;
227
228     typedef ci::SplitListSet< rcu_type, bucket_type,
229         typename ci::split_list::make_traits<
230             ci::opt::hash< hash_int >
231             , ci::opt::back_off< cds::backoff::pause >
232         >::type
233     > set_type;
234
235     set_type s( TestFixture::kSize, 2 );
236     this->test( s );
237 }
238
239 TYPED_TEST_P( IntrusiveSplitLazySet, member_cmpmix )
240 {
241     typedef typename TestFixture::rcu_type rcu_type;
242     typedef typename TestFixture::member_item_type member_item_type;
243     typedef typename TestFixture::mock_disposer mock_disposer;
244     typedef typename TestFixture::hash_int hash_int;
245
246     struct list_traits : public ci::lazy_list::traits
247     {
248         typedef ci::lazy_list::member_hook< offsetof( member_item_type, hMember ), ci::opt::gc<rcu_type>> hook;
249         typedef typename TestFixture::template less<member_item_type> less;
250         typedef typename TestFixture::template cmp<member_item_type> compare;
251         typedef mock_disposer disposer;
252     };
253     typedef ci::LazyList< rcu_type, member_item_type, list_traits > bucket_type;
254
255     struct set_traits : public ci::split_list::traits
256     {
257         typedef hash_int hash;
258         typedef typename TestFixture::simple_item_counter item_counter;
259     };
260     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
261
262     set_type s( TestFixture::kSize, 2 );
263     this->test( s );
264 }
265
266 TYPED_TEST_P( IntrusiveSplitLazySet, member_mutex )
267 {
268     typedef typename TestFixture::rcu_type rcu_type;
269     typedef typename TestFixture::member_mutex_item_type member_mutex_item_type;
270     typedef typename TestFixture::mock_disposer mock_disposer;
271     typedef typename TestFixture::hash_int hash_int;
272
273     struct list_traits : public ci::lazy_list::traits
274     {
275         typedef ci::lazy_list::member_hook< offsetof( member_mutex_item_type, hMember ), ci::opt::gc<rcu_type>, ci::opt::lock_type<std::mutex>> hook;
276         typedef typename TestFixture::template less<member_mutex_item_type> less;
277         typedef typename TestFixture::template cmp<member_mutex_item_type> compare;
278         typedef mock_disposer disposer;
279     };
280     typedef ci::LazyList< rcu_type, member_mutex_item_type, list_traits > bucket_type;
281
282     struct set_traits : public ci::split_list::traits
283     {
284         typedef hash_int hash;
285         typedef typename TestFixture::simple_item_counter item_counter;
286     };
287     typedef ci::SplitListSet< rcu_type, bucket_type, set_traits > set_type;
288
289     set_type s( TestFixture::kSize, 2 );
290     this->test( s );
291 }
292
293
294 // GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as
295 // "No test named <test_name> can be found in this test case"
296 REGISTER_TYPED_TEST_CASE_P( IntrusiveSplitLazySet,
297     base_cmp, base_less, base_cmpmix, base_mutex, member_cmp, member_less, member_cmpmix, member_mutex
298 );
299
300
301 #endif // CDSUNIT_SET_TEST_INTRUSIVE_MICHAEL_LAZY_RCU_H
302