]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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> | |
11fdf7f2 | 16 | #include <boost/context/fiber.hpp> |
7c673cae FG |
17 | #include <boost/intrusive/list.hpp> |
18 | #include <boost/intrusive_ptr.hpp> | |
19 | #include <boost/intrusive/set.hpp> | |
b32b8144 | 20 | #include <boost/intrusive/slist.hpp> |
7c673cae FG |
21 | |
22 | #include <boost/fiber/algo/algorithm.hpp> | |
23 | #include <boost/fiber/context.hpp> | |
24 | #include <boost/fiber/detail/config.hpp> | |
25 | #include <boost/fiber/detail/data.hpp> | |
26 | #include <boost/fiber/detail/spinlock.hpp> | |
27 | ||
28 | #ifdef BOOST_HAS_ABI_HEADERS | |
29 | # include BOOST_ABI_PREFIX | |
30 | #endif | |
31 | ||
32 | #ifdef _MSC_VER | |
33 | # pragma warning(push) | |
34 | # pragma warning(disable:4251) | |
35 | #endif | |
36 | ||
37 | namespace boost { | |
38 | namespace fibers { | |
39 | ||
40 | class BOOST_FIBERS_DECL scheduler { | |
41 | public: | |
42 | struct timepoint_less { | |
43 | bool operator()( context const& l, context const& r) const noexcept { | |
44 | return l.tp_ < r.tp_; | |
45 | } | |
46 | }; | |
47 | ||
48 | typedef intrusive::list< | |
49 | context, | |
50 | intrusive::member_hook< | |
51 | context, detail::ready_hook, & context::ready_hook_ >, | |
b32b8144 FG |
52 | intrusive::constant_time_size< false > |
53 | > ready_queue_type; | |
7c673cae | 54 | private: |
b32b8144 | 55 | typedef intrusive::multiset< |
7c673cae FG |
56 | context, |
57 | intrusive::member_hook< | |
58 | context, detail::sleep_hook, & context::sleep_hook_ >, | |
59 | intrusive::constant_time_size< false >, | |
b32b8144 FG |
60 | intrusive::compare< timepoint_less > |
61 | > sleep_queue_type; | |
7c673cae | 62 | typedef intrusive::list< |
b32b8144 FG |
63 | context, |
64 | intrusive::member_hook< | |
65 | context, detail::worker_hook, & context::worker_hook_ >, | |
66 | intrusive::constant_time_size< false > | |
67 | > worker_queue_type; | |
68 | typedef intrusive::slist< | |
7c673cae FG |
69 | context, |
70 | intrusive::member_hook< | |
71 | context, detail::terminated_hook, & context::terminated_hook_ >, | |
b32b8144 FG |
72 | intrusive::linear< true >, |
73 | intrusive::cache_last< true > | |
74 | > terminated_queue_type; | |
75 | typedef intrusive::slist< | |
7c673cae FG |
76 | context, |
77 | intrusive::member_hook< | |
b32b8144 FG |
78 | context, detail::remote_ready_hook, & context::remote_ready_hook_ >, |
79 | intrusive::linear< true >, | |
80 | intrusive::cache_last< true > | |
81 | > remote_ready_queue_type; | |
7c673cae | 82 | |
b32b8144 FG |
83 | #if ! defined(BOOST_FIBERS_NO_ATOMICS) |
84 | // remote ready-queue contains context' signaled by schedulers | |
85 | // running in other threads | |
86 | detail::spinlock remote_ready_splk_{}; | |
87 | remote_ready_queue_type remote_ready_queue_{}; | |
88 | #endif | |
89 | algo::algorithm::ptr_t algo_; | |
90 | // sleep-queue contains context' which have been called | |
91 | // scheduler::wait_until() | |
92 | sleep_queue_type sleep_queue_{}; | |
7c673cae FG |
93 | // worker-queue contains all context' mananged by this scheduler |
94 | // except main-context and dispatcher-context | |
95 | // unlink happens on destruction of a context | |
b32b8144 | 96 | worker_queue_type worker_queue_{}; |
7c673cae | 97 | // terminated-queue contains context' which have been terminated |
b32b8144 FG |
98 | terminated_queue_type terminated_queue_{}; |
99 | intrusive_ptr< context > dispatcher_ctx_{}; | |
100 | context * main_ctx_{ nullptr }; | |
101 | bool shutdown_{ false }; | |
7c673cae FG |
102 | |
103 | void release_terminated_() noexcept; | |
104 | ||
b32b8144 | 105 | #if ! defined(BOOST_FIBERS_NO_ATOMICS) |
7c673cae | 106 | void remote_ready2ready_() noexcept; |
b32b8144 | 107 | #endif |
7c673cae FG |
108 | |
109 | void sleep2ready_() noexcept; | |
110 | ||
111 | public: | |
112 | scheduler() noexcept; | |
113 | ||
114 | scheduler( scheduler const&) = delete; | |
115 | scheduler & operator=( scheduler const&) = delete; | |
116 | ||
117 | virtual ~scheduler(); | |
118 | ||
b32b8144 | 119 | void schedule( context *) noexcept; |
7c673cae | 120 | |
b32b8144 FG |
121 | #if ! defined(BOOST_FIBERS_NO_ATOMICS) |
122 | void schedule_from_remote( context *) noexcept; | |
123 | #endif | |
7c673cae | 124 | |
11fdf7f2 | 125 | boost::context::fiber dispatch() noexcept; |
7c673cae | 126 | |
11fdf7f2 | 127 | boost::context::fiber terminate( detail::spinlock_lock &, context *) noexcept; |
7c673cae FG |
128 | |
129 | void yield( context *) noexcept; | |
130 | ||
131 | bool wait_until( context *, | |
132 | std::chrono::steady_clock::time_point const&) noexcept; | |
20effc67 | 133 | |
7c673cae FG |
134 | bool wait_until( context *, |
135 | std::chrono::steady_clock::time_point const&, | |
20effc67 TL |
136 | detail::spinlock_lock &, |
137 | waker &&) noexcept; | |
7c673cae FG |
138 | |
139 | void suspend() noexcept; | |
140 | void suspend( detail::spinlock_lock &) noexcept; | |
141 | ||
142 | bool has_ready_fibers() const noexcept; | |
143 | ||
b32b8144 | 144 | void set_algo( algo::algorithm::ptr_t) noexcept; |
7c673cae FG |
145 | |
146 | void attach_main_context( context *) noexcept; | |
147 | ||
148 | void attach_dispatcher_context( intrusive_ptr< context >) noexcept; | |
149 | ||
150 | void attach_worker_context( context *) noexcept; | |
151 | ||
152 | void detach_worker_context( context *) noexcept; | |
153 | }; | |
154 | ||
155 | }} | |
156 | ||
157 | #ifdef _MSC_VER | |
158 | # pragma warning(pop) | |
159 | #endif | |
160 | ||
161 | #ifdef BOOST_HAS_ABI_HEADERS | |
162 | # include BOOST_ABI_SUFFIX | |
163 | #endif | |
164 | ||
165 | #endif // BOOST_FIBERS_FIBER_MANAGER_H |