Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:46:01

0001 //          Copyright Oliver Kowalke 2013.
0002 // Distributed under the Boost Software License, Version 1.0.
0003 //    (See accompanying file LICENSE_1_0.txt or copy at
0004 //          http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_FIBERS_FIBER_MANAGER_H
0007 #define BOOST_FIBERS_FIBER_MANAGER_H
0008 
0009 #include <chrono>
0010 #include <functional>
0011 #include <memory>
0012 #include <mutex>
0013 #include <vector>
0014 
0015 #include <boost/config.hpp>
0016 #include <boost/context/fiber.hpp>
0017 #include <boost/intrusive/list.hpp>
0018 #include <boost/intrusive_ptr.hpp>
0019 #include <boost/intrusive/set.hpp>
0020 #include <boost/intrusive/slist.hpp>
0021 
0022 #include <boost/fiber/algo/algorithm.hpp>
0023 #include <boost/fiber/context.hpp>
0024 #include <boost/fiber/detail/config.hpp>
0025 #include <boost/fiber/detail/data.hpp>
0026 #include <boost/fiber/detail/spinlock.hpp>
0027 
0028 #ifdef BOOST_HAS_ABI_HEADERS
0029 #  include BOOST_ABI_PREFIX
0030 #endif
0031 
0032 #ifdef _MSC_VER
0033 # pragma warning(push)
0034 # pragma warning(disable:4251)
0035 #endif
0036 
0037 namespace boost {
0038 namespace fibers {
0039 
0040 class BOOST_FIBERS_DECL scheduler {
0041 public:
0042     struct timepoint_less {
0043         bool operator()( context const& l, context const& r) const noexcept {
0044             return l.tp_ < r.tp_;
0045         }
0046     };
0047 
0048     typedef intrusive::list<
0049                 context,
0050                 intrusive::member_hook<
0051                     context, detail::ready_hook, & context::ready_hook_ >,
0052                 intrusive::constant_time_size< false >
0053             >                                               ready_queue_type;
0054 private:
0055     typedef intrusive::multiset<
0056                 context,
0057                 intrusive::member_hook<
0058                     context, detail::sleep_hook, & context::sleep_hook_ >,
0059                 intrusive::constant_time_size< false >,
0060                 intrusive::compare< timepoint_less >
0061             >                                               sleep_queue_type;
0062     typedef intrusive::list<
0063                 context,
0064                 intrusive::member_hook<
0065                     context, detail::worker_hook, & context::worker_hook_ >,
0066                 intrusive::constant_time_size< false >
0067             >                                               worker_queue_type;
0068     typedef intrusive::slist<
0069                 context,
0070                 intrusive::member_hook<
0071                     context, detail::terminated_hook, & context::terminated_hook_ >,
0072                 intrusive::linear< true >,
0073                 intrusive::cache_last< true >
0074             >                                               terminated_queue_type;
0075     typedef intrusive::slist<
0076                 context,
0077                 intrusive::member_hook<
0078                     context, detail::remote_ready_hook, & context::remote_ready_hook_ >,
0079                 intrusive::linear< true >,
0080                 intrusive::cache_last< true >
0081             >                                               remote_ready_queue_type;
0082 
0083 #if ! defined(BOOST_FIBERS_NO_ATOMICS)
0084     // remote ready-queue contains context' signaled by schedulers
0085     // running in other threads
0086     detail::spinlock                                            remote_ready_splk_{};
0087     remote_ready_queue_type                                     remote_ready_queue_{};
0088 #endif
0089     algo::algorithm::ptr_t             algo_;
0090     // sleep-queue contains context' which have been called
0091     // scheduler::wait_until()
0092     sleep_queue_type                                            sleep_queue_{};
0093     // worker-queue contains all context' managed by this scheduler
0094     // except main-context and dispatcher-context
0095     // unlink happens on destruction of a context
0096     worker_queue_type                                           worker_queue_{};
0097     // terminated-queue contains context' which have been terminated
0098     terminated_queue_type                                       terminated_queue_{};
0099     intrusive_ptr< context >                                    dispatcher_ctx_{};
0100     context                                                 *   main_ctx_{ nullptr };
0101     bool                                                        shutdown_{ false };
0102 
0103     void release_terminated_() noexcept;
0104 
0105 #if ! defined(BOOST_FIBERS_NO_ATOMICS)
0106     void remote_ready2ready_() noexcept;
0107 #endif
0108 
0109     void sleep2ready_() noexcept;
0110 
0111 public:
0112     scheduler(algo::algorithm::ptr_t algo) noexcept;
0113 
0114     scheduler( scheduler const&) = delete;
0115     scheduler & operator=( scheduler const&) = delete;
0116 
0117     virtual ~scheduler();
0118 
0119     void schedule( context *) noexcept;
0120 
0121 #if ! defined(BOOST_FIBERS_NO_ATOMICS)
0122     void schedule_from_remote( context *) noexcept;
0123 #endif
0124 
0125     boost::context::fiber dispatch() noexcept;
0126 
0127     boost::context::fiber terminate( detail::spinlock_lock &, context *) noexcept;
0128 
0129     void yield( context *) noexcept;
0130 
0131     bool wait_until( context *,
0132                      std::chrono::steady_clock::time_point const&) noexcept;
0133 
0134     bool wait_until( context *,
0135                      std::chrono::steady_clock::time_point const&,
0136                      detail::spinlock_lock &,
0137                      waker &&) noexcept;
0138 
0139     void suspend() noexcept;
0140     void suspend( detail::spinlock_lock &) noexcept;
0141 
0142     bool has_ready_fibers() const noexcept;
0143 
0144     void set_algo( algo::algorithm::ptr_t) noexcept;
0145 
0146     void attach_main_context( context *) noexcept;
0147 
0148     void attach_dispatcher_context( intrusive_ptr< context >) noexcept;
0149 
0150     void attach_worker_context( context *) noexcept;
0151 
0152     void detach_worker_context( context *) noexcept;
0153 };
0154 
0155 }}
0156 
0157 #ifdef _MSC_VER
0158 # pragma warning(pop)
0159 #endif
0160 
0161 #ifdef BOOST_HAS_ABI_HEADERS
0162 #  include BOOST_ABI_SUFFIX
0163 #endif
0164 
0165 #endif // BOOST_FIBERS_FIBER_MANAGER_H