2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-17 13:42:21 +00:00

support sleep_for()/sleep_until()

This commit is contained in:
Oliver Kowalke
2015-09-19 08:59:53 +02:00
parent 8d41c994af
commit 6da902ff09
7 changed files with 241 additions and 13 deletions

View File

@@ -8,6 +8,7 @@
#define BOOST_FIBERS_CONTEXT_H
#include <atomic>
#include <chrono>
#include <boost/assert.hpp>
#include <boost/config.hpp>
@@ -16,6 +17,7 @@
#include <boost/context/stack_context.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/parent_from_member.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/fiber/detail/config.hpp>
@@ -67,6 +69,14 @@ typedef intrusive::list_member_hook<
>
> ready_hook;
struct sleep_tag;
typedef intrusive::set_member_hook<
intrusive::tag< sleep_tag >,
intrusive::link_mode<
intrusive::auto_unlink
>
> sleep_hook;
struct terminated_tag;
typedef intrusive::list_member_hook<
intrusive::tag< terminated_tag >,
@@ -88,9 +98,11 @@ constexpr worker_context_t worker_context = worker_context_t();
class BOOST_FIBERS_DECL context {
public:
detail::ready_hook ready_hook_;
detail::terminated_hook terminated_hook_;
detail::wait_hook wait_hook_;
detail::ready_hook ready_hook_;
detail::sleep_hook sleep_hook_;
detail::terminated_hook terminated_hook_;
detail::wait_hook wait_hook_;
std::chrono::steady_clock::time_point tp_;
typedef intrusive::list<
context,
@@ -202,6 +214,7 @@ public:
ready_hook_(),
terminated_hook_(),
wait_hook_(),
tp_( (std::chrono::steady_clock::time_point::max)() ),
use_count_( 1), // fiber instance or scheduler owner
flags_( flag_worker_context),
scheduler_( nullptr),
@@ -238,6 +251,8 @@ public:
void yield() noexcept;
bool wait_until( std::chrono::steady_clock::time_point const&);
bool is_main_context() const noexcept {
return 0 != ( flags_ & flag_main_context);
}
@@ -258,6 +273,8 @@ public:
bool ready_is_linked();
bool sleep_is_linked();
void wait_unlink();
friend void intrusive_ptr_add_ref( context * ctx) {

View File

@@ -0,0 +1,42 @@
// 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_DETAIL_CONVERT_H
#define BOOST_FIBERS_DETAIL_CONVERT_H
#include <chrono>
#include <boost/config.hpp>
#include <boost/fiber/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
namespace detail {
inline
std::chrono::steady_clock::time_point convert(
std::chrono::steady_clock::time_point const& timeout_time) noexcept {
return timeout_time;
}
template< typename Clock, typename Duration >
std::chrono::steady_clock::time_point convert(
std::chrono::time_point< Clock, Duration > const& timeout_time) {
return std::chrono::steady_clock::now() + ( timeout_time - Clock::now() );
}
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_CONVERT_H

View File

@@ -6,10 +6,13 @@
#ifndef BOOST_THIS_FIBER_OPERATIONS_H
#define BOOST_THIS_FIBER_OPERATIONS_H
#include <chrono>
#include <boost/config.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/context.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/detail/convert.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -28,6 +31,23 @@ void yield() noexcept {
fibers::context::active()->yield();
}
template< typename Clock, typename Duration >
void sleep_until( std::chrono::time_point< Clock, Duration > const& sleep_time_) {
std::chrono::steady_clock::time_point sleep_time(
boost::fibers::detail::convert( sleep_time_) );
fibers::context::active()->wait_until( sleep_time);
// TODO: check if fiber was interrupted
//interruption_point();
}
template< typename Rep, typename Period >
void sleep_for( std::chrono::duration< Rep, Period > const& timeout_duration) {
fibers::context::active()->wait_until(
std::chrono::steady_clock::now() + timeout_duration);
// TODO: check if fiber was interrupted
//interruption_point();
}
}}
#ifdef BOOST_HAS_ABI_HEADERS

View File

@@ -6,9 +6,12 @@
#ifndef BOOST_FIBERS_FIBER_MANAGER_H
#define BOOST_FIBERS_FIBER_MANAGER_H
#include <chrono>
#include <boost/config.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/fiber/context.hpp>
#include <boost/fiber/detail/autoreset_event.hpp>
@@ -23,20 +26,35 @@ namespace fibers {
class BOOST_FIBERS_DECL scheduler {
private:
struct timepoint_less {
bool operator()( context const& l, context const& r) {
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;
typedef intrusive::set<
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_ >,
context,
detail::terminated_hook,
& context::terminated_hook_ >,
intrusive::constant_time_size< false > > terminated_queue_t;
context * main_ctx_;
intrusive_ptr< context > dispatcher_ctx_;
ready_queue_t ready_queue_;
sleep_queue_t sleep_queue_;
terminated_queue_t terminated_queue_;
bool shutdown_;
detail::autoreset_event ready_queue_ev_;
@@ -47,6 +65,8 @@ private:
void release_terminated_();
void woken_up_() noexcept;
public:
scheduler() noexcept;
@@ -67,6 +87,8 @@ public:
void yield( context *) noexcept;
bool wait_until( context *, std::chrono::steady_clock::time_point const&);
void re_schedule( context *) noexcept;
};