// Copyright Oliver Kowalke 2013. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_FIBERS_FIBER_MANAGER_H #define BOOST_FIBERS_FIBER_MANAGER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX #endif #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable:4251) #endif namespace boost { namespace fibers { class BOOST_FIBERS_DECL scheduler { public: struct timepoint_less { bool operator()( context const& l, context const& r) const noexcept { return l.tp_ < r.tp_; } }; typedef intrusive::list< context, intrusive::member_hook< context, detail::ready_hook, & context::ready_hook_ >, intrusive::constant_time_size< false > > ready_queue_t; private: typedef intrusive::multiset< context, intrusive::member_hook< context, detail::sleep_hook, & context::sleep_hook_ >, intrusive::constant_time_size< false >, intrusive::compare< timepoint_less > > sleep_queue_t; typedef intrusive::list< context, intrusive::member_hook< context, detail::terminated_hook, & context::terminated_hook_ >, intrusive::constant_time_size< false > > terminated_queue_t; typedef intrusive::list< context, intrusive::member_hook< context, detail::worker_hook, & context::worker_hook_ >, intrusive::constant_time_size< false > > worker_queue_t; std::unique_ptr< algo::algorithm > algo_; context * main_ctx_{ nullptr }; intrusive_ptr< context > dispatcher_ctx_{}; // worker-queue contains all context' mananged by this scheduler // except main-context and dispatcher-context // unlink happens on destruction of a context worker_queue_t worker_queue_{}; // terminated-queue contains context' which have been terminated terminated_queue_t terminated_queue_{}; #if ! defined(BOOST_FIBERS_NO_ATOMICS) // remote ready-queue contains context' signaled by schedulers // running in other threads detail::context_mpsc_queue remote_ready_queue_{}; // sleep-queue contains context' which have been called #endif // scheduler::wait_until() sleep_queue_t sleep_queue_{}; bool shutdown_{ false }; context * get_next_() noexcept; void release_terminated_() noexcept; #if ! defined(BOOST_FIBERS_NO_ATOMICS) void remote_ready2ready_() noexcept; #endif void sleep2ready_() noexcept; public: scheduler() noexcept; scheduler( scheduler const&) = delete; scheduler & operator=( scheduler const&) = delete; virtual ~scheduler(); void set_ready( context *) noexcept; #if ! defined(BOOST_FIBERS_NO_ATOMICS) void set_remote_ready( context *) noexcept; #endif #if (BOOST_EXECUTION_CONTEXT==1) void dispatch() noexcept; void set_terminated( context *) noexcept; #else boost::context::execution_context< detail::data_t * > dispatch() noexcept; boost::context::execution_context< detail::data_t * > set_terminated( context *) noexcept; #endif void yield( context *) noexcept; bool wait_until( context *, std::chrono::steady_clock::time_point const&) noexcept; bool wait_until( context *, std::chrono::steady_clock::time_point const&, detail::spinlock_lock &) noexcept; void suspend() noexcept; void suspend( detail::spinlock_lock &) noexcept; bool has_ready_fibers() const noexcept; void set_algo( std::unique_ptr< algo::algorithm >) noexcept; void attach_main_context( context *) noexcept; void attach_dispatcher_context( intrusive_ptr< context >) noexcept; void attach_worker_context( context *) noexcept; void detach_worker_context( context *) noexcept; }; }} #ifdef _MSC_VER # pragma warning(pop) #endif #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_SUFFIX #endif #endif // BOOST_FIBERS_FIBER_MANAGER_H