Added wait strategies to flat combining technique
[libcds.git] / test / stress / queue / queue_type.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
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 #ifndef CDSSTRESS_QUEUE_TYPES_H
32 #define CDSSTRESS_QUEUE_TYPES_H
33
34 #include <cds/container/msqueue.h>
35 #include <cds/container/moir_queue.h>
36 #include <cds/container/rwqueue.h>
37 #include <cds/container/optimistic_queue.h>
38 #include <cds/container/tsigas_cycle_queue.h>
39 #include <cds/container/vyukov_mpmc_cycle_queue.h>
40 #include <cds/container/basket_queue.h>
41 #include <cds/container/fcqueue.h>
42 #include <cds/container/fcdeque.h>
43 #include <cds/container/segmented_queue.h>
44
45 #include <cds/gc/hp.h>
46 #include <cds/gc/dhp.h>
47
48 #include "std_queue.h"
49 #include "lock/win32_lock.h"
50 #include "framework/michael_alloc.h"
51
52 #include <boost/container/deque.hpp>
53
54 #include <cds_test/stress_test.h>
55 #include <cds_test/stat_flat_combining_out.h>
56 #include "print_stat.h"
57
58 namespace queue {
59
60     namespace details {
61         template <typename T, typename Traits=cds::container::fcdeque::traits, class Deque=std::deque<T> >
62         class FCDequeL: public cds::container::FCDeque<T, Deque, Traits >
63         {
64             typedef cds::container::FCDeque<T, Deque, Traits > base_class;
65         public:
66             FCDequeL()
67             {}
68
69             FCDequeL(
70                 unsigned int nCompactFactor     ///< Flat combining: publication list compacting factor
71                 ,unsigned int nCombinePassCount ///< Flat combining: number of combining passes for combiner thread
72                 )
73                 : base_class( nCompactFactor, nCombinePassCount )
74             {}
75
76             bool push( T const& v )
77             {
78                 return base_class::push_front( v );
79             }
80             bool enqueue( T const& v )
81             {
82                 return push( v );
83             }
84
85             bool pop( T& v )
86             {
87                 return base_class::pop_back( v );
88             }
89             bool deque( T& v )
90             {
91                 return pop(v);
92             }
93         };
94
95         template <typename T, typename Traits=cds::container::fcdeque::traits, class Deque = std::deque<T> >
96         class FCDequeR: public cds::container::FCDeque<T, Deque, Traits >
97         {
98             typedef cds::container::FCDeque<T, Deque, Traits > base_class;
99         public:
100             FCDequeR()
101             {}
102
103             FCDequeR(
104                 unsigned int nCompactFactor     ///< Flat combining: publication list compacting factor
105                 ,unsigned int nCombinePassCount ///< Flat combining: number of combining passes for combiner thread
106                 )
107                 : base_class( nCompactFactor, nCombinePassCount )
108             {}
109
110             bool push( T const& v )
111             {
112                 return base_class::push_back( v );
113             }
114             bool enqueue( T const& v )
115             {
116                 return push( v );
117             }
118
119             bool pop( T& v )
120             {
121                 return base_class::pop_front( v );
122             }
123             bool deque( T& v )
124             {
125                 return pop(v);
126             }
127         };
128
129     } // namespace details
130
131     template <typename Value>
132     struct Types {
133
134         // MSQueue
135         typedef cds::container::MSQueue<cds::gc::HP,  Value > MSQueue_HP;
136         typedef cds::container::MSQueue<cds::gc::DHP, Value > MSQueue_DHP;
137         typedef cds::container::MoirQueue<cds::gc::HP, Value > MoirQueue_HP;
138         typedef cds::container::MoirQueue<cds::gc::DHP, Value > MoirQueue_DHP;
139
140         struct traits_MSQueue_michaelAlloc : public cds::container::msqueue::traits
141         {
142             typedef memory::MichaelAllocator<int>  allocator;
143         };
144         typedef cds::container::MSQueue<cds::gc::HP,  Value, traits_MSQueue_michaelAlloc > MSQueue_HP_michaelAlloc;
145         typedef cds::container::MSQueue<cds::gc::DHP, Value, traits_MSQueue_michaelAlloc > MSQueue_DHP_michaelAlloc;
146         typedef cds::container::MoirQueue<cds::gc::HP, Value, traits_MSQueue_michaelAlloc > MoirQueue_HP_michaelAlloc;
147         typedef cds::container::MoirQueue<cds::gc::DHP, Value, traits_MSQueue_michaelAlloc > MoirQueue_DHP_michaelAlloc;
148
149         struct traits_MSQueue_seqcst : public
150             cds::container::msqueue::make_traits <
151                 cds::opt::memory_model < cds::opt::v::sequential_consistent >
152             > ::type
153         {};
154         typedef cds::container::MSQueue< cds::gc::HP,  Value, traits_MSQueue_seqcst > MSQueue_HP_seqcst;
155         typedef cds::container::MSQueue< cds::gc::DHP, Value, traits_MSQueue_seqcst > MSQueue_DHP_seqcst;
156         typedef cds::container::MoirQueue< cds::gc::HP, Value, traits_MSQueue_seqcst > MoirQueue_HP_seqcst;
157         typedef cds::container::MoirQueue< cds::gc::DHP, Value, traits_MSQueue_seqcst > MoirQueue_DHP_seqcst;
158
159         // MSQueue + item counter
160         struct traits_MSQueue_ic : public
161             cds::container::msqueue::make_traits <
162                 cds::opt::item_counter < cds::atomicity::item_counter >
163             >::type
164         {};
165         typedef cds::container::MSQueue< cds::gc::HP,  Value, traits_MSQueue_ic > MSQueue_HP_ic;
166         typedef cds::container::MSQueue< cds::gc::DHP, Value, traits_MSQueue_ic > MSQueue_DHP_ic;
167         typedef cds::container::MoirQueue< cds::gc::HP, Value, traits_MSQueue_ic > MoirQueue_HP_ic;
168         typedef cds::container::MoirQueue< cds::gc::DHP, Value, traits_MSQueue_ic > MoirQueue_DHP_ic;
169
170         // MSQueue + stat
171         struct traits_MSQueue_stat: public
172             cds::container::msqueue::make_traits <
173                 cds::opt::stat< cds::container::msqueue::stat<> >
174             >::type
175         {};
176         typedef cds::container::MSQueue< cds::gc::HP,  Value, traits_MSQueue_stat > MSQueue_HP_stat;
177         typedef cds::container::MSQueue< cds::gc::DHP, Value, traits_MSQueue_stat > MSQueue_DHP_stat;
178         typedef cds::container::MoirQueue< cds::gc::HP, Value, traits_MSQueue_stat > MoirQueue_HP_stat;
179         typedef cds::container::MoirQueue< cds::gc::DHP, Value, traits_MSQueue_stat > MoirQueue_DHP_stat;
180
181
182         // OptimisticQueue
183         typedef cds::container::OptimisticQueue< cds::gc::HP, Value > OptimisticQueue_HP;
184         typedef cds::container::OptimisticQueue< cds::gc::DHP, Value > OptimisticQueue_DHP;
185
186         struct traits_OptimisticQueue_michaelAlloc : public cds::container::optimistic_queue::traits
187         {
188             typedef memory::MichaelAllocator<int> allocator;
189         };
190         typedef cds::container::OptimisticQueue< cds::gc::HP,  Value, traits_OptimisticQueue_michaelAlloc > OptimisticQueue_HP_michaelAlloc;
191         typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_michaelAlloc > OptimisticQueue_DHP_michaelAlloc;
192
193         struct traits_OptimisticQueue_seqcst : public cds::container::optimistic_queue::traits
194         {
195             typedef cds::opt::v::sequential_consistent memory_model;
196         };
197         typedef cds::container::OptimisticQueue< cds::gc::HP,  Value, traits_OptimisticQueue_seqcst > OptimisticQueue_HP_seqcst;
198         typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_seqcst > OptimisticQueue_DHP_seqcst;
199
200         struct traits_OptimisticQueue_ic : public cds::container::optimistic_queue::traits
201         {
202             typedef cds::atomicity::item_counter item_counter;
203         };
204         typedef cds::container::OptimisticQueue< cds::gc::HP,  Value, traits_OptimisticQueue_ic > OptimisticQueue_HP_ic;
205         typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_ic > OptimisticQueue_DHP_ic;
206
207         struct traits_OptimisticQueue_stat : public
208             cds::container::optimistic_queue::make_traits <
209                 cds::opt::stat < cds::intrusive::optimistic_queue::stat<> >
210             > ::type
211         {};
212         typedef cds::container::OptimisticQueue< cds::gc::HP,  Value, traits_OptimisticQueue_stat > OptimisticQueue_HP_stat;
213         typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_stat > OptimisticQueue_DHP_stat;
214
215
216         // TsigasCycleQueue
217
218         class TsigasCycleQueue_dyn
219             : public cds::container::TsigasCycleQueue< Value,
220                 typename cds::container::tsigas_queue::make_traits<
221                     cds::opt::buffer< cds::opt::v::initialized_dynamic_buffer< int > >
222                 >::type
223             >
224         {
225             typedef cds::container::TsigasCycleQueue< Value,
226                 typename cds::container::tsigas_queue::make_traits<
227                     cds::opt::buffer< cds::opt::v::initialized_dynamic_buffer< int > >
228                 >::type
229             > base_class;
230         public:
231             TsigasCycleQueue_dyn()
232                 : base_class( 1024 * 64 )
233             {}
234
235             TsigasCycleQueue_dyn( size_t nCapacity )
236                 : base_class( nCapacity )
237             {}
238
239             cds::opt::none statistics() const
240             {
241                 return cds::opt::none();
242             }
243         };
244
245         class TsigasCycleQueue_dyn_michaelAlloc
246             : public cds::container::TsigasCycleQueue< Value,
247                 typename cds::container::tsigas_queue::make_traits<
248                     cds::opt::buffer< cds::opt::v::initialized_dynamic_buffer< int > >
249                     ,cds::opt::allocator< memory::MichaelAllocator<int> >
250                 >::type
251             >
252         {
253             typedef cds::container::TsigasCycleQueue< Value,
254                 typename cds::container::tsigas_queue::make_traits<
255                    cds::opt::buffer< cds::opt::v::initialized_dynamic_buffer< int > >
256                     , cds::opt::allocator< memory::MichaelAllocator<int> >
257                 >::type
258             > base_class;
259         public:
260             TsigasCycleQueue_dyn_michaelAlloc()
261                 : base_class( 1024 * 64 )
262             {}
263
264             TsigasCycleQueue_dyn_michaelAlloc( size_t nCapacity )
265                 : base_class( nCapacity )
266             {}
267
268             cds::opt::none statistics() const
269             {
270                 return cds::opt::none();
271             }
272         };
273
274         class TsigasCycleQueue_dyn_ic
275             : public cds::container::TsigasCycleQueue< Value,
276                 typename cds::container::tsigas_queue::make_traits<
277                     cds::opt::buffer< cds::opt::v::initialized_dynamic_buffer< int > >
278                     ,cds::opt::item_counter< cds::atomicity::item_counter >
279                 >::type
280             >
281         {
282             typedef cds::container::TsigasCycleQueue< Value,
283                 typename cds::container::tsigas_queue::make_traits<
284                     cds::opt::buffer< cds::opt::v::initialized_dynamic_buffer< int > >
285                     ,cds::opt::item_counter< cds::atomicity::item_counter >
286                 >::type
287             > base_class;
288         public:
289             TsigasCycleQueue_dyn_ic()
290                 : base_class( 1024 * 64 )
291             {}
292             TsigasCycleQueue_dyn_ic( size_t nCapacity )
293                 : base_class( nCapacity )
294             {}
295
296             cds::opt::none statistics() const
297             {
298                 return cds::opt::none();
299             }
300         };
301
302         // VyukovMPMCCycleQueue
303         struct traits_VyukovMPMCCycleQueue_dyn : public cds::container::vyukov_queue::traits
304         {
305             typedef cds::opt::v::uninitialized_dynamic_buffer< int > buffer;
306         };
307         class VyukovMPMCCycleQueue_dyn
308             : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn >
309         {
310             typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn > base_class;
311         public:
312             VyukovMPMCCycleQueue_dyn()
313                 : base_class( 1024 * 64 )
314             {}
315             VyukovMPMCCycleQueue_dyn( size_t nCapacity )
316                 : base_class( nCapacity )
317             {}
318
319             cds::opt::none statistics() const
320             {
321                 return cds::opt::none();
322             }
323         };
324
325         struct traits_VyukovMPMCCycleQueue_dyn_michaelAlloc : public cds::container::vyukov_queue::traits
326         {
327             typedef cds::opt::v::uninitialized_dynamic_buffer< int, memory::MichaelAllocator<int> > buffer;
328         };
329         class VyukovMPMCCycleQueue_dyn_michaelAlloc
330             : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_michaelAlloc >
331         {
332             typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_michaelAlloc > base_class;
333         public:
334             VyukovMPMCCycleQueue_dyn_michaelAlloc()
335                 : base_class( 1024 * 64 )
336             {}
337             VyukovMPMCCycleQueue_dyn_michaelAlloc( size_t nCapacity )
338                 : base_class( nCapacity )
339             {}
340
341             cds::opt::none statistics() const
342             {
343                 return cds::opt::none();
344             }
345         };
346
347         struct traits_VyukovMPMCCycleQueue_dyn_ic : public traits_VyukovMPMCCycleQueue_dyn
348         {
349             typedef cds::atomicity::item_counter item_counter;
350         };
351         class VyukovMPMCCycleQueue_dyn_ic
352             : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_ic >
353         {
354             typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_ic > base_class;
355         public:
356             VyukovMPMCCycleQueue_dyn_ic()
357                 : base_class( 1024 * 64 )
358             {}
359             VyukovMPMCCycleQueue_dyn_ic( size_t nCapacity )
360                 : base_class( nCapacity )
361             {}
362
363             cds::opt::none statistics() const
364             {
365                 return cds::opt::none();
366             }
367         };
368
369
370         // BasketQueue
371
372         typedef cds::container::BasketQueue< cds::gc::HP , Value > BasketQueue_HP;
373         typedef cds::container::BasketQueue< cds::gc::DHP, Value > BasketQueue_DHP;
374
375         struct traits_BasketQueue_michaelAlloc : public cds::container::basket_queue::traits
376         {
377             typedef memory::MichaelAllocator<int> allocator;
378         };
379         typedef cds::container::BasketQueue< cds::gc::HP,  Value, traits_BasketQueue_michaelAlloc > BasketQueue_HP_michaelAlloc;
380         typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_michaelAlloc > BasketQueue_DHP_michaelAlloc;
381
382         struct traits_BasketQueue_seqcst : public cds::container::basket_queue::traits
383         {
384             typedef cds::opt::v::sequential_consistent mamory_model;
385         };
386         typedef cds::container::BasketQueue< cds::gc::HP,  Value, traits_BasketQueue_seqcst > BasketQueue_HP_seqcst;
387         typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_seqcst > BasketQueue_DHP_seqcst;
388
389         struct traits_BasketQueue_ic : public cds::container::basket_queue::traits
390         {
391             typedef cds::atomicity::item_counter item_counter;
392         };
393         typedef cds::container::BasketQueue< cds::gc::HP,  Value, traits_BasketQueue_ic >BasketQueue_HP_ic;
394         typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_ic >BasketQueue_DHP_ic;
395
396         struct traits_BasketQueue_stat : public cds::container::basket_queue::traits
397         {
398             typedef cds::container::basket_queue::stat<> stat;
399         };
400         typedef cds::container::BasketQueue< cds::gc::HP,  Value, traits_BasketQueue_stat > BasketQueue_HP_stat;
401         typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_stat > BasketQueue_DHP_stat;
402
403
404         // RWQueue
405         typedef cds::container::RWQueue< Value > RWQueue_Spin;
406
407         struct traits_RWQueue_Spin_ic : public cds::container::rwqueue::traits
408         {
409             typedef cds::atomicity::item_counter item_counter;
410         };
411         typedef cds::container::RWQueue< Value, traits_RWQueue_Spin_ic > RWQueue_Spin_ic;
412
413         struct traits_RWQueue_mutex : public
414             cds::container::rwqueue::make_traits<
415                 cds::opt::lock_type< std::mutex >
416             >::type
417         {};
418         typedef cds::container::RWQueue< Value, traits_RWQueue_mutex > RWQueue_mutex;
419
420         // FCQueue
421         struct traits_FCQueue_single_mutex_single_condvar:
422             public cds::container::fcqueue::make_traits<
423                 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<>>
424             >::type
425         {};
426         struct traits_FCQueue_single_mutex_single_condvar_stat: traits_FCQueue_single_mutex_single_condvar
427         {
428             typedef cds::container::fcqueue::stat<> stat;
429         };
430         struct traits_FCQueue_single_mutex_multi_condvar:
431             public cds::container::fcqueue::make_traits<
432                 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_multi_condvar<>>
433             >::type
434         {};
435         struct traits_FCQueue_single_mutex_multi_condvar_stat: traits_FCQueue_single_mutex_multi_condvar
436         {
437             typedef cds::container::fcqueue::stat<> stat;
438         };
439         struct traits_FCQueue_multi_mutex_multi_condvar:
440             public cds::container::fcqueue::make_traits<
441                 cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<>>
442             >::type
443         {};
444         struct traits_FCQueue_multi_mutex_multi_condvar_stat: traits_FCQueue_multi_mutex_multi_condvar
445         {
446             typedef cds::container::fcqueue::stat<> stat;
447         };
448         struct traits_FCQueue_elimination:
449             public cds::container::fcqueue::make_traits<
450                 cds::opt::enable_elimination< true >
451             >::type
452         {};
453         struct traits_FCQueue_elimination_stat:
454             public cds::container::fcqueue::make_traits<
455                 cds::opt::enable_elimination< true >
456                 ,cds::opt::stat< cds::container::fcqueue::stat<> >
457             >::type
458         {};
459
460         typedef cds::container::FCQueue< Value > FCQueue_deque;
461         typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_single_mutex_single_condvar> FCQueue_deque_wait_ss;
462         typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_single_mutex_single_condvar_stat> FCQueue_deque_wait_ss_stat;
463         typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_single_mutex_multi_condvar> FCQueue_deque_wait_sm;
464         typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_single_mutex_multi_condvar_stat> FCQueue_deque_wait_sm_stat;
465         typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_multi_mutex_multi_condvar> FCQueue_deque_wait_mm;
466         typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_multi_mutex_multi_condvar_stat> FCQueue_deque_wait_mm_stat;
467
468         typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_elimination > FCQueue_deque_elimination;
469         typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_elimination_stat > FCQueue_deque_elimination_stat;
470
471         typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value> >> FCQueue_list;
472         typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value>>, traits_FCQueue_single_mutex_single_condvar> FCQueue_list_wait_ss;
473         typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value>>, traits_FCQueue_single_mutex_single_condvar_stat> FCQueue_list_wait_ss_stat;
474         typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value>>, traits_FCQueue_single_mutex_multi_condvar> FCQueue_list_wait_sm;
475         typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value>>, traits_FCQueue_single_mutex_multi_condvar_stat> FCQueue_list_wait_sm_stat;
476         typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value>>, traits_FCQueue_multi_mutex_multi_condvar> FCQueue_list_wait_mm;
477         typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value>>, traits_FCQueue_multi_mutex_multi_condvar_stat> FCQueue_list_wait_mm_stat;
478
479         typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value> >, traits_FCQueue_elimination > FCQueue_list_elimination;
480         typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value> >, traits_FCQueue_elimination_stat > FCQueue_list_elimination_stat;
481
482
483    // FCDeque
484         struct traits_FCDeque_stat:
485             public cds::container::fcdeque::make_traits<
486                 cds::opt::stat< cds::container::fcdeque::stat<> >
487             >::type
488         {};
489         struct traits_FCDeque_elimination:
490             public cds::container::fcdeque::make_traits<
491                 cds::opt::enable_elimination< true >
492             >::type
493         {};
494         struct traits_FCDeque_elimination_stat:
495             public cds::container::fcdeque::make_traits<
496                 cds::opt::stat< cds::container::fcdeque::stat<> >,
497                 cds::opt::enable_elimination< true >
498             >::type
499         {};
500         struct traits_FCDeque_mutex:
501             public cds::container::fcdeque::make_traits<
502                 cds::opt::lock_type< std::mutex >
503             >::type
504         {};
505
506         struct traits_FCDeque_wait_ss: cds::container::fcdeque::traits
507         {
508             typedef cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<> wait_strategy;
509         };
510         struct traits_FCDeque_wait_ss_stat: traits_FCDeque_wait_ss
511         {
512             typedef cds::container::fcdeque::stat<> stat;
513         };
514         struct traits_FCDeque_wait_sm: cds::container::fcdeque::traits
515         {
516             typedef cds::algo::flat_combining::wait_strategy::single_mutex_multi_condvar<> wait_strategy;
517         };
518         struct traits_FCDeque_wait_sm_stat: traits_FCDeque_wait_sm
519         {
520             typedef cds::container::fcdeque::stat<> stat;
521         };
522         struct traits_FCDeque_wait_mm: cds::container::fcdeque::traits
523         {
524             typedef cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<> wait_strategy;
525         };
526         struct traits_FCDeque_wait_mm_stat: traits_FCDeque_wait_mm
527         {
528             typedef cds::container::fcdeque::stat<> stat;
529         };
530
531         typedef details::FCDequeL< Value > FCDequeL_default;
532         typedef details::FCDequeL< Value, traits_FCDeque_mutex > FCDequeL_mutex;
533         typedef details::FCDequeL< Value, traits_FCDeque_stat > FCDequeL_stat;
534         typedef details::FCDequeL< Value, traits_FCDeque_wait_ss > FCDequeL_wait_ss;
535         typedef details::FCDequeL< Value, traits_FCDeque_wait_ss_stat > FCDequeL_wait_ss_stat;
536         typedef details::FCDequeL< Value, traits_FCDeque_wait_sm > FCDequeL_wait_sm;
537         typedef details::FCDequeL< Value, traits_FCDeque_wait_sm_stat > FCDequeL_wait_sm_stat;
538         typedef details::FCDequeL< Value, traits_FCDeque_wait_mm > FCDequeL_wait_mm;
539         typedef details::FCDequeL< Value, traits_FCDeque_wait_mm_stat > FCDequeL_wait_mm_stat;
540         typedef details::FCDequeL< Value, traits_FCDeque_elimination > FCDequeL_elimination;
541         typedef details::FCDequeL< Value, traits_FCDeque_elimination_stat > FCDequeL_elimination_stat;
542
543         typedef details::FCDequeL< Value, cds::container::fcdeque::traits, boost::container::deque<Value> > FCDequeL_boost;
544         typedef details::FCDequeL< Value, traits_FCDeque_stat, boost::container::deque<Value> > FCDequeL_boost_stat;
545         typedef details::FCDequeL< Value, traits_FCDeque_elimination, boost::container::deque<Value> > FCDequeL_boost_elimination;
546         typedef details::FCDequeL< Value, traits_FCDeque_elimination_stat, boost::container::deque<Value> > FCDequeL_boost_elimination_stat;
547
548         typedef details::FCDequeR< Value > FCDequeR_default;
549         typedef details::FCDequeR< Value, traits_FCDeque_mutex > FCDequeR_mutex;
550         typedef details::FCDequeR< Value, traits_FCDeque_stat > FCDequeR_stat;
551         typedef details::FCDequeR< Value, traits_FCDeque_wait_ss > FCDequeR_wait_ss;
552         typedef details::FCDequeR< Value, traits_FCDeque_wait_ss_stat > FCDequeR_wait_ss_stat;
553         typedef details::FCDequeR< Value, traits_FCDeque_wait_sm > FCDequeR_wait_sm;
554         typedef details::FCDequeR< Value, traits_FCDeque_wait_sm_stat > FCDequeR_wait_sm_stat;
555         typedef details::FCDequeR< Value, traits_FCDeque_wait_mm > FCDequeR_wait_mm;
556         typedef details::FCDequeR< Value, traits_FCDeque_wait_mm_stat > FCDequeR_wait_mm_stat;
557         typedef details::FCDequeR< Value, traits_FCDeque_elimination > FCDequeR_elimination;
558         typedef details::FCDequeR< Value, traits_FCDeque_elimination_stat > FCDequeR_elimination_stat;
559
560         typedef details::FCDequeR< Value, cds::container::fcdeque::traits, boost::container::deque<Value> > FCDequeR_boost;
561         typedef details::FCDequeR< Value, traits_FCDeque_stat, boost::container::deque<Value> > FCDequeR_boost_stat;
562         typedef details::FCDequeR< Value, traits_FCDeque_elimination, boost::container::deque<Value> > FCDequeR_boost_elimination;
563         typedef details::FCDequeR< Value, traits_FCDeque_elimination_stat, boost::container::deque<Value> > FCDequeR_boost_elimination_stat;
564
565         // STL
566         typedef StdQueue_deque<Value>               StdQueue_deque_Spinlock;
567         typedef StdQueue_list<Value>                StdQueue_list_Spinlock;
568         typedef StdQueue_deque<Value, std::mutex>   StdQueue_deque_Mutex;
569         typedef StdQueue_list<Value, std::mutex>    StdQueue_list_Mutex;
570 #ifdef UNIT_LOCK_WIN_CS
571         typedef StdQueue_deque<Value, lock::win::CS>    StdQueue_deque_WinCS;
572         typedef StdQueue_list<Value, lock::win::CS>     StdQueue_list_WinCS;
573         typedef StdQueue_deque<Value, lock::win::Mutex> StdQueue_deque_WinMutex;
574         typedef StdQueue_list<Value, lock::win::Mutex>  StdQueue_list_WinMutex;
575 #endif
576
577         // SegmentedQueue
578         class traits_SegmentedQueue_spin_stat:
579             public cds::container::segmented_queue::make_traits<
580                 cds::opt::stat< cds::intrusive::segmented_queue::stat<> >
581             >::type
582         {};
583         class traits_SegmentedQueue_spin_padding:
584             public cds::container::segmented_queue::make_traits<
585                 cds::opt::padding< cds::opt::cache_line_padding >
586             >::type
587         {};
588         class traits_SegmentedQueue_mutex_stat:
589             public cds::container::segmented_queue::make_traits<
590                 cds::opt::stat< cds::intrusive::segmented_queue::stat<> >
591                 ,cds::opt::lock_type< std::mutex >
592             >::type
593         {};
594         class traits_SegmentedQueue_mutex:
595             public cds::container::segmented_queue::make_traits<
596                 cds::opt::lock_type< std::mutex >
597             >::type
598         {};
599         class traits_SegmentedQueue_mutex_padding:
600             public cds::container::segmented_queue::make_traits<
601                 cds::opt::lock_type< std::mutex >
602                 , cds::opt::padding< cds::opt::cache_line_padding >
603             >::type
604         {};
605
606         typedef cds::container::SegmentedQueue< cds::gc::HP, Value >  SegmentedQueue_HP_spin;
607         typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_spin_padding >  SegmentedQueue_HP_spin_padding;
608         typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_spin_stat >  SegmentedQueue_HP_spin_stat;
609         typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_mutex >  SegmentedQueue_HP_mutex;
610         typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_mutex_padding >  SegmentedQueue_HP_mutex_padding;
611         typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_mutex_stat >  SegmentedQueue_HP_mutex_stat;
612
613         typedef cds::container::SegmentedQueue< cds::gc::DHP, Value >  SegmentedQueue_DHP_spin;
614         typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_spin_padding >  SegmentedQueue_DHP_spin_padding;
615         typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_spin_stat >  SegmentedQueue_DHP_spin_stat;
616         typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_mutex >  SegmentedQueue_DHP_mutex;
617         typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_mutex_padding >  SegmentedQueue_DHP_mutex_padding;
618         typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_mutex_stat >  SegmentedQueue_DHP_mutex_stat;
619     };
620 }
621
622
623 // *********************************************
624 // Queue statistics
625 namespace cds_test {
626
627     template <typename Counter>
628     static inline property_stream& operator <<( property_stream& o, cds::container::fcqueue::stat<Counter> const& s )
629     {
630             return o
631                 << CDSSTRESS_STAT_OUT( s, m_nEnqueue )
632                 << CDSSTRESS_STAT_OUT( s, m_nEnqMove )
633                 << CDSSTRESS_STAT_OUT( s, m_nDequeue )
634                 << CDSSTRESS_STAT_OUT( s, m_nFailedDeq )
635                 << CDSSTRESS_STAT_OUT( s, m_nCollided )
636                 << static_cast<cds::algo::flat_combining::stat<> const&>(s);
637     }
638
639     static inline property_stream& operator <<( property_stream& o, cds::container::fcqueue::empty_stat const& /*s*/ )
640     {
641         return o;
642     }
643
644     static inline property_stream& operator <<( property_stream& o, cds::container::fcdeque::empty_stat const& /*s*/ )
645     {
646         return o;
647     }
648
649     static inline property_stream& operator <<( property_stream& o, cds::container::fcdeque::stat<> const& s )
650     {
651         return o
652             << CDSSTRESS_STAT_OUT( s, m_nPushFront )
653             << CDSSTRESS_STAT_OUT( s, m_nPushFrontMove )
654             << CDSSTRESS_STAT_OUT( s, m_nPushBack )
655             << CDSSTRESS_STAT_OUT( s, m_nPushBackMove )
656             << CDSSTRESS_STAT_OUT( s, m_nPopFront )
657             << CDSSTRESS_STAT_OUT( s, m_nFailedPopFront )
658             << CDSSTRESS_STAT_OUT( s, m_nPopBack )
659             << CDSSTRESS_STAT_OUT( s, m_nFailedPopBack )
660             << CDSSTRESS_STAT_OUT( s, m_nCollided )
661             << static_cast<cds::algo::flat_combining::stat<> const&>(s);
662     }
663
664 } // namespace cds_test
665
666 #define CDSSTRESS_Queue_F( test_fixture, type_name ) \
667     TEST_F( test_fixture, type_name ) \
668     { \
669         typedef queue::Types< value_type >::type_name queue_type; \
670         queue_type queue; \
671         test( queue ); \
672     }
673
674 #define CDSSTRESS_MSQueue( test_fixture ) \
675     CDSSTRESS_Queue_F( test_fixture, MSQueue_HP ) \
676     CDSSTRESS_Queue_F( test_fixture, MSQueue_HP_michaelAlloc ) \
677     CDSSTRESS_Queue_F( test_fixture, MSQueue_HP_seqcst ) \
678     CDSSTRESS_Queue_F( test_fixture, MSQueue_HP_ic ) \
679     CDSSTRESS_Queue_F( test_fixture, MSQueue_HP_stat ) \
680     CDSSTRESS_Queue_F( test_fixture, MSQueue_DHP ) \
681     CDSSTRESS_Queue_F( test_fixture, MSQueue_DHP_michaelAlloc ) \
682     CDSSTRESS_Queue_F( test_fixture, MSQueue_DHP_seqcst ) \
683     CDSSTRESS_Queue_F( test_fixture, MSQueue_DHP_ic ) \
684     CDSSTRESS_Queue_F( test_fixture, MSQueue_DHP_stat )
685
686 #define CDSSTRESS_MoirQueue( test_fixture ) \
687     CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP ) \
688     CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP_michaelAlloc ) \
689     CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP_seqcst ) \
690     CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP_ic ) \
691     CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP_stat ) \
692     CDSSTRESS_Queue_F( test_fixture, MoirQueue_DHP ) \
693     CDSSTRESS_Queue_F( test_fixture, MoirQueue_DHP_michaelAlloc ) \
694     CDSSTRESS_Queue_F( test_fixture, MoirQueue_DHP_seqcst ) \
695     CDSSTRESS_Queue_F( test_fixture, MoirQueue_DHP_ic ) \
696     CDSSTRESS_Queue_F( test_fixture, MoirQueue_DHP_stat )
697
698 #define CDSSTRESS_OptimsticQueue( test_fixture ) \
699     CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_HP ) \
700     CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_HP_michaelAlloc ) \
701     CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_HP_seqcst ) \
702     CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_HP_ic ) \
703     CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_HP_stat ) \
704     CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_DHP ) \
705     CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_DHP_michaelAlloc ) \
706     CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_DHP_seqcst ) \
707     CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_DHP_ic ) \
708     CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_DHP_stat )
709
710 #define CDSSTRESS_BasketQueue( test_fixture ) \
711     CDSSTRESS_Queue_F( test_fixture, BasketQueue_HP ) \
712     CDSSTRESS_Queue_F( test_fixture, BasketQueue_HP_michaelAlloc ) \
713     CDSSTRESS_Queue_F( test_fixture, BasketQueue_HP_seqcst ) \
714     CDSSTRESS_Queue_F( test_fixture, BasketQueue_HP_ic ) \
715     CDSSTRESS_Queue_F( test_fixture, BasketQueue_HP_stat ) \
716     CDSSTRESS_Queue_F( test_fixture, BasketQueue_DHP ) \
717     CDSSTRESS_Queue_F( test_fixture, BasketQueue_DHP_michaelAlloc ) \
718     CDSSTRESS_Queue_F( test_fixture, BasketQueue_DHP_seqcst ) \
719     CDSSTRESS_Queue_F( test_fixture, BasketQueue_DHP_ic ) \
720     CDSSTRESS_Queue_F( test_fixture, BasketQueue_DHP_stat )
721
722 #define CDSSTRESS_FCQueue( test_fixture ) \
723     CDSSTRESS_Queue_F( test_fixture, FCQueue_deque ) \
724     CDSSTRESS_Queue_F( test_fixture, FCQueue_deque_wait_ss ) \
725     CDSSTRESS_Queue_F( test_fixture, FCQueue_deque_wait_ss_stat ) \
726     CDSSTRESS_Queue_F( test_fixture, FCQueue_deque_wait_sm ) \
727     CDSSTRESS_Queue_F( test_fixture, FCQueue_deque_wait_sm_stat ) \
728     CDSSTRESS_Queue_F( test_fixture, FCQueue_deque_wait_mm ) \
729     CDSSTRESS_Queue_F( test_fixture, FCQueue_deque_wait_mm_stat ) \
730     CDSSTRESS_Queue_F( test_fixture, FCQueue_deque_elimination ) \
731     CDSSTRESS_Queue_F( test_fixture, FCQueue_deque_elimination_stat ) \
732     CDSSTRESS_Queue_F( test_fixture, FCQueue_list ) \
733     CDSSTRESS_Queue_F( test_fixture, FCQueue_list_wait_ss ) \
734     CDSSTRESS_Queue_F( test_fixture, FCQueue_list_wait_ss_stat ) \
735     CDSSTRESS_Queue_F( test_fixture, FCQueue_list_wait_sm ) \
736     CDSSTRESS_Queue_F( test_fixture, FCQueue_list_wait_sm_stat ) \
737     CDSSTRESS_Queue_F( test_fixture, FCQueue_list_wait_mm ) \
738     CDSSTRESS_Queue_F( test_fixture, FCQueue_list_wait_mm_stat ) \
739     CDSSTRESS_Queue_F( test_fixture, FCQueue_list_elimination ) \
740     CDSSTRESS_Queue_F( test_fixture, FCQueue_list_elimination_stat )
741
742 #define CDSSTRESS_FCDeque( test_fixture ) \
743     CDSSTRESS_Queue_F( test_fixture, FCDequeL_default ) \
744     CDSSTRESS_Queue_F( test_fixture, FCDequeL_mutex ) \
745     CDSSTRESS_Queue_F( test_fixture, FCDequeL_stat ) \
746     CDSSTRESS_Queue_F( test_fixture, FCDequeL_wait_ss ) \
747     CDSSTRESS_Queue_F( test_fixture, FCDequeL_wait_ss_stat ) \
748     CDSSTRESS_Queue_F( test_fixture, FCDequeL_wait_sm ) \
749     CDSSTRESS_Queue_F( test_fixture, FCDequeL_wait_sm_stat ) \
750     CDSSTRESS_Queue_F( test_fixture, FCDequeL_wait_mm ) \
751     CDSSTRESS_Queue_F( test_fixture, FCDequeL_wait_mm_stat ) \
752     CDSSTRESS_Queue_F( test_fixture, FCDequeL_elimination ) \
753     CDSSTRESS_Queue_F( test_fixture, FCDequeL_elimination_stat ) \
754     CDSSTRESS_Queue_F( test_fixture, FCDequeL_boost ) \
755     CDSSTRESS_Queue_F( test_fixture, FCDequeL_boost_stat ) \
756     CDSSTRESS_Queue_F( test_fixture, FCDequeL_boost_elimination ) \
757     CDSSTRESS_Queue_F( test_fixture, FCDequeL_boost_elimination_stat ) \
758     CDSSTRESS_Queue_F( test_fixture, FCDequeR_default ) \
759     CDSSTRESS_Queue_F( test_fixture, FCDequeR_mutex ) \
760     CDSSTRESS_Queue_F( test_fixture, FCDequeR_stat ) \
761     CDSSTRESS_Queue_F( test_fixture, FCDequeR_wait_ss ) \
762     CDSSTRESS_Queue_F( test_fixture, FCDequeR_wait_ss_stat ) \
763     CDSSTRESS_Queue_F( test_fixture, FCDequeR_wait_sm ) \
764     CDSSTRESS_Queue_F( test_fixture, FCDequeR_wait_sm_stat ) \
765     CDSSTRESS_Queue_F( test_fixture, FCDequeR_wait_mm ) \
766     CDSSTRESS_Queue_F( test_fixture, FCDequeR_wait_mm_stat ) \
767     CDSSTRESS_Queue_F( test_fixture, FCDequeR_elimination ) \
768     CDSSTRESS_Queue_F( test_fixture, FCDequeR_elimination_stat ) \
769     CDSSTRESS_Queue_F( test_fixture, FCDequeR_boost ) \
770     CDSSTRESS_Queue_F( test_fixture, FCDequeR_boost_stat ) \
771     CDSSTRESS_Queue_F( test_fixture, FCDequeR_boost_elimination ) \
772     CDSSTRESS_Queue_F( test_fixture, FCDequeR_boost_elimination_stat )
773
774 #define CDSSTRESS_RWQueue( test_fixture ) \
775     CDSSTRESS_Queue_F( test_fixture, RWQueue_Spin ) \
776     CDSSTRESS_Queue_F( test_fixture, RWQueue_Spin_ic ) \
777     CDSSTRESS_Queue_F( test_fixture, RWQueue_mutex )
778
779 #define CDSSTRESS_SegmentedQueue( test_fixture ) \
780     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_spin ) \
781     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_spin_padding ) \
782     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_spin_stat ) \
783     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_mutex ) \
784     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_mutex_padding ) \
785     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_mutex_stat ) \
786     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_spin ) \
787     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_spin_padding ) \
788     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_spin_stat ) \
789     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_mutex ) \
790     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_mutex_padding ) \
791     CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_mutex_stat )
792
793
794 #define CDSSTRESS_TsigasQueue( test_fixture ) \
795     CDSSTRESS_Queue_F( test_fixture, TsigasCycleQueue_dyn ) \
796     CDSSTRESS_Queue_F( test_fixture, TsigasCycleQueue_dyn_michaelAlloc ) \
797     CDSSTRESS_Queue_F( test_fixture, TsigasCycleQueue_dyn_ic )
798
799 #define CDSSTRESS_VyukovQueue( test_fixture ) \
800     CDSSTRESS_Queue_F( test_fixture, VyukovMPMCCycleQueue_dyn ) \
801     CDSSTRESS_Queue_F( test_fixture, VyukovMPMCCycleQueue_dyn_michaelAlloc ) \
802     CDSSTRESS_Queue_F( test_fixture, VyukovMPMCCycleQueue_dyn_ic )
803
804 #define CDSSTRESS_StdQueue( test_fixture ) \
805     CDSSTRESS_Queue_F( test_fixture, StdQueue_deque_Spinlock ) \
806     CDSSTRESS_Queue_F( test_fixture, StdQueue_list_Spinlock ) \
807     CDSSTRESS_Queue_F( test_fixture, StdQueue_deque_Mutex ) \
808     CDSSTRESS_Queue_F( test_fixture, StdQueue_list_Mutex )
809
810 #endif // #ifndef CDSSTRESS_QUEUE_TYPES_H