Merged branch 'master' of https://github.com/Nemo1369/libcds
[libcds.git] / test / unit / stack / 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_treiber_stack.h"
32
33 #include <cds/gc/hp.h>
34 #include <cds/container/treiber_stack.h>
35
36 namespace {
37
38     namespace cc = cds::container;
39     typedef cds::gc::HP gc_type;
40
41     class TreiberStack_HP : public cds_test::TreiberStack
42     {
43         typedef cds_test::TreiberStack base_class;
44
45     protected:
46         void SetUp()
47         {
48             typedef cc::TreiberStack< gc_type, int > 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( TreiberStack_HP, defaulted )
76     {
77         typedef cc::TreiberStack< gc_type, int > stack_type;
78
79         test<stack_type>();
80     }
81
82     TEST_F( TreiberStack_HP, backoff )
83     {
84         typedef cc::TreiberStack< gc_type, int
85             , typename cc::treiber_stack::make_traits<
86                 cds::opt::back_off< cds::backoff::yield>
87             >::type
88         > stack_type;
89
90         test<stack_type>();
91     }
92
93     TEST_F( TreiberStack_HP, alloc )
94     {
95         // allocator must be rebinded for real value type
96         struct foo;
97
98         typedef cc::TreiberStack< gc_type, int
99             , typename cc::treiber_stack::make_traits<
100                 cds::opt::back_off< cds::backoff::pause>
101                 ,cds::opt::memory_model<cds::opt::v::relaxed_ordering>
102                 ,cds::opt::allocator< std::allocator< foo >>
103             >::type
104         > stack_type;
105
106         test<stack_type>();
107     }
108
109     TEST_F( TreiberStack_HP, elimination )
110     {
111         typedef cc::TreiberStack< gc_type, int
112             , typename cc::treiber_stack::make_traits<
113                 cds::opt::enable_elimination<true>
114             >::type
115         > stack_type;
116
117         test<stack_type>();
118     }
119
120     TEST_F( TreiberStack_HP, elimination_backoff )
121     {
122         struct traits : public cc::treiber_stack::traits
123         {
124             enum {
125                 enable_elimination = true
126             };
127             typedef cds::backoff::pause back_off;
128         };
129         typedef cc::TreiberStack< gc_type, int, traits > stack_type;
130
131         test<stack_type>();
132     }
133
134     TEST_F( TreiberStack_HP, elimination_dynamic )
135     {
136         typedef cc::TreiberStack< gc_type, int
137             , typename cc::treiber_stack::make_traits<
138                 cds::opt::enable_elimination<true>
139                 , cds::opt::buffer< cds::opt::v::initialized_dynamic_buffer<void *> >
140             >::type
141         > stack_type;
142
143         test_dyn<stack_type>( 4 );
144     }
145
146     TEST_F( TreiberStack_HP, elimination_stat )
147     {
148         typedef cc::TreiberStack< gc_type, int
149             , typename cc::treiber_stack::make_traits<
150                 cds::opt::enable_elimination<true>
151                 , cds::opt::stat< cc::treiber_stack::stat<> >
152             >::type
153         > stack_type;
154
155         test<stack_type>();
156     }
157
158     TEST_F( TreiberStack_HP, elimination_dynamic_backoff )
159     {
160         struct traits : public cc::treiber_stack::traits
161         {
162             enum {
163                 enable_elimination = true
164             };
165             typedef cds::opt::v::initialized_dynamic_buffer<void *> buffer;
166             typedef cds::backoff::yield back_off;
167         };
168         typedef cc::TreiberStack< gc_type, int, traits > stack_type;
169
170         test_dyn<stack_type>( 2 );
171     }
172
173 } // namespace