Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / fiber / scheduler.hpp
1 //          Copyright Oliver Kowalke 2013.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE_1_0.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef BOOST_FIBERS_FIBER_MANAGER_H
7 #define BOOST_FIBERS_FIBER_MANAGER_H
8
9 #include <chrono>
10 #include <functional>
11 #include <memory>
12 #include <mutex>
13 #include <vector>
14
15 #include <boost/config.hpp>
16 #if (BOOST_EXECUTION_CONTEXT==1)
17 # include <boost/context/execution_context.hpp>
18 #else
19 # include <boost/context/continuation.hpp>
20 #endif
21 #include <boost/intrusive/list.hpp>
22 #include <boost/intrusive_ptr.hpp>
23 #include <boost/intrusive/set.hpp>
24 #include <boost/intrusive/slist.hpp>
25
26 #include <boost/fiber/algo/algorithm.hpp>
27 #include <boost/fiber/context.hpp>
28 #include <boost/fiber/detail/config.hpp>
29 #include <boost/fiber/detail/data.hpp>
30 #include <boost/fiber/detail/spinlock.hpp>
31
32 #ifdef BOOST_HAS_ABI_HEADERS
33 #  include BOOST_ABI_PREFIX
34 #endif
35
36 #ifdef _MSC_VER
37 # pragma warning(push)
38 # pragma warning(disable:4251)
39 #endif
40
41 namespace boost {
42 namespace fibers {
43
44 class BOOST_FIBERS_DECL scheduler {
45 public:
46     struct timepoint_less {
47         bool operator()( context const& l, context const& r) const noexcept {
48             return l.tp_ < r.tp_;
49         }
50     };
51
52     typedef intrusive::list<
53                 context,
54                 intrusive::member_hook<
55                     context, detail::ready_hook, & context::ready_hook_ >,
56                 intrusive::constant_time_size< false >
57             >                                               ready_queue_type;
58 private:
59     typedef intrusive::multiset<
60                 context,
61                 intrusive::member_hook<
62                     context, detail::sleep_hook, & context::sleep_hook_ >,
63                 intrusive::constant_time_size< false >,
64                 intrusive::compare< timepoint_less >
65             >                                               sleep_queue_type;
66     typedef intrusive::list<
67                 context,
68                 intrusive::member_hook<
69                     context, detail::worker_hook, & context::worker_hook_ >,
70                 intrusive::constant_time_size< false >
71             >                                               worker_queue_type;
72     typedef intrusive::slist<
73                 context,
74                 intrusive::member_hook<
75                     context, detail::terminated_hook, & context::terminated_hook_ >,
76                 intrusive::linear< true >,
77                 intrusive::cache_last< true >
78             >                                               terminated_queue_type;
79     typedef intrusive::slist<
80                 context,
81                 intrusive::member_hook<
82                     context, detail::remote_ready_hook, & context::remote_ready_hook_ >,
83                 intrusive::linear< true >,
84                 intrusive::cache_last< true >
85             >                                               remote_ready_queue_type;
86
87 #if ! defined(BOOST_FIBERS_NO_ATOMICS)
88     // remote ready-queue contains context' signaled by schedulers
89     // running in other threads
90     detail::spinlock                                            remote_ready_splk_{};
91     remote_ready_queue_type                                     remote_ready_queue_{};
92 #endif
93     alignas(cache_alignment) std::unique_ptr< algo::algorithm > algo_;
94     // sleep-queue contains context' which have been called
95     // scheduler::wait_until()
96     sleep_queue_type                                            sleep_queue_{};
97     // worker-queue contains all context' mananged by this scheduler
98     // except main-context and dispatcher-context
99     // unlink happens on destruction of a context
100     worker_queue_type                                           worker_queue_{};
101     // terminated-queue contains context' which have been terminated
102     terminated_queue_type                                       terminated_queue_{};
103     intrusive_ptr< context >                                    dispatcher_ctx_{};
104     context                                                 *   main_ctx_{ nullptr };
105     bool                                                        shutdown_{ false };
106
107     void release_terminated_() noexcept;
108
109 #if ! defined(BOOST_FIBERS_NO_ATOMICS)
110     void remote_ready2ready_() noexcept;
111 #endif
112
113     void sleep2ready_() noexcept;
114
115 public:
116     scheduler() noexcept;
117
118     scheduler( scheduler const&) = delete;
119     scheduler & operator=( scheduler const&) = delete;
120
121     virtual ~scheduler();
122
123     void schedule( context *) noexcept;
124
125 #if ! defined(BOOST_FIBERS_NO_ATOMICS)
126     void schedule_from_remote( context *) noexcept;
127 #endif
128
129 #if (BOOST_EXECUTION_CONTEXT==1)
130     void dispatch() noexcept;
131
132     void terminate( detail::spinlock_lock &, context *) noexcept;
133 #else
134     boost::context::continuation dispatch() noexcept;
135
136     boost::context::continuation terminate( detail::spinlock_lock &, context *) noexcept;
137 #endif
138
139     void yield( context *) noexcept;
140
141     bool wait_until( context *,
142                      std::chrono::steady_clock::time_point const&) noexcept;
143     bool wait_until( context *,
144                      std::chrono::steady_clock::time_point const&,
145                      detail::spinlock_lock &) noexcept;
146
147     void suspend() noexcept;
148     void suspend( detail::spinlock_lock &) noexcept;
149
150     bool has_ready_fibers() const noexcept;
151
152     void set_algo( std::unique_ptr< algo::algorithm >) noexcept;
153
154     void attach_main_context( context *) noexcept;
155
156     void attach_dispatcher_context( intrusive_ptr< context >) noexcept;
157
158     void attach_worker_context( context *) noexcept;
159
160     void detach_worker_context( context *) noexcept;
161 };
162
163 }}
164
165 #ifdef _MSC_VER
166 # pragma warning(pop)
167 #endif
168
169 #ifdef BOOST_HAS_ABI_HEADERS
170 #  include BOOST_ABI_SUFFIX
171 #endif
172
173 #endif // BOOST_FIBERS_FIBER_MANAGER_H