Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57639 - in sandbox/fiber: boost/fiber boost/fiber/detail libs/fiber/src
From: oliver.kowalke_at_[hidden]
Date: 2009-11-13 13:18:15


Author: olli
Date: 2009-11-13 13:18:14 EST (Fri, 13 Nov 2009)
New Revision: 57639
URL: http://svn.boost.org/trac/boost/changeset/57639

Log:
- implemetation of cancel_fiber(), suspend_fiber(), resume_fiber()

Text files modified:
   sandbox/fiber/boost/fiber/detail/fiber_state.hpp | 22 +++---
   sandbox/fiber/boost/fiber/detail/scheduler_impl.hpp | 16 +++-
   sandbox/fiber/boost/fiber/fiber.hpp | 4 +
   sandbox/fiber/boost/fiber/scheduler.hpp | 12 +++
   sandbox/fiber/boost/fiber/utility.hpp | 8 +
   sandbox/fiber/libs/fiber/src/fiber.cpp | 11 ++
   sandbox/fiber/libs/fiber/src/scheduler.cpp | 30 ++++++++
   sandbox/fiber/libs/fiber/src/scheduler_impl.cpp | 131 +++++++++++++++++++++++++++++++++++----
   8 files changed, 195 insertions(+), 39 deletions(-)

Modified: sandbox/fiber/boost/fiber/detail/fiber_state.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/detail/fiber_state.hpp (original)
+++ sandbox/fiber/boost/fiber/detail/fiber_state.hpp 2009-11-13 13:18:14 EST (Fri, 13 Nov 2009)
@@ -13,19 +13,21 @@
 namespace fibers {
 namespace detail {
 
-enum fiber_state_t
+enum state_t
 {
- STATE_MASTER = 0X00,
- STATE_NOT_STARTED = 0X10,
- STATE_RUNNABLE = 0x20,
- STATE_READY = 0x21,
- STATE_RUNNING = 0x22,
- STATE_NOT_RUNNABLE = 0x40,
- STATE_SUSPENDED = 0x41,
- STATE_WAITING = 0x42,
- STATE_TERMINATED = 0x80
+ STATE_MASTER = 1 << 0,
+ STATE_NOT_STARTED = 1 << 1,
+ STATE_READY = 1 << 2,
+ STATE_RUNNING = 1 << 3,
+ STATE_SUSPENDED = 1 << 4,
+ STATE_WAITING = 1 << 5,
+ STATE_TERMINATED = 1 << 6
 };
 
+typedef char fiber_state_t;
+
+#define IS_ALIVE_BIT_MASK 0x3C
+
 }}
 
 }

Modified: sandbox/fiber/boost/fiber/detail/scheduler_impl.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/detail/scheduler_impl.hpp (original)
+++ sandbox/fiber/boost/fiber/detail/scheduler_impl.hpp 2009-11-13 13:18:14 EST (Fri, 13 Nov 2009)
@@ -10,6 +10,7 @@
 #include <cstddef>
 #include <list>
 #include <map>
+#include <queue>
 
 #include <boost/utility.hpp>
 
@@ -26,13 +27,14 @@
 {
 private:
         typedef std::map< fiber::id, fiber > container;
- typedef std::list< fiber::id > queue;
+ typedef std::list< fiber::id > runnable_queue;
+ typedef std::queue< fiber::id > terminated_queue;
 
         fiber master_;
         fiber::id f_id_;
         container fibers_;
- queue runnable_fibers_;
- queue terminated_fibers_;
+ runnable_queue runnable_fibers_;
+ terminated_queue terminated_fibers_;
 
 public:
         scheduler_impl();
@@ -43,10 +45,16 @@
 
         void yield_active_fiber();
 
- void terminate_active_fiber();
+ void cancel_active_fiber();
+
+ void suspend_active_fiber();
 
         void cancel_fiber( fiber::id const&);
 
+ void suspend_fiber( fiber::id const&);
+
+ void resume_fiber( fiber::id const&);
+
         bool run();
 
         bool empty();

Modified: sandbox/fiber/boost/fiber/fiber.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/fiber.hpp (original)
+++ sandbox/fiber/boost/fiber/fiber.hpp 2009-11-13 13:18:14 EST (Fri, 13 Nov 2009)
@@ -189,6 +189,10 @@
         bool is_alive() const;
 
         void cancel();
+
+ void suspend();
+
+ void resume();
 };
 
 class fiber::id

