1 2 // Copyright Oliver Kowalke 2015. 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 // 7 8 #ifndef BOOST_FIBERS_ALGO_WORK_STEALING_H 9 #define BOOST_FIBERS_ALGO_WORK_STEALING_H 10 11 #include <atomic> 12 #include <condition_variable> 13 #include <chrono> 14 #include <cstddef> 15 #include <cstdint> 16 #include <mutex> 17 #include <vector> 18 19 #include <boost/config.hpp> 20 #include <boost/intrusive_ptr.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/context_spinlock_queue.hpp> 26 #include <boost/fiber/detail/context_spmc_queue.hpp> 27 #include <boost/fiber/scheduler.hpp> 28 29 #ifdef BOOST_HAS_ABI_HEADERS 30 # include BOOST_ABI_PREFIX 31 #endif 32 33 namespace boost { 34 namespace fibers { 35 namespace algo { 36 37 class BOOST_FIBERS_DECL work_stealing : public algorithm { 38 private: 39 static std::atomic< std::uint32_t > counter_; 40 static std::vector< intrusive_ptr< work_stealing > > schedulers_; 41 42 std::uint32_t id_; 43 std::uint32_t thread_count_; 44 #ifdef BOOST_FIBERS_USE_SPMC_QUEUE 45 detail::context_spmc_queue rqueue_{}; 46 #else 47 detail::context_spinlock_queue rqueue_{}; 48 #endif 49 std::mutex mtx_{}; 50 std::condition_variable cnd_{}; 51 bool flag_{ false }; 52 bool suspend_; 53 54 static void init_( std::uint32_t, std::vector< intrusive_ptr< work_stealing > > &); 55 56 public: 57 work_stealing( std::uint32_t, bool = false); 58 59 work_stealing( work_stealing const&) = delete; 60 work_stealing( work_stealing &&) = delete; 61 62 work_stealing & operator=( work_stealing const&) = delete; 63 work_stealing & operator=( work_stealing &&) = delete; 64 65 void awakened( context *) noexcept override; 66 67 context * pick_next() noexcept override; 68 steal()69 virtual context * steal() noexcept { 70 return rqueue_.steal(); 71 } 72 has_ready_fibers() const73 bool has_ready_fibers() const noexcept override { 74 return ! rqueue_.empty(); 75 } 76 77 void suspend_until( std::chrono::steady_clock::time_point const&) noexcept override; 78 79 void notify() noexcept override; 80 }; 81 82 }}} 83 84 #ifdef BOOST_HAS_ABI_HEADERS 85 # include BOOST_ABI_SUFFIX 86 #endif 87 88 #endif // BOOST_FIBERS_ALGO_WORK_STEALING_H 89