Merged branch 'master' of https://github.com/Nemo1369/libcds
[libcds.git] / test / unit / stack / intrusive_treiber_stack_hp.cpp
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 #include "test_intrusive_treiber_stack.h"
32
33 #include <cds/gc/hp.h>
34 #include <cds/intrusive/treiber_stack.h>
35
36 namespace {
37
38     namespace ci = cds::intrusive;
39     typedef cds::gc::HP gc_type;
40
41     class IntrusiveTreiberStack_HP : public cds_test::IntrusiveTreiberStack
42     {
43     typedef cds_test::IntrusiveTreiberStack base_class;
44
45     protected:
46         void SetUp()
47         {
48             typedef cds::intrusive::TreiberStack< gc_type, base_hook_item<gc_type>> stack_type;
49
50             cds::gc::hp::GarbageCollector::Construct( stack_type::c_nHazardPtrCount, 1, 16 );
51             cds::threading::Manager::attachThread();
52         }
53
54         void TearDown()
55         {
56             cds::threading::Manager::detachThread();
57             cds::gc::hp::GarbageCollector::Destruct( true );
58         }
59
60         template <typename Stack>
61         void test()
62         {
63             Stack stack;
64             base_class::test( stack );
65         }
66
67         template <typename Stack>
68         void test_dyn( size_t elimination_size )
69         {
70             Stack stack( elimination_size );
71             base_class::test( stack );
72         }
73     };
74
75     TEST_F( IntrusiveTreiberStack_HP, defaulted )
76     {
77         typedef cds::intrusive::TreiberStack< gc_type,
78             base_hook_item<gc_type>
79         > stack_type;
80
81         test<stack_type>();
82     }
83
84     TEST_F( IntrusiveTreiberStack_HP, base )
85     {
86         typedef cds::intrusive::TreiberStack< gc_type,
87             base_hook_item<gc_type>
88             , typename ci::treiber_stack::make_traits<
89                 ci::opt::hook<
90                     ci::treiber_stack::base_hook<
91                         ci::opt::gc<gc_type>
92                     >
93                 >
94             >::type
95         > stack_type;
96
97         test<stack_type>();
98     }
99
100     TEST_F( IntrusiveTreiberStack_HP, base_disposer )
101     {
102         struct traits:
103             ci::treiber_stack::make_traits <
104                 ci::opt::hook<
105                     ci::treiber_stack::base_hook< ci::opt::gc<gc_type> >
106                 >
107                 ,ci::opt::disposer< mock_disposer >
108             >::type
109         {};
110         typedef cds::intrusive::TreiberStack<
111             gc_type,
112             base_hook_item<gc_type>,
113             traits
114         > stack_type;
115
116         test<stack_type>();
117     }
118
119     TEST_F( IntrusiveTreiberStack_HP, member )
120     {
121         struct traits
122             : ci::treiber_stack::make_traits <
123                 ci::opt::hook<
124                     ci::treiber_stack::member_hook<
125                         offsetof( member_hook_item<gc_type>, hMember),
126                         ci::opt::gc<gc_type>
127                     >
128                 >
129             > ::type
130         {};
131         typedef cds::intrusive::TreiberStack<
132             gc_type,
133             member_hook_item<gc_type>,
134             traits
135         > stack_type;
136
137         test<stack_type>();
138     }
139
140     TEST_F( IntrusiveTreiberStack_HP, member_disposer )
141     {
142         struct traits
143             : ci::treiber_stack::make_traits <
144                 ci::opt::hook<
145                     ci::treiber_stack::member_hook<
146                         offsetof( member_hook_item<gc_type>, hMember),
147                         ci::opt::gc<gc_type>
148                     >
149                 >
150                 ,ci::opt::disposer< mock_disposer >
151             >::type
152         {};
153         typedef cds::intrusive::TreiberStack<
154             gc_type,
155             member_hook_item<gc_type>,
156             traits
157         > stack_type;
158
159         test<stack_type>();
160     }
161
162     TEST_F( IntrusiveTreiberStack_HP, relaxed )
163     {
164         typedef cds::intrusive::TreiberStack< gc_type,
165             base_hook_item<gc_type>
166             , typename ci::treiber_stack::make_traits<
167                 ci::opt::memory_model< ci::opt::v::relaxed_ordering >
168             >::type
169         > stack_type;
170
171         test<stack_type>();
172     }
173
174     TEST_F( IntrusiveTreiberStack_HP, elimination )
175     {
176         typedef cds::intrusive::TreiberStack< gc_type,
177             base_hook_item<gc_type>
178             , typename ci::treiber_stack::make_traits<
179                 cds::opt::enable_elimination<true>
180             >::type
181         > stack_type;
182
183         test<stack_type>();
184     }
185
186     TEST_F( IntrusiveTreiberStack_HP, elimination_base )
187     {
188         typedef cds::intrusive::TreiberStack< gc_type,
189             base_hook_item<gc_type>
190             , typename ci::treiber_stack::make_traits<
191                 cds::opt::enable_elimination<true>
192                 ,ci::opt::hook<
193                     ci::treiber_stack::base_hook<
194                         ci::opt::gc<gc_type>
195                     >
196                 >
197             >::type
198         > stack_type;
199
200         test<stack_type>();
201     }
202
203     TEST_F( IntrusiveTreiberStack_HP, elimination_base_dynamic )
204     {
205         typedef cds::intrusive::TreiberStack< gc_type,
206             base_hook_item<gc_type>
207             , typename ci::treiber_stack::make_traits<
208                 cds::opt::enable_elimination<true>
209                 ,ci::opt::hook<
210                     ci::treiber_stack::base_hook<
211                         ci::opt::gc<gc_type>
212                     >
213                 >
214                 ,ci::opt::buffer< ci::opt::v::initialized_dynamic_buffer<void *> >
215             >::type
216         > stack_type;
217
218         test_dyn<stack_type>( 2 );
219     }
220
221     TEST_F( IntrusiveTreiberStack_HP, elimination_base_disposer )
222     {
223         typedef cds::intrusive::TreiberStack< gc_type,
224             base_hook_item<gc_type>
225             , typename ci::treiber_stack::make_traits<
226                 cds::opt::enable_elimination<true>
227                 ,ci::opt::hook<
228                     ci::treiber_stack::base_hook< ci::opt::gc<gc_type> >
229                 >
230                 ,ci::opt::disposer< mock_disposer >
231             >::type
232         > stack_type;
233
234         test<stack_type>();
235     }
236
237     TEST_F( IntrusiveTreiberStack_HP, elimination_member )
238     {
239         typedef cds::intrusive::TreiberStack< gc_type,
240             member_hook_item<gc_type>
241             , typename ci::treiber_stack::make_traits<
242                 cds::opt::enable_elimination<true>
243                 ,ci::opt::hook<
244                     ci::treiber_stack::member_hook<
245                         offsetof( member_hook_item<gc_type>, hMember),
246                         ci::opt::gc<gc_type>
247                     >
248                 >
249             >::type
250         > stack_type;
251
252         test<stack_type>();
253     }
254
255     TEST_F( IntrusiveTreiberStack_HP, elimination_member_dynamic )
256     {
257         typedef cds::intrusive::TreiberStack< gc_type,
258             member_hook_item<gc_type>
259             , typename ci::treiber_stack::make_traits<
260                 cds::opt::enable_elimination<true>
261                 ,ci::opt::hook<
262                     ci::treiber_stack::member_hook<
263                         offsetof( member_hook_item<gc_type>, hMember),
264                         ci::opt::gc<gc_type>
265                     >
266                 >
267                 ,ci::opt::buffer< ci::opt::v::initialized_dynamic_buffer<void *> >
268             >::type
269         > stack_type;
270
271         test_dyn<stack_type>( 2 );
272     }
273
274     TEST_F( IntrusiveTreiberStack_HP, elimination_member_disposer )
275     {
276         typedef cds::intrusive::TreiberStack< gc_type,
277             member_hook_item<gc_type>
278             , typename ci::treiber_stack::make_traits<
279                 cds::opt::enable_elimination<true>
280                 ,ci::opt::hook<
281                     ci::treiber_stack::member_hook<
282                         offsetof( member_hook_item<gc_type>, hMember),
283                         ci::opt::gc<gc_type>
284                     >
285                 >
286                 ,ci::opt::buffer< ci::opt::v::initialized_dynamic_buffer<void *> >
287                 , ci::opt::disposer< mock_disposer >
288             >::type
289         > stack_type;
290
291         test_dyn<stack_type>( 2 );
292     }
293
294 } // namespace
295