1ea7dac484418f74f7b99a5279c59aedf723aa2d
[libcds.git] / cds / algo / elimination.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 CDSLIB_ALGO_ELIMINATION_H
32 #define CDSLIB_ALGO_ELIMINATION_H
33
34 #include <cds/algo/elimination_tls.h>
35 #include <cds/algo/elimination_opt.h>
36 #include <cds/algo/atomic.h>
37 #include <cds/threading/model.h>
38
39 namespace cds { namespace algo {
40
41     /// Elimination technique
42     /** @anchor cds_elimination_description
43         Elimination technique allows highly distributed coupling and execution of operations with reverse
44         semantics like the pushes and pops on a stack. If a push followed by a pop are performed
45         on a stack, the data structure's state does not change (similarly for a pop followed by a push).
46         This means that if one can cause pairs of pushes and pops to meet and pair up in
47         separate locations, the threads can exchange values without having to touch a centralized structure
48         since they have anyhow "eliminated" each other's effect on it. Elimination can be implemented
49         by using a collision array in which threads pick random locations in order to try and collide.
50         Pairs of threads that "collide" in some location run through a synchronization protocol,
51         and all such disjoint collisions can be performed in parallel. If a thread has not met another
52         in the selected location or if it met a thread with an operation that cannot be eliminated
53         (such as two push operations), an alternative scheme must be used.
54     */
55     namespace elimination {
56
57         /// Base class describing an operation for eliminating
58         /**
59             This class contains some debugng info.
60             Actual operation descriptor depends on real container and its interface.
61         */
62         struct operation_desc
63         {
64             record * pOwner;    ///< Owner of the descriptor
65         };
66
67         /// Acquires elimination record for the current thread
68         template <typename OperationDesc>
69         static inline record * init_record( OperationDesc& op )
70         {
71             record& rec = cds::threading::elimination_record();
72             assert( rec.is_free());
73             op.pOwner = &rec;
74             rec.pOp = static_cast<operation_desc *>( &op );
75             return &rec;
76         }
77
78         /// Releases elimination record for the current thread
79         static inline void clear_record()
80         {
81             cds::threading::elimination_record().pOp = nullptr;
82         }
83     } // namespace elimination
84 }} // namespace cds::algo
85
86 #endif // CDSLIB_ALGO_ELIMINATION_H