• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
6 #ifndef BOOST_THIS_FIBER_OPERATIONS_H
7 #define BOOST_THIS_FIBER_OPERATIONS_H
8 
9 #include <chrono>
10 
11 #include <boost/config.hpp>
12 
13 #include <boost/fiber/algo/algorithm.hpp>
14 #include <boost/fiber/context.hpp>
15 #include <boost/fiber/detail/config.hpp>
16 #include <boost/fiber/detail/convert.hpp>
17 #include <boost/fiber/fiber.hpp>
18 #include <boost/fiber/scheduler.hpp>
19 
20 #ifdef BOOST_HAS_ABI_HEADERS
21 #  include BOOST_ABI_PREFIX
22 #endif
23 
24 namespace boost {
25 namespace this_fiber {
26 
27 inline
get_id()28 fibers::fiber::id get_id() noexcept {
29     return fibers::context::active()->get_id();
30 }
31 
32 inline
yield()33 void yield() noexcept {
34     fibers::context::active()->yield();
35 }
36 
37 template< typename Clock, typename Duration >
sleep_until(std::chrono::time_point<Clock,Duration> const & sleep_time_)38 void sleep_until( std::chrono::time_point< Clock, Duration > const& sleep_time_) {
39     std::chrono::steady_clock::time_point sleep_time = boost::fibers::detail::convert( sleep_time_);
40     fibers::context * active_ctx = fibers::context::active();
41     active_ctx->twstatus.store( static_cast< std::intptr_t >( 0), std::memory_order_release);
42     active_ctx->wait_until( sleep_time);
43 }
44 
45 template< typename Rep, typename Period >
sleep_for(std::chrono::duration<Rep,Period> const & timeout_duration)46 void sleep_for( std::chrono::duration< Rep, Period > const& timeout_duration) {
47     fibers::context * active_ctx = fibers::context::active();
48     active_ctx->twstatus.store( static_cast< std::intptr_t >( 0), std::memory_order_release);
49     active_ctx->wait_until( std::chrono::steady_clock::now() + timeout_duration);
50 }
51 
52 template< typename PROPS >
properties()53 PROPS & properties() {
54     fibers::fiber_properties * props = fibers::context::active()->get_properties();
55     if ( BOOST_LIKELY( nullptr == props) ) {
56         // props could be nullptr if the thread's main fiber has not yet
57         // yielded (not yet passed through algorithm_with_properties::
58         // awakened()). Address that by yielding right now.
59         yield();
60         // Try again to obtain the fiber_properties subclass instance ptr.
61         // Walk through the whole chain again because who knows WHAT might
62         // have happened while we were yielding!
63         props = fibers::context::active()->get_properties();
64         // Could still be hosed if the running manager isn't a subclass of
65         // algorithm_with_properties.
66         BOOST_ASSERT_MSG( props, "this_fiber::properties not set");
67     }
68     return dynamic_cast< PROPS & >( * props );
69 }
70 
71 }
72 
73 namespace fibers {
74 
75 inline
has_ready_fibers()76 bool has_ready_fibers() noexcept {
77     return boost::fibers::context::active()->get_scheduler()->has_ready_fibers();
78 }
79 
80 template< typename SchedAlgo, typename ... Args >
use_scheduling_algorithm(Args &&...args)81 void use_scheduling_algorithm( Args && ... args) noexcept {
82     boost::fibers::context::active()->get_scheduler()
83         ->set_algo( new SchedAlgo( std::forward< Args >( args) ... ) );
84 }
85 
86 }}
87 
88 #ifdef BOOST_HAS_ABI_HEADERS
89 #  include BOOST_ABI_SUFFIX
90 #endif
91 
92 #endif // BOOST_THIS_FIBER_OPERATIONS_H
93