• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <boost/context/fiber.hpp>
17 #include <boost/intrusive/list.hpp>
18 #include <boost/intrusive_ptr.hpp>
19 #include <boost/intrusive/set.hpp>
20 #include <boost/intrusive/slist.hpp>
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 {
operator ()boost::fibers::scheduler::timepoint_less43         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_ >,
52                 intrusive::constant_time_size< false >
53             >                                               ready_queue_type;
54 private:
55     typedef intrusive::multiset<
56                 context,
57                 intrusive::member_hook<
58                     context, detail::sleep_hook, & context::sleep_hook_ >,
59                 intrusive::constant_time_size< false >,
60                 intrusive::compare< timepoint_less >
61             >                                               sleep_queue_type;
62     typedef intrusive::list<
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<
69                 context,
70                 intrusive::member_hook<
71                     context, detail::terminated_hook, & context::terminated_hook_ >,
72                 intrusive::linear< true >,
73                 intrusive::cache_last< true >
74             >                                               terminated_queue_type;
75     typedef intrusive::slist<
76                 context,
77                 intrusive::member_hook<
78                     context, detail::remote_ready_hook, & context::remote_ready_hook_ >,
79                 intrusive::linear< true >,
80                 intrusive::cache_last< true >
81             >                                               remote_ready_queue_type;
82 
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_{};
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
96     worker_queue_type                                           worker_queue_{};
97     // terminated-queue contains context' which have been terminated
98     terminated_queue_type                                       terminated_queue_{};
99     intrusive_ptr< context >                                    dispatcher_ctx_{};
100     context                                                 *   main_ctx_{ nullptr };
101     bool                                                        shutdown_{ false };
102 
103     void release_terminated_() noexcept;
104 
105 #if ! defined(BOOST_FIBERS_NO_ATOMICS)
106     void remote_ready2ready_() noexcept;
107 #endif
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 
119     void schedule( context *) noexcept;
120 
121 #if ! defined(BOOST_FIBERS_NO_ATOMICS)
122     void schedule_from_remote( context *) noexcept;
123 #endif
124 
125     boost::context::fiber dispatch() noexcept;
126 
127     boost::context::fiber terminate( detail::spinlock_lock &, context *) noexcept;
128 
129     void yield( context *) noexcept;
130 
131     bool wait_until( context *,
132                      std::chrono::steady_clock::time_point const&) noexcept;
133     bool wait_until( context *,
134                      std::chrono::steady_clock::time_point const&,
135                      detail::spinlock_lock &) noexcept;
136 
137     void suspend() noexcept;
138     void suspend( detail::spinlock_lock &) noexcept;
139 
140     bool has_ready_fibers() const noexcept;
141 
142     void set_algo( algo::algorithm::ptr_t) noexcept;
143 
144     void attach_main_context( context *) noexcept;
145 
146     void attach_dispatcher_context( intrusive_ptr< context >) noexcept;
147 
148     void attach_worker_context( context *) noexcept;
149 
150     void detach_worker_context( context *) noexcept;
151 };
152 
153 }}
154 
155 #ifdef _MSC_VER
156 # pragma warning(pop)
157 #endif
158 
159 #ifdef BOOST_HAS_ABI_HEADERS
160 #  include BOOST_ABI_SUFFIX
161 #endif
162 
163 #endif // BOOST_FIBERS_FIBER_MANAGER_H
164