2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
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.
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.
31 #include <gtest/gtest.h>
32 #include <cds/intrusive/fcstack.h>
34 #include <boost/intrusive/list.hpp>
37 class IntrusiveFCStack : public ::testing::Test
40 template <typename Hook>
41 struct base_hook_item : public Hook
51 template <typename Hook>
52 struct member_hook_item
66 void operator ()( T * p )
72 template <class Stack>
75 typedef typename Stack::value_type value_type;
78 ASSERT_TRUE( stack.empty());
80 value_type v1, v2, v3;
84 ASSERT_TRUE( stack.push( v1 ));
85 ASSERT_TRUE( !stack.empty());
86 ASSERT_TRUE( stack.push( v2 ));
87 ASSERT_TRUE( !stack.empty());
88 ASSERT_TRUE( stack.push( v3 ));
89 ASSERT_TRUE( !stack.empty());
93 ASSERT_TRUE( pv != nullptr );
94 ASSERT_EQ( pv->nVal, 3 );
95 ASSERT_TRUE( !stack.empty());
97 ASSERT_TRUE( pv != nullptr );
98 ASSERT_EQ( pv->nVal, 2 );
99 ASSERT_TRUE( !stack.empty());
101 ASSERT_TRUE( pv != nullptr );
102 ASSERT_EQ( pv->nVal, 1 );
103 ASSERT_TRUE( stack.empty());
105 ASSERT_TRUE( pv == nullptr );
106 ASSERT_TRUE( stack.empty());
108 if ( !std::is_same<typename Stack::disposer, cds::intrusive::opt::v::empty_disposer>::value ) {
109 int v1disp = v1.nDisposeCount;
110 int v2disp = v2.nDisposeCount;
111 int v3disp = v3.nDisposeCount;
113 ASSERT_TRUE( stack.push( v1 ));
114 ASSERT_TRUE( stack.push( v2 ));
115 ASSERT_TRUE( stack.push( v3 ));
118 ASSERT_TRUE( stack.empty());
120 EXPECT_EQ( v1.nDisposeCount, v1disp);
121 EXPECT_EQ( v2.nDisposeCount, v2disp);
122 EXPECT_EQ( v3.nDisposeCount, v3disp);
124 ASSERT_TRUE( stack.push( v1 ));
125 ASSERT_TRUE( stack.push( v2 ));
126 ASSERT_TRUE( stack.push( v3 ));
127 ASSERT_TRUE( !stack.empty());
130 ASSERT_TRUE( stack.empty());
132 EXPECT_EQ( v1.nDisposeCount, v1disp + 1 );
133 EXPECT_EQ( v2.nDisposeCount, v2disp + 1 );
134 EXPECT_EQ( v3.nDisposeCount, v3disp + 1 );
139 TEST_F( IntrusiveFCStack, slist )
141 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
142 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type > > stack_type;
146 TEST_F( IntrusiveFCStack, slist_empty_wait_strategy )
148 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
149 struct stack_traits: public cds::intrusive::fcstack::traits
151 typedef cds::algo::flat_combining::wait_strategy::empty wait_strategy;
153 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
157 TEST_F( IntrusiveFCStack, slist_single_mutex_single_condvar )
159 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
160 struct stack_traits: public cds::intrusive::fcstack::traits
162 typedef cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<> wait_strategy;
164 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
168 TEST_F( IntrusiveFCStack, slist_single_mutex_multi_condvar )
170 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
171 struct stack_traits: public cds::intrusive::fcstack::traits
173 typedef cds::algo::flat_combining::wait_strategy::single_mutex_multi_condvar<> wait_strategy;
175 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
179 TEST_F( IntrusiveFCStack, slist_multi_mutex_multi_condvar )
181 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
182 struct stack_traits: public cds::intrusive::fcstack::traits
184 typedef cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<> wait_strategy;
186 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
190 TEST_F( IntrusiveFCStack, slist_single_mutex_single_condvar_2ms )
192 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
193 struct stack_traits: public cds::intrusive::fcstack::traits
195 typedef cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<2> wait_strategy;
197 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
201 TEST_F( IntrusiveFCStack, slist_single_mutex_multi_condvar_3ms )
203 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
204 struct stack_traits: public cds::intrusive::fcstack::traits
206 typedef cds::algo::flat_combining::wait_strategy::single_mutex_multi_condvar<3> wait_strategy;
208 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
212 TEST_F( IntrusiveFCStack, slist_multi_mutex_multi_condvar_2ms )
214 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
215 struct stack_traits: public cds::intrusive::fcstack::traits
217 typedef cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<2> wait_strategy;
219 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
223 TEST_F( IntrusiveFCStack, slist_disposer )
225 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
226 struct stack_traits : public cds::intrusive::fcstack::traits
228 typedef mock_disposer disposer;
230 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
234 TEST_F( IntrusiveFCStack, slist_mutex )
236 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
237 struct stack_traits : public cds::intrusive::fcstack::traits
239 typedef std::mutex lock_type;
241 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
245 TEST_F( IntrusiveFCStack, slist_elimination )
247 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
248 struct stack_traits : public
249 cds::intrusive::fcstack::make_traits <
250 cds::opt::enable_elimination < true >
253 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
257 TEST_F( IntrusiveFCStack, slist_elimination_disposer )
259 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
260 struct stack_traits : public
261 cds::intrusive::fcstack::make_traits <
262 cds::opt::enable_elimination < true >,
263 cds::intrusive::opt::disposer< mock_disposer >,
264 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<>>
267 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
271 TEST_F( IntrusiveFCStack, slist_elimination_stat )
273 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
274 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >,
275 cds::intrusive::fcstack::make_traits<
276 cds::opt::enable_elimination< true >
277 , cds::opt::stat< cds::intrusive::fcstack::stat<> >
278 , cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_multi_condvar<>>
284 TEST_F( IntrusiveFCStack, slist_member )
286 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
287 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
289 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option > > stack_type;
293 TEST_F( IntrusiveFCStack, slist_member_empty_wait_strategy )
295 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
296 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
297 struct stack_traits: public cds::intrusive::fcstack::traits
299 typedef cds::algo::flat_combining::wait_strategy::empty wait_strategy;
302 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option >, stack_traits > stack_type;
306 TEST_F( IntrusiveFCStack, slist_member_single_mutex_single_condvar )
308 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
309 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
310 struct stack_traits: public cds::intrusive::fcstack::traits
312 typedef cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<> wait_strategy;
315 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option >, stack_traits > stack_type;
319 TEST_F( IntrusiveFCStack, slist_member_single_mutex_multi_condvar )
321 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
322 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
323 struct stack_traits: public cds::intrusive::fcstack::traits
325 typedef cds::algo::flat_combining::wait_strategy::single_mutex_multi_condvar<> wait_strategy;
328 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option >, stack_traits > stack_type;
332 TEST_F( IntrusiveFCStack, slist_member_multi_mutex_multi_condvar )
334 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
335 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
336 struct stack_traits: public cds::intrusive::fcstack::traits
338 typedef cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<> wait_strategy;
341 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option >, stack_traits > stack_type;
345 TEST_F( IntrusiveFCStack, slist_member_disposer )
347 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
348 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
349 struct stack_traits : public cds::intrusive::fcstack::traits
351 typedef mock_disposer disposer;
354 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option >, stack_traits > stack_type;
358 TEST_F( IntrusiveFCStack, slist_member_elimination )
360 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
361 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
363 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option >,
364 cds::intrusive::fcstack::make_traits<
365 cds::opt::enable_elimination< true >
371 TEST_F( IntrusiveFCStack, slist_member_elimination_stat )
373 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
374 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
376 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option >,
377 cds::intrusive::fcstack::make_traits<
378 cds::opt::enable_elimination< true >
379 , cds::opt::stat< cds::intrusive::fcstack::stat<> >
380 , cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_multi_condvar<>>
386 TEST_F( IntrusiveFCStack, list )
388 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
389 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type > > stack_type;
393 TEST_F( IntrusiveFCStack, list_mutex )
395 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
396 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type >,
397 cds::intrusive::fcstack::make_traits<
398 cds::opt::lock_type< std::mutex >
405 TEST_F( IntrusiveFCStack, list_elimination )
407 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
408 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type >,
409 cds::intrusive::fcstack::make_traits<
410 cds::opt::enable_elimination< true >
416 TEST_F( IntrusiveFCStack, list_elimination_stat )
418 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
419 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type >,
420 cds::intrusive::fcstack::make_traits<
421 cds::opt::enable_elimination< true >
422 , cds::opt::stat< cds::intrusive::fcstack::stat<> >
423 , cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<>>
429 TEST_F( IntrusiveFCStack, list_member )
431 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
432 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
434 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type, member_option > > stack_type;
438 TEST_F( IntrusiveFCStack, list_member_elimination )
440 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
441 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
443 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type, member_option >,
444 cds::intrusive::fcstack::make_traits<
445 cds::opt::enable_elimination< true >
451 TEST_F( IntrusiveFCStack, list_member_elimination_stat )
453 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
454 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
456 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type, member_option >,
457 cds::intrusive::fcstack::make_traits<
458 cds::opt::enable_elimination< true >
459 , cds::opt::stat< cds::intrusive::fcstack::stat<> >
460 , cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<>>