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