176ba5004ff6cd4b1e1e2a59d687fb5d0063dc49
[c11tester.git] / libcdsTest / ms-queue / intrusive_msqueue_hp.cc
1 #include "test_intrusive_msqueue.h"
2
3 #include <stdio.h>
4 #include <cds/init.h>
5 #include <cds/gc/hp.h>
6 #include <cds/intrusive/msqueue.h>
7 #include <vector>
8
9 #define NDEBUG          // disable assert()
10 #include <assert.h>
11 #include <atomic>
12
13 namespace ci = cds::intrusive;
14 typedef cds::gc::HP gc_type;
15
16 typedef cds_test::intrusive_msqueue base_class;
17 typedef typename base_class::base_hook_item< ci::msqueue::node<gc_type>> base_item_type;
18 typedef typename base_class::member_hook_item< ci::msqueue::node<gc_type>> member_item_type;
19
20 typedef cds_test::intrusive_msqueue::mock_disposer mock_disposer;
21
22 template <typename Queue, typename Data>
23 void test_enqueue( Queue& q, Data& arr )
24 {
25     typedef typename Queue::value_type value_type;
26     size_t nSize = arr.size();
27
28     value_type * pv;
29     for ( size_t i = 0; i < nSize; ++i )
30         arr[i].nVal = static_cast<int>(i);
31
32     assert(q.empty());
33     assert(q.size() == 0);
34
35     // pop from empty queue
36 //    pv = q.pop();
37     assert( pv == nullptr );
38     assert( q.empty());
39     assert(q.size() == 0);
40
41 //    pv = q.dequeue();
42     assert( pv == nullptr );
43     assert( q.empty());
44     assert(q.size() == 0);
45
46     for ( size_t i = 0; i < nSize; ++i ) {
47         if ( i & 1 )
48             q.push( arr[i] );
49         else
50             q.enqueue( arr[i] );
51         assert( !q.empty());
52         assert(q.size() == i+1);
53     }
54 }
55
56
57 template <typename Queue, typename Data>
58 void test_dequeue( Queue& q, Data& arr )
59 {
60     typedef typename Queue::value_type value_type;
61     size_t nSize = arr.size();
62
63     value_type * pv;
64 /*
65     for ( size_t i = 0; i < nSize; ++i )
66         arr[i].nVal = static_cast<int>(i);
67
68     assert(q.empty());
69     assert(q.size() == 0);
70
71     // pop from empty queue
72     pv = q.pop();
73     assert( pv == nullptr );
74     assert( q.empty());
75     assert(q.size() == 0);
76
77     pv = q.dequeue();
78     assert( pv == nullptr );
79     assert( q.empty());
80     assert(q.size() == 0);
81
82     // push/pop test
83     for ( size_t i = 0; i < nSize; ++i ) {
84         if ( i & 1 )
85             q.push( arr[i] );
86         else
87             q.enqueue( arr[i] );
88         assert( !q.empty());
89         assert(q.size() == i+1);
90     }
91 */
92
93     for ( size_t i = 0; i < nSize; ++i ) {
94         assert( !q.empty());
95         assert( q.size() == nSize - i );
96         if ( i & 1 )
97             pv = q.pop();
98         else
99             pv = q.dequeue();
100         assert( pv != nullptr );
101         assert( pv->nVal == i);
102     }
103     assert( q.empty());
104     assert( q.size() == 0 );
105
106 /*
107     Queue::gc::scan();
108     --nSize; // last element of array is in queue yet as a dummy item
109     for ( size_t i = 0; i < nSize; ++i ) {
110         assert( arr[i].nDisposeCount == 1 );
111     }
112     assert( arr[nSize].nDisposeCount == 0 );
113
114     // clear test
115     for ( size_t i = 0; i < nSize; ++i )
116         q.push( arr[i] );
117
118     assert( !q.empty());
119     assert( q.size() == nSize );
120
121     q.clear();
122     assert( q.empty());
123     assert( q.size() == 0 );
124
125     Queue::gc::scan();
126     for ( size_t i = 0; i < nSize - 1; ++i ) {
127         printf("nDisCount (2): %d, (i) %lu\n",  arr[i].nDisposeCount, i );
128     }
129     printf("nDisCount: (1) %d\n",  arr[nSize - 1].nDisposeCount ); // this element is in the queue yet
130     assert( arr[nSize].nDisposeCount == 1 );
131 */
132
133 }
134
135 int main () {
136         cds::Initialize();
137
138         {
139                 typedef ci::MSQueue< gc_type, base_item_type > queue_type;      
140                 cds::gc::hp::GarbageCollector::Construct( queue_type::c_nHazardPtrCount, 1, 16 );
141                 cds::threading::Manager::attachThread();
142
143                 {
144                         typedef cds::intrusive::MSQueue< gc_type, base_item_type,
145                             typename ci::msqueue::make_traits<
146                                 ci::opt::disposer< mock_disposer >
147                                 , cds::opt::item_counter< cds::atomicity::item_counter >
148                                 , ci::opt::hook< ci::msqueue::base_hook< ci::opt::gc<gc_type>>>
149                             >::type
150                         > test_queue;
151
152                         std::vector<base_item_type> arr;
153                         arr.resize(5);
154                         printf("test start\n");
155                         {
156                                 std::atomic<int> x;
157                                 atomic_store_explicit(&x, 0xaaa, std::memory_order_seq_cst);
158                                 test_queue q;
159                                 test_enqueue(q, arr);
160                                 atomic_store_explicit(&x, 0xccc, std::memory_order_seq_cst);
161                                 test_dequeue(q, arr);
162                                 atomic_store_explicit(&x, 0xbbb, std::memory_order_seq_cst);
163                         }
164                         printf("test end\n");
165
166 //                      gc_type::scan();
167 //                      check_array( arr );
168
169                 }
170
171         }
172
173         cds::Terminate();
174 }