Modified: sandbox/fiber/boost/fiber/scheduler.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/scheduler.hpp (original)
+++ sandbox/fiber/boost/fiber/scheduler.hpp 2009-11-13 13:18:14 EST (Fri, 13 Nov 2009)
@@ -29,6 +29,7 @@
 fiber::fiber::id get_id();
 void yield();
 void cancel();
+void suspend();
 
 }
 
@@ -41,6 +42,7 @@
         friend fiber::id this_fiber::get_id();
         friend void this_fiber::yield();
         friend void this_fiber::cancel();
+ friend void this_fiber::suspend();
         friend class fiber;
 
         typedef thread_specific_ptr< detail::scheduler_impl > tss_impl_t;
@@ -49,14 +51,20 @@
 
         static bool runs_as_fiber();
 
- static fiber::id get_id();
+ static fiber::id active_fiber();
 
         static void yield_active_fiber();
 
- static void terminate_active_fiber();
+ static void cancel_active_fiber();
+
+ static void suspend_active_fiber();
 
         static void cancel_fiber( fiber::id const&);
 
+ static void suspend_fiber( fiber::id const&);
+
+ static void resume_fiber( fiber::id const&);
+
         detail::scheduler_impl * access_();
 
 public:

Modified: sandbox/fiber/boost/fiber/utility.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/utility.hpp (original)
+++ sandbox/fiber/boost/fiber/utility.hpp 2009-11-13 13:18:14 EST (Fri, 13 Nov 2009)
@@ -25,7 +25,7 @@
 
 inline
 fiber::id get_id()
-{ return fibers::scheduler::get_id(); }
+{ return fibers::scheduler::active_fiber(); }
 
 inline
 void yield()
@@ -33,7 +33,11 @@
 
 inline
 void cancel()
-{ fibers::scheduler::terminate_active_fiber(); }
+{ fibers::scheduler::cancel_active_fiber(); }
+
+inline
+void suspend()
+{ fibers::scheduler::suspend_active_fiber(); }
 
 }}
 

Modified: sandbox/fiber/libs/fiber/src/fiber.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/fiber.cpp (original)
+++ sandbox/fiber/libs/fiber/src/fiber.cpp 2009-11-13 13:18:14 EST (Fri, 13 Nov 2009)
@@ -106,14 +106,21 @@
 {
         if ( ! info_)
                 throw fiber_moved();
- return ( info_->state & detail::STATE_RUNNABLE) == detail::STATE_RUNNABLE ||
- ( info_->state & detail::STATE_NOT_RUNNABLE) == detail::STATE_NOT_RUNNABLE;
+ return ( info_->state & IS_ALIVE_BIT_MASK) != 0;
 }
 
 void
 fiber::cancel()
 { scheduler::cancel_fiber( get_id() ); }
 
+void
+fiber::suspend()
+{ scheduler::suspend_fiber( get_id() ); }
+
+void
+fiber::resume()
+{ scheduler::resume_fiber( get_id() ); }
+
 }}
 
 #include <boost/config/abi_suffix.hpp>

Modified: sandbox/fiber/libs/fiber/src/scheduler.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/scheduler.cpp (original)
+++ sandbox/fiber/libs/fiber/src/scheduler.cpp 2009-11-13 13:18:14 EST (Fri, 13 Nov 2009)
@@ -22,7 +22,7 @@
 { return impl_.get() != 0; }
 
 fiber::id
-scheduler::get_id()
+scheduler::active_fiber()
 {
         detail::scheduler_impl * impl( impl_.get() );
         if ( ! impl) throw fiber_error("not a fiber");
@@ -38,11 +38,19 @@
 }
 
 void
