Added sync::Monitor concept
[libcds.git] / cds / sync / monitor.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_SYNC_MONITOR_H
4 #define CDSLIB_SYNC_MONITOR_H
5
6 namespace cds { namespace sync {
7
8     /**
9         @page cds_sync_monitor Synchronization monitor
10
11         A <a href="http://en.wikipedia.org/wiki/Monitor_%28synchronization%29">monitor</a> is synchronization construct
12         that allows threads to have both mutual exclusion and the ability to wait (block) for a certain condition to become true.
13
14         Some blocking data structure algoritms like the trees require per-node locking.
15         For huge trees containing millions of nodes it can be very inefficient to inject
16         the lock object into each node. Moreover, some operating systems may not support
17         the millions of system objects like mutexes per user process.
18
19         The monitor strategy is intended to solve that problem.
20         When the node should be locked, the monitor is called to allocate appropriate
21         lock object for the node if it's needed, and to lock the node.
22         The monitor strategy can significantly reduce the number of system objects
23         required for the data structure.
24
25         <b>Implemetatios</b>
26
27         \p libcds contains several monitor implementations:
28         - \p sync::injected_monitor injects the lock object into each node.
29             That mock monitor is designed for user-space locking primitive like
30             \ref sync::spin_lock "spin-lock".
31
32         <b>How to use</b>
33
34         If you use a container from \p libcds that requires a monitor, you should just
35         specify required monitor type in container's traits. Usually, the monitor 
36         is specified by \p traits::sync_monitor typedef, or by \p cds::opt::sync_monitor
37         option for container's \p make_traits metafunction.
38
39         If you're developing a new container algorithm, you should know internal monitor 
40         interface:
41         \code
42         class Monitor {
43         public:
44             // Monitor's injection into the Node class
45             template <typename Node>
46             struct wrapper;
47
48             // Locks the node 
49             template <typename Node>
50             void lock( Node& node );
51
52             // Unlocks the node
53             template <typename Node>
54             void unlock( Node& node );
55
56             // Scoped lock applyes RAII to Monitor
57             template <typename Node>
58             class scoped_lock 
59             {
60             public:
61                 // Locks node by monitor mon
62                 scoped_lock( Monitor& mon, Node& node );
63
64                 // Unlocks the node locked by ctor
65                 ~scoped_lock();
66             };
67         };
68         \endcode
69         The monitor should be a member of your container:
70         \code
71         template <typename GC, typename T, typename Traits>
72         class my_container {
73             // ...
74             typedef typename Traits::sync_monitor   sync_monitor;
75             sync_monitor m_Monitor;
76             //...
77         };
78         \endcode
79     */
80
81 }} // namespace cds::sync
82
83 #endif // #ifndef CDSLIB_SYNC_MONITOR_H
84