• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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