diff --git a/examples/priority.cpp b/examples/priority.cpp index 1de01975..64ef60a4 100644 --- a/examples/priority.cpp +++ b/examples/priority.cpp @@ -13,7 +13,7 @@ class priority_props: public boost::fibers::fiber_properties public: priority_props(boost::fibers::fiber_properties::back_ptr p): fiber_properties(p), - priority_(0) + priority_(nullptr) {} int get_priority() const { return priority_; } @@ -48,16 +48,16 @@ private: // Much as we would like, we don't use std::priority_queue because it // doesn't appear to provide any way to alter the priority (and hence // queue position) of a particular item. - boost::fibers::fiber_base* head_; + boost::fibers::fiber_context* head_; public: priority_scheduler(): - head_(0) + head_(nullptr) {} // For a subclass of sched_algorithm_with_properties<>, it's important to // override awakened_props(), NOT awakened(). - virtual void awakened_props(boost::fibers::fiber_base* f) + virtual void awakened_props(boost::fibers::fiber_context* f) { int f_priority = properties(f).get_priority(); // With this scheduler, fibers with higher priority values are @@ -66,35 +66,35 @@ public: // we're handed a new fiber_base, put it at the end of the fibers with // that same priority. In other words: search for the first fiber in // the queue with LOWER priority, and insert before that one. - boost::fibers::fiber_base** fp = &head_; - for ( ; *fp; fp = &(*fp)->nxt_) + boost::fibers::fiber_context** fp = &head_; + for ( ; *fp; fp = &(*fp)->nxt) if (properties(*fp).get_priority() < f_priority) break; // It doesn't matter whether we hit the end of the list or found // another fiber with lower priority. Either way, insert f here. - f->nxt_ = *fp; + f->nxt = *fp; *fp = f; std::cout << "awakened(" << properties(f).name << "): "; describe_ready_queue(); } - virtual boost::fibers::fiber_base* pick_next() + virtual boost::fibers::fiber_context* pick_next() { // if ready queue is empty, just tell caller if (! head_) - return 0; + return nullptr; // Here we have at least one ready fiber. Unlink and return that. - boost::fibers::fiber_base* f = head_; - head_ = f->nxt_; - f->nxt_ = 0; + boost::fibers::fiber_context* f = head_; + head_ = f->nxt; + f->nxt = nullptr; std::cout << "pick_next() resuming " << properties(f).name << ": "; describe_ready_queue(); return f; } - virtual void property_change(boost::fibers::fiber_base* f, priority_props& props) + virtual void property_change(boost::fibers::fiber_context* f, priority_props& props) { // Although our priority_props class defines multiple properties, only // one of them (priority) actually calls notify() when changed. The @@ -107,15 +107,15 @@ public: // over the queue to find both the existing item and the new desired // insertion point. bool found = false; - boost::fibers::fiber_base **insert = 0, **fp = &head_; - for ( ; *fp; fp = &(*fp)->nxt_) + boost::fibers::fiber_context **insert = nullptr, **fp = &head_; + for ( ; *fp; fp = &(*fp)->nxt) { if (*fp == f) { // found the passed fiber in our list -- unlink it found = true; - *fp = (*fp)->nxt_; - f->nxt_ = 0; + *fp = (*fp)->nxt; + f->nxt = nullptr; // If that was the last item in the list, stop. if (! *fp) break; @@ -161,7 +161,7 @@ public: where = "to end"; } // Insert f at the new insertion point in the queue. - f->nxt_ = *insert; + f->nxt = *insert; *insert = f; std::cout << "moving " << where << ": "; @@ -175,7 +175,7 @@ public: else { const char* delim = ""; - for (boost::fibers::fiber_base *f = head_; f; f = f->nxt_) + for (boost::fibers::fiber_context *f = head_; f; f = f->nxt) { priority_props& props(properties(f)); std::cout << delim << props.name << '(' << props.get_priority() << ')'; diff --git a/include/boost/fiber/fiber.hpp b/include/boost/fiber/fiber.hpp index c731bc3f..34f94df6 100644 --- a/include/boost/fiber/fiber.hpp +++ b/include/boost/fiber/fiber.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX @@ -27,11 +28,6 @@ namespace boost { namespace fibers { -namespace detail { - -struct scheduler; - -} class fiber_context; @@ -51,7 +47,7 @@ private: // reserve space for control structure std::size_t size = sctx.size - sizeof( fiber_context); void * sp = static_cast< char * >( sctx.sp) - sizeof( fiber_context); - // placement new of worker_fiber on top of fiber's stack + // placement new of fiber_context on top of fiber's stack return ptr_t( new ( sp) fiber_context( context::preallocated( sp, size, sctx), salloc, std::forward< Fn >( fn), std::forward< Args >( args) ... ) ); @@ -120,14 +116,10 @@ public: return impl_ ? impl_->get_id() : id(); } - bool thread_affinity() const noexcept; - - void thread_affinity( bool) noexcept; - template PROPS& properties() { - return fm_properties(impl_.get()); + return detail::scheduler::instance()->properties(impl_.get()); } }; diff --git a/include/boost/fiber/fiber_manager.hpp b/include/boost/fiber/fiber_manager.hpp index 9dd46bb3..6b497891 100644 --- a/include/boost/fiber/fiber_manager.hpp +++ b/include/boost/fiber/fiber_manager.hpp @@ -50,8 +50,6 @@ public: virtual ~fiber_manager() noexcept; - sched_algorithm* get_sched_algo_(); - std::chrono::high_resolution_clock::time_point next_wakeup(); void spawn( fiber_context *); @@ -83,6 +81,8 @@ public: fiber_context * active() noexcept; + sched_algorithm* get_sched_algo_(); + void set_sched_algo( sched_algorithm *); void wait_interval( std::chrono::high_resolution_clock::duration const&) noexcept; @@ -94,16 +94,14 @@ public: std::chrono::high_resolution_clock::duration wait_interval() noexcept; -#error FIX ME // implementation for fiber::properties() template < class PROPS > - PROPS& properties( detail::worker_fiber * f ) + PROPS& properties( fiber_context * f ) { return dynamic_cast&>(*get_sched_algo_()) .properties(f); } -#error FIX ME // implementation for this_fiber::properties() template < class PROPS > PROPS& properties() diff --git a/include/boost/fiber/operations.hpp b/include/boost/fiber/operations.hpp index 455377e5..4ccdf245 100644 --- a/include/boost/fiber/operations.hpp +++ b/include/boost/fiber/operations.hpp @@ -52,8 +52,7 @@ void sleep_for( std::chrono::duration< Rep, Period > const& timeout_duration) { template < class PROPS > PROPS& properties() { - // fibers::detail::scheduler::instance()->active()->... ? - return fibers::fm_properties(); + return fibers::detail::scheduler::instance()->active()->properties(); } } // this_fiber diff --git a/include/boost/fiber/properties.hpp b/include/boost/fiber/properties.hpp index 5ae52eab..0f5bf403 100644 --- a/include/boost/fiber/properties.hpp +++ b/include/boost/fiber/properties.hpp @@ -24,17 +24,14 @@ namespace boost { namespace fibers { -namespace detail { -class worker_fiber; -} // detail - struct sched_algorithm; +class fiber_context; class fiber_properties { protected: // initialized by constructor - detail::worker_fiber* fiber_; + fiber_context* fiber_; // set every time this fiber becomes READY sched_algorithm* sched_algo_; @@ -45,17 +42,17 @@ protected: public: // fiber_properties, and by implication every subclass, must accept a back - // pointer to its worker_fiber. - typedef detail::worker_fiber* back_ptr; + // pointer to its fiber_context. + typedef fiber_context* back_ptr; // Any specific property setter method, after updating the relevant // instance variable, can/should call notify(). fiber_properties(back_ptr f): fiber_(f), - sched_algo_(0) + sched_algo_(nullptr) {} // We need a virtual destructor (hence a vtable) because fiber_properties - // is stored polymorphically (as fiber_properties*) in worker_fiber, and + // is stored polymorphically (as fiber_properties*) in fiber_context, and // destroyed via that pointer. ~fiber_properties() {} diff --git a/src/fiber.cpp b/src/fiber.cpp index 1add6ab1..dcc23ef6 100644 --- a/src/fiber.cpp +++ b/src/fiber.cpp @@ -34,7 +34,7 @@ fiber::join() { if ( boost::this_fiber::get_id() == get_id() ) { throw fiber_resource_error( static_cast< int >( std::errc::resource_deadlock_would_occur), - "boost fiber: trying joining itself"); + "boost fiber: trying to join itself"); } if ( ! joinable() ) {