Merged branch 'master' of https://github.com/Nemo1369/libcds
[libcds.git] / test / unit / queue / intrusive_optqueue_dhp.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_msqueue.h"
32
33 #include <cds/gc/dhp.h>
34 #include <cds/intrusive/optimistic_queue.h>
35 #include <vector>
36
37 namespace {
38     namespace ci = cds::intrusive;
39     typedef cds::gc::DHP gc_type;
40
41
42     class IntrusiveOptQueue_DHP : public cds_test::intrusive_msqueue
43     {
44         typedef cds_test::intrusive_msqueue base_class;
45
46     protected:
47         typedef typename base_class::base_hook_item< ci::optimistic_queue::node<gc_type>> base_item_type;
48         typedef typename base_class::member_hook_item< ci::optimistic_queue::node<gc_type>> member_item_type;
49
50         void SetUp()
51         {
52             typedef ci::OptimisticQueue< gc_type, base_item_type,
53                 typename ci::optimistic_queue::make_traits<
54                     ci::opt::hook< ci::optimistic_queue::base_hook< ci::opt::gc<gc_type>>>
55                 >::type
56             > queue_type;
57
58             cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount );
59             cds::threading::Manager::attachThread();
60         }
61
62         void TearDown()
63         {
64             cds::threading::Manager::detachThread();
65             cds::gc::dhp::smr::destruct();
66         }
67
68         template <typename V>
69         void check_array( V& arr )
70         {
71             for ( size_t i = 0; i < arr.size() - 1; ++i ) {
72                 ASSERT_EQ( arr[i].nDisposeCount, 2 );
73             }
74             ASSERT_EQ( arr.back().nDisposeCount, 1 );
75         }
76     };
77
78     TEST_F( IntrusiveOptQueue_DHP, base_hook )
79     {
80         typedef cds::intrusive::OptimisticQueue< gc_type, base_item_type,
81             typename ci::optimistic_queue::make_traits<
82                 ci::opt::disposer< mock_disposer >
83                 ,ci::opt::hook< ci::optimistic_queue::base_hook< ci::opt::gc<gc_type>>>
84             >::type
85         > test_queue;
86
87         std::vector<base_item_type> arr;
88         arr.resize(100);
89         {
90             test_queue q;
91             test(q, arr);
92         }
93         gc_type::scan();
94         check_array( arr );
95     }
96
97     TEST_F( IntrusiveOptQueue_DHP, base_item_counting )
98     {
99         typedef cds::intrusive::OptimisticQueue< gc_type, base_item_type,
100             typename ci::optimistic_queue::make_traits<
101                 ci::opt::disposer< mock_disposer >
102                 , cds::opt::item_counter< cds::atomicity::item_counter >
103                 , ci::opt::hook< ci::optimistic_queue::base_hook< ci::opt::gc<gc_type>>>
104             >::type
105         > test_queue;
106
107         std::vector<base_item_type> arr;
108         arr.resize(100);
109         {
110             test_queue q;
111             test(q, arr);
112         }
113         gc_type::scan();
114         check_array( arr );
115     }
116
117     TEST_F( IntrusiveOptQueue_DHP, base_stat )
118     {
119         struct traits : public ci::optimistic_queue::traits
120         {
121             typedef ci::optimistic_queue::base_hook< ci::opt::gc<gc_type>> hook;
122             typedef mock_disposer disposer;
123             typedef cds::atomicity::item_counter item_counter;
124             typedef ci::optimistic_queue::stat<> stat;
125             typedef cds::opt::v::sequential_consistent memory_model;
126         };
127         typedef cds::intrusive::OptimisticQueue< gc_type, base_item_type, traits > test_queue;
128
129         std::vector<base_item_type> arr;
130         arr.resize(100);
131         {
132             test_queue q;
133             test(q, arr);
134         }
135         gc_type::scan();
136         check_array( arr );
137     }
138
139     TEST_F( IntrusiveOptQueue_DHP, member_hook )
140     {
141         typedef cds::intrusive::OptimisticQueue< gc_type, member_item_type,
142             typename ci::optimistic_queue::make_traits<
143                 ci::opt::disposer< mock_disposer >
144                 ,ci::opt::hook< ci::optimistic_queue::member_hook<
145                     offsetof( member_item_type, hMember ),
146                     ci::opt::gc<gc_type>
147                 >>
148             >::type
149         > test_queue;
150
151         std::vector<member_item_type> arr;
152         arr.resize( 100 );
153         {
154             test_queue q;
155             test( q, arr );
156         }
157         gc_type::scan();
158         check_array( arr );
159     }
160
161     TEST_F( IntrusiveOptQueue_DHP, member_hook_stat )
162     {
163         struct traits : public ci::optimistic_queue::traits
164         {
165             typedef ci::optimistic_queue::member_hook<
166                 offsetof( member_item_type, hMember ),
167                 ci::opt::gc<gc_type>
168             > hook;
169             typedef mock_disposer disposer;
170             typedef cds::atomicity::item_counter item_counter;
171             typedef ci::optimistic_queue::stat<> stat;
172             typedef cds::opt::v::sequential_consistent memory_model;
173         };
174         typedef cds::intrusive::OptimisticQueue< gc_type, member_item_type, traits > test_queue;
175
176         std::vector<member_item_type> arr;
177         arr.resize( 100 );
178         {
179             test_queue q;
180             test( q, arr );
181         }
182         gc_type::scan();
183         check_array( arr );
184     }
185
186 } // namespace
187