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)
6 #ifndef BOOST_FIBERS_FIBER_MANAGER_H
7 #define BOOST_FIBERS_FIBER_MANAGER_H
15 #include <boost/config.hpp>
16 #if (BOOST_EXECUTION_CONTEXT==1)
17 # include <boost/context/execution_context.hpp>
19 # include <boost/context/continuation.hpp>
21 #include <boost/intrusive/list.hpp>
22 #include <boost/intrusive_ptr.hpp>
23 #include <boost/intrusive/set.hpp>
24 #include <boost/intrusive/slist.hpp>
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>
32 #ifdef BOOST_HAS_ABI_HEADERS
33 # include BOOST_ABI_PREFIX
37 # pragma warning(push)
38 # pragma warning(disable:4251)
44 class BOOST_FIBERS_DECL scheduler {
46 struct timepoint_less {
47 bool operator()( context const& l, context const& r) const noexcept {
52 typedef intrusive::list<
54 intrusive::member_hook<
55 context, detail::ready_hook, & context::ready_hook_ >,
56 intrusive::constant_time_size< false >
59 typedef intrusive::multiset<
61 intrusive::member_hook<
62 context, detail::sleep_hook, & context::sleep_hook_ >,
63 intrusive::constant_time_size< false >,
64 intrusive::compare< timepoint_less >
66 typedef intrusive::list<
68 intrusive::member_hook<
69 context, detail::worker_hook, & context::worker_hook_ >,
70 intrusive::constant_time_size< false >
72 typedef intrusive::slist<
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<
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;
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_{};
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 };
107 void release_terminated_() noexcept;
109 #if ! defined(BOOST_FIBERS_NO_ATOMICS)
110 void remote_ready2ready_() noexcept;
113 void sleep2ready_() noexcept;
116 scheduler() noexcept;
118 scheduler( scheduler const&) = delete;
119 scheduler & operator=( scheduler const&) = delete;
121 virtual ~scheduler();
123 void schedule( context *) noexcept;
125 #if ! defined(BOOST_FIBERS_NO_ATOMICS)
126 void schedule_from_remote( context *) noexcept;
129 #if (BOOST_EXECUTION_CONTEXT==1)
130 void dispatch() noexcept;
132 void terminate( detail::spinlock_lock &, context *) noexcept;
134 boost::context::continuation dispatch() noexcept;
136 boost::context::continuation terminate( detail::spinlock_lock &, context *) noexcept;
139 void yield( context *) noexcept;
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;
147 void suspend() noexcept;
148 void suspend( detail::spinlock_lock &) noexcept;
150 bool has_ready_fibers() const noexcept;
152 void set_algo( std::unique_ptr< algo::algorithm >) noexcept;
154 void attach_main_context( context *) noexcept;
156 void attach_dispatcher_context( intrusive_ptr< context >) noexcept;
158 void attach_worker_context( context *) noexcept;
160 void detach_worker_context( context *) noexcept;
166 # pragma warning(pop)
169 #ifdef BOOST_HAS_ABI_HEADERS
170 # include BOOST_ABI_SUFFIX
173 #endif // BOOST_FIBERS_FIBER_MANAGER_H