scheduler.hpp 5.5 KB

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