-scheduler::terminate_active_fiber()
+scheduler::cancel_active_fiber()
 {
         detail::scheduler_impl * impl( impl_.get() );
         if ( ! impl) throw fiber_error("not a fiber");
- impl->terminate_active_fiber();
+ impl->cancel_active_fiber();
+}
+
+void
+scheduler::suspend_active_fiber()
+{
+ detail::scheduler_impl * impl( impl_.get() );
+ if ( ! impl) throw fiber_error("not a fiber");
+ impl->suspend_active_fiber();
 }
 
 void
@@ -53,6 +61,22 @@
         impl->cancel_fiber( f_id);
 }
 
+void
+scheduler::suspend_fiber( fiber::id const& f_id)
+{
+ detail::scheduler_impl * impl( impl_.get() );
+ if ( ! impl) throw fiber_error("not a fiber");
+ impl->suspend_fiber( f_id);
+}
+
+void
+scheduler::resume_fiber( fiber::id const& f_id)
+{
+ detail::scheduler_impl * impl( impl_.get() );
+ if ( ! impl) throw fiber_error("not a fiber");
+ impl->resume_fiber( f_id);
+}
+
 detail::scheduler_impl *
 scheduler::access_()
 {

Modified: sandbox/fiber/libs/fiber/src/scheduler_impl.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/scheduler_impl.cpp (original)
+++ sandbox/fiber/libs/fiber/src/scheduler_impl.cpp 2009-11-13 13:18:14 EST (Fri, 13 Nov 2009)
@@ -21,6 +21,27 @@
 namespace fibers {
 namespace detail {
 
+#define HAS_STATE_MASTER( state) \
+ ( state & STATE_MASTER) != 0
+
+#define HAS_STATE_NOT_STARTED( state) \
+ ( state & STATE_NOT_STARTED) != 0
+
+#define HAS_STATE_READY( state) \
+ ( state & STATE_READY) != 0
+
+#define HAS_STATE_RUNNING( state) \
+ ( state & STATE_RUNNING) != 0
+
+#define HAS_STATE_SUSPENDED( state) \
+ ( state & STATE_SUSPENDED) != 0
+
+#define HAS_STATE_WAITING( state) \
+ ( state & STATE_WAITING) != 0
+
+#define HAS_STATE_TERMINATED( state) \
+ ( state & STATE_TERMINATED) != 0
+
 scheduler_impl::scheduler_impl() :
         master_(
                 fiber_info_base::ptr_t(
@@ -58,11 +79,19 @@
 }
 
 void
-scheduler_impl::terminate_active_fiber()
+scheduler_impl::cancel_active_fiber()
 {
         BOOST_ASSERT( STATE_RUNNING == fibers_[f_id_].info_->state);
         fibers_[f_id_].info_->state = STATE_TERMINATED;
- terminated_fibers_.push_back( f_id_);
+ terminated_fibers_.push( f_id_);
+ fibers_[f_id_].switch_to_( master_);
+}
+
+void
+scheduler_impl::suspend_active_fiber()
+{
+ BOOST_ASSERT( STATE_RUNNING == fibers_[f_id_].info_->state);
+ fibers_[f_id_].info_->state |= STATE_SUSPENDED;
         fibers_[f_id_].switch_to_( master_);
 }
 
@@ -73,30 +102,92 @@
         if ( i == fibers_.end() ) return;
         fiber f( i->second);
         BOOST_ASSERT( f);
- BOOST_ASSERT( STATE_MASTER != f.info_->state);
- if ( STATE_TERMINATED == f.info_->state) return;
- else if ( STATE_NOT_STARTED == f.info_->state)
+ BOOST_ASSERT( HAS_STATE_MASTER( f.info_->state) );
+
+ if ( HAS_STATE_TERMINATED( f.info_->state) ||
+ HAS_STATE_NOT_STARTED( f.info_->state) )
+ return;
+
+ if ( HAS_STATE_READY( f.info_->state) )
         {
                 f.info_->state = STATE_TERMINATED;
- terminated_fibers_.push_back( f_id);
+ runnable_fibers_.remove( f.get_id() );
+ terminated_fibers_.push( f_id);
         }
- else if ( STATE_READY == f.info_->state)
+ else if ( HAS_STATE_RUNNING( f.info_->state) )
         {
+ BOOST_ASSERT( f_id == f.get_id() );
                 f.info_->state = STATE_TERMINATED;
- runnable_fibers_.remove( f.get_id() );
- terminated_fibers_.push_back( f_id);
+ terminated_fibers_.push( f_id);
+ f.switch_to_( master_);
         }
- else if ( STATE_RUNNING == f.info_->state)
+ else if ( HAS_STATE_WAITING( f.info_->state) )
         {
                 f.info_->state = STATE_TERMINATED;
- terminated_fibers_.push_back( f_id);
+ // TODO: remove from waiting-queue
+ terminated_fibers_.push( f_id);
+ }
+ else
+ BOOST_ASSERT( ! "should never reached");
+}
+
+void
+scheduler_impl::suspend_fiber( fiber::id const& f_id)
+{
+ container::iterator i = fibers_.find( f_id);
+ if ( i == fibers_.end() ) return;
+ fiber f( i->second);
+ BOOST_ASSERT( f);
+ BOOST_ASSERT( STATE_MASTER != f.info_->state);
+
+ if ( HAS_STATE_TERMINATED( f.info_->state) ||
+ HAS_STATE_NOT_STARTED( f.info_->state) )
+ return;
+
+ if ( HAS_STATE_READY( f.info_->state) )
+ {
+ f.info_->state |= STATE_SUSPENDED;
+ runnable_fibers_.remove( f.get_id() );
+ }
+ else if ( HAS_STATE_RUNNING( f.info_->state) )
+ {
+ BOOST_ASSERT( f_id == f.get_id() );
+ f.info_->state |= STATE_SUSPENDED;
                 f.switch_to_( master_);
         }
- else
+ else if ( HAS_STATE_WAITING( f.info_->state) )
         {
- // TODO: remove waiting fiber/suspended fiber
- f.info_->state = STATE_TERMINATED;
- terminated_fibers_.push_back( f_id);
+ f.info_->state |= STATE_SUSPENDED;
+ // TODO: remove from waiting-queue
+ }
+ else
+ BOOST_ASSERT( ! "should never reached");
+}
+
+void
+scheduler_impl::resume_fiber( fiber::id const& f_id)
+{
+ container::iterator i = fibers_.find( f_id);
+ if ( i == fibers_.end() ) return;
+ fiber f( i->second);
+ BOOST_ASSERT( f);
+ BOOST_ASSERT( STATE_MASTER != f.info_->state);
+
+ if ( HAS_STATE_SUSPENDED( f.info_->state) )
+ {
+ f.info_->state &= ~STATE_SUSPENDED;
+ switch ( f.info_->state)
+ {
+ case STATE_READY:
+ case STATE_RUNNING:
+ runnable_fibers_.push_back( f.get_id() );
+ break;
+ case STATE_WAITING:
+ // TODO: put it into the waiting-queue
+ break;
+ default:
+ BOOST_ASSERT( ! "should never reached");
+ }
         }
 }
 
@@ -117,7 +208,7 @@
         {
                 BOOST_ASSERT( STATE_TERMINATED == fibers_[terminated_fibers_.front()].info_->state);
                 fibers_.erase( terminated_fibers_.front() );
- terminated_fibers_.pop_front();
+ terminated_fibers_.pop();
                 result = true;
         }
         return result;
@@ -131,6 +222,14 @@
 scheduler_impl::size()
 { return fibers_.size(); }
 
+#undef HAS_STATE_MASTER
+#undef HAS_STATE_NOT_STARTED
+#undef HAS_STATE_READY
+#undef HAS_STATE_RUNNING
+#undef HAS_STATE_SUSPENDED
+#undef HAS_STATE_WAITING
+#undef HAS_STATE_TERMINATED
+
 }}}
 
 #include <boost/config/abi_suffix.hpp>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk