Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58003 - in sandbox/fiber: . boost/fiber boost/fiber/detail libs/fiber/build libs/fiber/examples libs/fiber/src
From: oliver.kowalke_at_[hidden]
Date: 2009-11-28 06:46:13


Author: olli
Date: 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
New Revision: 58003
URL: http://svn.boost.org/trac/boost/changeset/58003

Log:
- scheduler with scheduling-strategy as template argument (default round_robin)

Added:
   sandbox/fiber/boost/fiber/round_robin.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/strategy.hpp (contents, props changed)
   sandbox/fiber/libs/fiber/examples/future.cpp (contents, props changed)
   sandbox/fiber/libs/fiber/src/strategy.cpp (contents, props changed)
Removed:
   sandbox/fiber/boost/fiber/detail/round_robin.hpp
   sandbox/fiber/boost/fiber/detail/strategy.hpp
   sandbox/fiber/libs/fiber/src/scheduler.cpp
Text files modified:
   sandbox/fiber/boost/fiber/detail/fiber_info_base_posix.hpp | 4
   sandbox/fiber/boost/fiber/fiber.hpp | 17 -
   sandbox/fiber/boost/fiber/interruption.hpp | 20 +-
   sandbox/fiber/boost/fiber/scheduler.hpp | 106 ++---------
   sandbox/fiber/boost/fiber/utility.hpp | 49 ++---
   sandbox/fiber/change.log | 13 +
   sandbox/fiber/libs/fiber/build/Jamfile.v2 | 4
   sandbox/fiber/libs/fiber/examples/Jamfile.v2 | 9
   sandbox/fiber/libs/fiber/examples/at_exit.cpp | 2
   sandbox/fiber/libs/fiber/examples/cancel.cpp | 2
   sandbox/fiber/libs/fiber/examples/interrupt.cpp | 10
   sandbox/fiber/libs/fiber/examples/join.cpp | 2
   sandbox/fiber/libs/fiber/examples/ping_pong.cpp | 4
   sandbox/fiber/libs/fiber/examples/simple.cpp | 2
   sandbox/fiber/libs/fiber/examples/simple_mt.cpp | 4
   sandbox/fiber/libs/fiber/src/fiber.cpp | 11
   sandbox/fiber/libs/fiber/src/fiber_posix.cpp | 2
   sandbox/fiber/libs/fiber/src/fiber_windows.cpp | 2
   sandbox/fiber/libs/fiber/src/round_robin.cpp | 344 ++++++++++-----------------------------
   19 files changed, 195 insertions(+), 412 deletions(-)

Modified: sandbox/fiber/boost/fiber/detail/fiber_info_base_posix.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/detail/fiber_info_base_posix.hpp (original)
+++ sandbox/fiber/boost/fiber/detail/fiber_info_base_posix.hpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -28,6 +28,9 @@
 
 namespace boost {
 namespace fibers {
+
+class strategy;
+
 namespace detail {
 
 struct BOOST_FIBER_DECL fiber_info_base
@@ -44,6 +47,7 @@
         fiber_state_t state;
         fiber_interrupt_t interrupt;
         callable_stack_t at_exit;
+ strategy * st;
 
         fiber_info_base();
 

Deleted: sandbox/fiber/boost/fiber/detail/round_robin.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/detail/round_robin.hpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
+++ (empty file)
@@ -1,114 +0,0 @@
-
-// Copyright Oliver Kowalke 2009.
-// 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_ROUND_ROBIN_H
-#define BOOST_FIBERS_DETAIL_ROUND_ROBIN_H
-
-#include <cstddef>
-#include <list>
-#include <map>
-#include <queue>
-
-#include <boost/function.hpp>
-#include <boost/optional.hpp>
-#include <boost/utility.hpp>
-
-#include <boost/fiber/detail/config.hpp>
-#include <boost/fiber/detail/fiber_state.hpp>
-#include <boost/fiber/detail/strategy.hpp>
-#include <boost/fiber/fiber.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-# if defined(BOOST_MSVC)
-# pragma warning(push)
-# pragma warning(disable:4251 4275)
-# endif
-
-namespace boost {
-namespace fibers {
-namespace detail {
-
-class BOOST_FIBER_DECL round_robin : private noncopyable,
- public strategy
-{
-private:
- struct schedulable
- {
- fiber f;
- std::list< fiber::id > joining_fibers;
- optional< fiber::id > waiting_on;
-
- schedulable() :
- f(), joining_fibers(), waiting_on()
- {}
-
- schedulable( fiber f_) :
- f( f_), joining_fibers(), waiting_on()
- {}
- };
-
- typedef std::map< fiber::id, schedulable > container;
- typedef std::list< fiber::id > runnable_queue;
- typedef std::queue< fiber::id > terminated_queue;
-
- fiber master_;
- fiber active_;
- container fibers_;
- runnable_queue runnable_fibers_;
- terminated_queue terminated_fibers_;
-
-public:
- round_robin();
-
- ~round_robin();
-
- void add( fiber const&);
-
- fiber::id get_id() const;
-
- void yield();
-
- void cancel();
-
- void interrupt();
-
- bool interruption_requested() const;
-
- bool interruption_enabled() const;
-
- fiber_interrupt_t & interrupt_flags();
-
- int priority() const;
-
- void priority( int);
-
- void at_exit( callable_t);
-
- void interrupt( fiber::id const&);
-
- void cancel( fiber::id const&);
-
- void join( fiber::id const&);
-
- void reschedule( fiber::id const&);
-
- bool run();
-
- bool empty() const;
-
- std::size_t size() const;
-};
-
-}}}
-
-# if defined(BOOST_MSVC)
-# pragma warning(pop)
-# endif
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_FIBERS_DETAIL_ROUND_ROBIN_H

Deleted: sandbox/fiber/boost/fiber/detail/strategy.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/detail/strategy.hpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
+++ (empty file)
@@ -1,78 +0,0 @@
-
-// Copyright Oliver Kowalke 2009.
-// 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_STRATEGY_H
-#define BOOST_FIBERS_DETAIL_STRATEGY_H
-
-#include <cstddef>
-
-#include <boost/function.hpp>
-
-#include <boost/fiber/fiber.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-# if defined(BOOST_MSVC)
-# pragma warning(push)
-# pragma warning(disable:4251 4275)
-# endif
-
-namespace boost {
-namespace fibers {
-namespace detail {
-
-struct BOOST_FIBER_DECL strategy
-{
- typedef function< void() > callable_t;
-
- virtual ~strategy() {}
-
- virtual void add( fiber const&) = 0;
-
- virtual fiber::id get_id() const = 0;
-
- virtual void yield() = 0;
-
- virtual void cancel() = 0;
-
- virtual void interrupt() = 0;
-
- virtual bool interruption_requested() const = 0;
-
- virtual bool interruption_enabled() const = 0;
-
- virtual fiber_interrupt_t & interrupt_flags() = 0;
-
- virtual int priority() const = 0;
-
- virtual void priority( int) = 0;
-
- virtual void at_exit( callable_t) = 0;
-
- virtual void interrupt( fiber::id const&) = 0;
-
- virtual void cancel( fiber::id const&) = 0;
-
- virtual void join( fiber::id const&) = 0;
-
- virtual void reschedule( fiber::id const&) = 0;
-
- virtual bool run() = 0;
-
- virtual bool empty() const = 0;
-
- virtual std::size_t size() const = 0;
-};
-
-}}}
-
-# if defined(BOOST_MSVC)
-# pragma warning(pop)
-# endif
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_FIBERS_DETAIL_STRATEGY_H

Modified: sandbox/fiber/boost/fiber/fiber.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/fiber.hpp (original)
+++ sandbox/fiber/boost/fiber/fiber.hpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -30,21 +30,21 @@
 
 namespace boost {
 namespace fibers {
-namespace detail {
-
-class round_robin;
-
-}
 
 #define BOOST_FIBER_DEFAULT_STACKSIZE 64000
 
+class strategy;
+
 class BOOST_FIBER_DECL fiber
 {
 private:
- friend class detail::round_robin;
+ friend class strategy;
 
         struct dummy;
 
+ static void convert_thread_to_fiber();
+ static void convert_fiber_to_thread();
+
         detail::fiber_info_base::ptr_t info_base_;
 
         explicit fiber( detail::fiber_info_base::ptr_t);
@@ -88,9 +88,6 @@
 public:
         class id;
 
- static void convert_thread_to_fiber();
- static void convert_fiber_to_thread();
-
         fiber();
 
 #ifdef BOOST_HAS_RVALUE_REFS
@@ -123,7 +120,7 @@
         template< typename Fn >
         explicit fiber(
                         Fn fn,
- typename disable_if< boost::is_convertible< Fn &, boost::detail::fiber_move_t< Fn > >, dummy * >::type = 0) :
+ typename disable_if< boost::is_convertible< Fn &, boost::detail::fiber_move_t< Fn > >, dummy * >::type = 0) :
                 info_base_( make_info_( BOOST_FIBER_DEFAULT_STACKSIZE, fn) )
         { init_(); }
 

Modified: sandbox/fiber/boost/fiber/interruption.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/interruption.hpp (original)
+++ sandbox/fiber/boost/fiber/interruption.hpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -4,8 +4,8 @@
 // (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-#ifndef BOOST_FIBERS_INTERRUPTION_H
-#define BOOST_FIBERS_INTERRUPTION_H
+#ifndef BOOST_THIS_FIBER_INTERRUPTION_H
+#define BOOST_THIS_FIBER_INTERRUPTION_H
 
 #include <cstddef>
 
@@ -13,12 +13,12 @@
 
 #include <boost/fiber/detail/config.hpp>
 #include <boost/fiber/detail/fiber_state.hpp>
-#include <boost/fiber/scheduler.hpp>
+#include <boost/fiber/strategy.hpp>
 
 #include <boost/config/abi_prefix.hpp>
 
 namespace boost {
-namespace fibers {
+namespace this_fiber {
 
 class restore_interruption;
 
@@ -31,10 +31,10 @@
 
 public:
         disable_interruption() :
- set_( ( scheduler::interrupt_flags() & detail::INTERRUPTION_BLOCKED) != 0)
+ set_( ( fibers::strategy::interrupt_flags() & fibers::detail::INTERRUPTION_BLOCKED) != 0)
         {
                 if ( ! set_)
- scheduler::interrupt_flags() |= detail::INTERRUPTION_BLOCKED;
+ fibers::strategy::interrupt_flags() |= fibers::detail::INTERRUPTION_BLOCKED;
         }
 
         ~disable_interruption()
@@ -42,7 +42,7 @@
                 try
                 {
                         if ( ! set_)
- scheduler::interrupt_flags() &= ~detail::INTERRUPTION_BLOCKED;
+ fibers::strategy::interrupt_flags() &= ~fibers::detail::INTERRUPTION_BLOCKED;
                 }
                 catch (...)
                 {}
@@ -59,7 +59,7 @@
                 disabler_( disabler)
         {
                 if ( ! disabler_.set_)
- scheduler::interrupt_flags() &= ~detail::INTERRUPTION_BLOCKED;
+ fibers::strategy::interrupt_flags() &= ~fibers::detail::INTERRUPTION_BLOCKED;
         }
 
         ~restore_interruption()
@@ -67,7 +67,7 @@
            try
            {
                         if ( ! disabler_.set_)
- scheduler::interrupt_flags() |= detail::INTERRUPTION_BLOCKED;
+ fibers::strategy::interrupt_flags() |= fibers::detail::INTERRUPTION_BLOCKED;
                 }
                 catch (...)
                 {}
@@ -78,4 +78,4 @@
 
 #include <boost/config/abi_suffix.hpp>
 
-#endif // BOOST_FIBERS_INTERRUPTION_H
+#endif // BOOST_THIS_FIBER_INTERRUPTION_H

Added: sandbox/fiber/boost/fiber/round_robin.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/round_robin.hpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -0,0 +1,91 @@
+
+// Copyright Oliver Kowalke 2009.
+// 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_ROUND_ROBIN_H
+#define BOOST_FIBERS_ROUND_ROBIN_H
+
+#include <cstddef>
+#include <list>
+#include <map>
+#include <queue>
+
+#include <boost/function.hpp>
+#include <boost/optional.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/detail/config.hpp>
+#include <boost/fiber/detail/fiber_state.hpp>
+#include <boost/fiber/fiber.hpp>
+#include <boost/fiber/strategy.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+# if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4251 4275)
+# endif
+
+namespace boost {
+namespace fibers {
+
+class BOOST_FIBER_DECL round_robin : private noncopyable,
+ public strategy
+{
+private:
+ struct schedulable
+ {
+ fiber f;
+ std::list< fiber::id > joining_fibers;
+ optional< fiber::id > waiting_on;
+
+ schedulable() :
+ f(), joining_fibers(), waiting_on()
+ {}
+
+ schedulable( fiber f_) :
+ f( f_), joining_fibers(), waiting_on()
+ {}
+ };
+
+ typedef std::map< fiber::id, schedulable > container;
+ typedef std::list< fiber::id > runnable_queue;
+ typedef std::queue< fiber::id > terminated_queue;
+
+ container fibers_;
+ runnable_queue runnable_fibers_;
+ terminated_queue terminated_fibers_;
+
+public:
+ round_robin();
+
+ void add( fiber);
+
+ void yield( fiber::id const&);
+
+ void cancel( fiber::id const&);
+
+ void join( fiber::id const&);
+
+ void interrupt( fiber::id const&);
+
+ void reschedule( fiber::id const&);
+
+ bool run();
+
+ bool empty();
+
+ std::size_t size();
+};
+
+}}
+
+# if defined(BOOST_MSVC)
+# pragma warning(pop)
+# endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBERS_ROUND_ROBIN_H

Modified: sandbox/fiber/boost/fiber/scheduler.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/scheduler.hpp (original)
+++ sandbox/fiber/boost/fiber/scheduler.hpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -10,15 +10,15 @@
 #include <cstddef>
 #include <memory>
 
-#include <boost/function.hpp>
 #include <boost/preprocessor/repetition.hpp>
 #include <boost/thread/tss.hpp>
 #include <boost/utility.hpp>
 
 #include <boost/fiber/detail/config.hpp>
 #include <boost/fiber/detail/fiber_state.hpp>
-#include <boost/fiber/detail/strategy.hpp>
 #include <boost/fiber/fiber.hpp>
+#include <boost/fiber/round_robin.hpp>
+#include <boost/fiber/strategy.hpp>
 
 #include <boost/config/abi_prefix.hpp>
 
@@ -28,99 +28,43 @@
 # endif
 
 namespace boost {
-
-namespace this_fiber {
-
-bool runs_as_fiber();
-boost::fiber::id get_id();
-void yield();
-void cancel();
-int priority();
-void priority( int);
-void interruption_point();
-bool interruption_requested();
-bool interruption_enabled();
-template< typename Callable >
-void at_fiber_exit( Callable);
-void at_fiber_exit( function< void() >);
-void at_fiber_exit( void (*)() );
-
-}
-
 namespace fibers {
 
-class disable_interruption;
-class restore_interruption;
-
+template< typename Strategy = round_robin >
 class BOOST_FIBER_DECL scheduler : private noncopyable
 {
 private:
- friend bool this_fiber::runs_as_fiber();
- friend fiber::id this_fiber::get_id();
- friend void this_fiber::yield();
- friend void this_fiber::cancel();
- friend int this_fiber::priority();
- friend void this_fiber::priority( int);
- friend void this_fiber::interruption_point();
- friend bool this_fiber::interruption_requested();
- friend bool this_fiber::interruption_enabled();
- template< typename Callable >
- friend void this_fiber::at_fiber_exit( Callable);
- friend void this_fiber::at_fiber_exit( function< void() >);
- friend void this_fiber::at_fiber_exit( void (*)() );
- friend class fiber;
- friend class disable_interruption;
- friend class restore_interruption;
-
- typedef thread_specific_ptr< detail::strategy > impl_t;
- typedef function< void() > callable_t;
-
- static impl_t impl_;
-
- static bool runs_as_fiber();
-
- static fiber::id get_id();
-
- static void interrupt();
-
- static bool interruption_requested();
 
- static bool interruption_enabled();
+ typedef thread_specific_ptr< strategy > impl_t;
 
- static detail::fiber_interrupt_t & interrupt_flags();
+ impl_t impl_;
 
- static void yield();
-
- static void cancel();
-
- static int priority();
-
- static void priority( int);
-
- static void at_exit( callable_t);
-
- static void interrupt( fiber::id const&);
-
- static bool interruption_requested( fiber::id const&);
-
- static void cancel( fiber::id const&);
-
- static void join( fiber::id const&);
-
- static void reschedule( fiber::id const&);
-
- detail::strategy * access_();
+ strategy * access_()
+ {
+ if ( ! impl_.get() )
+ impl_.reset( new Strategy() );
+ return impl_.get();
+ }
 
 public:
- ~scheduler();
+ scheduler() :
+ impl_()
+ {}
+
+ ~scheduler()
+ { impl_.reset(); }
 
- bool run();
+ bool run()
+ { return access_()->run(); }
 
- bool empty();
+ bool empty()
+ { return access_()->empty(); }
 
- std::size_t size();
+ std::size_t size()
+ { return access_()->size(); }
 
- void submit_fiber( fiber);
+ void submit_fiber( fiber f)
+ { access_()->add( f); }
 
         template< typename Fn >
         void make_fiber( Fn fn)

Added: sandbox/fiber/boost/fiber/strategy.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/strategy.hpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -0,0 +1,159 @@
+
+// Copyright Oliver Kowalke 2009.
+// 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_STRATEGY_H
+#define BOOST_FIBERS_STRATEGY_H
+
+#include <cstddef>
+
+#include <boost/function.hpp>
+#include <boost/thread/tss.hpp>
+
+#include <boost/fiber/detail/fiber_state.hpp>
+#include <boost/fiber/fiber.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+# if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4251 4275)
+# endif
+
+namespace boost {
+
+namespace this_fiber {
+
+bool runs_as_fiber();
+fiber::id get_id();
+void yield();
+void cancel();
+int priority();
+void priority( int);
+void interruption_point();
+bool interruption_requested();
+bool interruption_enabled();
+template< typename Callable >
+void at_fiber_exit( Callable);
+void at_fiber_exit( function< void() >);
+void at_fiber_exit( void (*)() );
+
+class disable_interruption;
+class restore_interruption;
+
+}
+
+namespace fibers {
+
+class BOOST_FIBER_DECL strategy
+{
+private:
+ friend bool this_fiber::runs_as_fiber();
+ friend fiber::id this_fiber::get_id();
+ friend void this_fiber::yield();
+ friend void this_fiber::cancel();
+ friend int this_fiber::priority();
+ friend void this_fiber::priority( int);
+ friend void this_fiber::interruption_point();
+ friend bool this_fiber::interruption_requested();
+ friend bool this_fiber::interruption_enabled();
+ template< typename Callable >
+ friend void this_fiber::at_fiber_exit( Callable);
+ friend void this_fiber::at_fiber_exit( function< void() >);
+ friend void this_fiber::at_fiber_exit( void (*)() );
+ friend class this_fiber::disable_interruption;
+ friend class this_fiber::restore_interruption;
+
+ typedef function< void() > callable_t;
+
+ static bool runs_as_fiber();
+
+ static fiber::id get_id();
+
+ static void interruption_point();
+
+ static bool interruption_requested();
+
+ static detail::fiber_interrupt_t & interrupt_flags();
+
+ static bool interruption_enabled();
+
+ static int priority();
+
+ static void priority( int);
+
+ static void at_fiber_exit( callable_t);
+
+ static void yield();
+
+ static void cancel();
+
+protected:
+ typedef thread_specific_ptr< fiber > active_fiber_t;
+
+ static active_fiber_t active_fiber;
+ fiber master_fiber;
+
+ void attach( fiber &);
+
+ void switch_between( fiber &, fiber &);
+
+ void enable_interruption( fiber &);
+
+ bool interruption_enabled( fiber const&);
+
+ bool is_master( fiber const&);
+
+ bool in_state_not_started( fiber const&);
+
+ bool in_state_ready( fiber const&);
+
+ bool in_state_running( fiber const&);
+
+ bool in_state_wait_for_join( fiber const&);
+
+ bool in_state_terminated( fiber const&);
+
+ void set_state_ready( fiber &);
+
+ void set_state_running( fiber &);
+
+ void set_state_wait_for_join( fiber &);
+
+ void set_state_terminated( fiber &);
+
+public:
+ strategy();
+
+ virtual ~strategy();
+
+ virtual void add( fiber) = 0;
+
+ virtual void yield( fiber::id const&) = 0;
+
+ virtual void cancel( fiber::id const&) = 0;
+
+ virtual void join( fiber::id const&) = 0;
+
+ virtual void interrupt( fiber::id const&) = 0;
+
+ virtual void reschedule( fiber::id const&) = 0;
+
+ virtual bool run() = 0;
+
+ virtual bool empty() = 0;
+
+ virtual std::size_t size() = 0;
+};
+
+}}
+
+# if defined(BOOST_MSVC)
+# pragma warning(pop)
+# endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBERS_STRATEGY_H

Modified: sandbox/fiber/boost/fiber/utility.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/utility.hpp (original)
+++ sandbox/fiber/boost/fiber/utility.hpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -8,11 +8,10 @@
 #define BOOST_THIS_FIBER_UTILITY_H
 
 #include <boost/bind.hpp>
-#include <boost/config.hpp>
 #include <boost/function.hpp>
 
 #include <boost/fiber/fiber.hpp>
-#include <boost/fiber/scheduler.hpp>
+#include <boost/fiber/strategy.hpp>
 
 #include <boost/config/abi_prefix.hpp>
 
@@ -21,57 +20,51 @@
 
 inline
 bool runs_as_fiber()
-{ return fibers::scheduler::runs_as_fiber(); }
+{ return fibers::strategy::runs_as_fiber(); }
 
 inline
 fiber::id get_id()
-{ return fibers::scheduler::get_id(); }
-
-inline
-void yield()
-{ fibers::scheduler::yield(); }
-
-inline
-void cancel()
-{ fibers::scheduler::cancel(); }
+{ return fibers::strategy::get_id(); }
 
 inline
 int priority()
-{ return fibers::scheduler::priority(); }
+{ return fibers::strategy::priority(); }
 
 inline
 void priority( int prio)
-{ fibers::scheduler::priority( prio); }
+{ fibers::strategy::priority( prio); }
 
 inline
 void interruption_point()
-{ fibers::scheduler::interrupt(); }
+{ fibers::strategy::interruption_point(); }
 
 inline
 bool interruption_requested()
-{ return fibers::scheduler::interruption_requested(); }
+{ return fibers::strategy::interruption_requested(); }
 
 inline
 bool interruption_enabled()
-{ return fibers::scheduler::interruption_enabled(); }
+{ return fibers::strategy::interruption_enabled(); }
+
+inline
+void at_fiber_exit( function< void() > ca)
+{ fibers::strategy::at_fiber_exit( ca); }
 
 template< typename Callable >
 void at_fiber_exit( Callable ca)
-{
- fibers::scheduler::at_exit(
- boost::bind( boost::type< void >(), ca) );
-}
+{ fibers::strategy::at_fiber_exit( boost::bind( boost::type< void >(), ca) ); }
 
 inline
-void at_fiber_exit( function< void() > ca)
-{ fibers::scheduler::at_exit( ca); }
+void at_fiber_exit( void ( * ca)() )
+{ fibers::strategy::at_fiber_exit( boost::bind( boost::type< void >(), ca) ); }
 
 inline
-void at_fiber_exit( void ( * ca)() )
-{
- fibers::scheduler::at_exit(
- boost::bind( boost::type< void >(), ca) );
-}
+void yield()
+{ fibers::strategy::yield(); }
+
+inline
+void cancel()
+{ fibers::strategy::cancel(); }
 
 }}
 

Modified: sandbox/fiber/change.log
==============================================================================
--- sandbox/fiber/change.log (original)
+++ sandbox/fiber/change.log 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -1,3 +1,16 @@
+0.2.0:
+------
+- classes disable_interruption and restore_interruption moved into namespace boost::this_fiber
+- classes strategy and round robin moved into namespace boost::fibers
+- class strategy becomes an abstract base-class and provides protected member
+ functions in order to access private data of class boost::fiber
+- class scheduler becomes a template
+ the template argument must be derived from strategy and implements the scheduling strategy
+ the default is boost::fibers::round_robin
+- multiple schedulers in one thread supported
+- STATE macros in class boost::fibers::round_robin replaced by protected member function of
+ boost::fibers::strategy
+
 0.1.1 :
 -------
 - refactor STATE macros -> don't test and set only one bit

Modified: sandbox/fiber/libs/fiber/build/Jamfile.v2
==============================================================================
--- sandbox/fiber/libs/fiber/build/Jamfile.v2 (original)
+++ sandbox/fiber/libs/fiber/build/Jamfile.v2 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -50,7 +50,7 @@
         manual_reset_event.cpp
         mutex.cpp
         round_robin.cpp
- scheduler.cpp
+ strategy.cpp
     : ## requirements ##
       <fiberapi>win32
     ;
@@ -66,7 +66,7 @@
         manual_reset_event.cpp
         mutex.cpp
         round_robin.cpp
- scheduler.cpp
+ strategy.cpp
     : ## requirements ##
       <fiberapi>posix
     ;

Modified: sandbox/fiber/libs/fiber/examples/Jamfile.v2
==============================================================================
--- sandbox/fiber/libs/fiber/examples/Jamfile.v2 (original)
+++ sandbox/fiber/libs/fiber/examples/Jamfile.v2 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -24,9 +24,10 @@
     ;
 
 exe at_exit : at_exit.cpp ;
-exe join : join.cpp ;
-exe interrupt : interrupt.cpp ;
 exe cancel : cancel.cpp ;
-exe simple : simple.cpp ;
-exe simple_mt : simple_mt.cpp ;
+exe future : future.cpp ;
+exe interrupt : interrupt.cpp ;
+exe join : join.cpp ;
 exe ping_pong : ping_pong.cpp ;
+exe simple_mt : simple_mt.cpp ;
+exe simple : simple.cpp ;

Modified: sandbox/fiber/libs/fiber/examples/at_exit.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/examples/at_exit.cpp (original)
+++ sandbox/fiber/libs/fiber/examples/at_exit.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -20,7 +20,7 @@
 {
         try
         {
- boost::fibers::scheduler sched;
+ boost::fibers::scheduler<> sched;
 
                 sched.make_fiber( fn);
 

Modified: sandbox/fiber/libs/fiber/examples/cancel.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/examples/cancel.cpp (original)
+++ sandbox/fiber/libs/fiber/examples/cancel.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -39,7 +39,7 @@
 {
         try
         {
- boost::fibers::scheduler sched;
+ boost::fibers::scheduler<> sched;
 
                 boost::fiber f( fn_1);
                 sched.submit_fiber( f);

Added: sandbox/fiber/libs/fiber/examples/future.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/examples/future.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -0,0 +1,83 @@
+#include <cstdlib>
+#include <iostream>
+#include <string>
+
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/thread.hpp>
+
+#include <boost/fiber.hpp>
+
+inline
+std::string helloworld_fn()
+{ return "Hello World"; }
+
+class callable
+{
+private:
+ struct impl
+ {
+ virtual ~impl() {}
+
+ virtual void exec() = 0;
+ };
+
+ template< typename T >
+ class timpl : public impl
+ {
+ private:
+ boost::packaged_task< T > pt_;
+
+ public:
+ timpl( boost::packaged_task< T > & pt) :
+ pt_( boost::move( pt) )
+ {}
+
+ void exec()
+ { pt_(); }
+ };
+
+ boost::shared_ptr< impl > impl_;
+
+public:
+ template< typename T >
+ callable( boost::packaged_task< T > & pt) :
+ impl_( new timpl< T >( pt) )
+ {}
+
+ void operator()()
+ { impl_->exec(); }
+};
+
+int main()
+{
+ try
+ {
+ boost::fibers::scheduler<> sched;
+
+ boost::packaged_task< std::string > pt( helloworld_fn);
+ boost::unique_future< std::string > fu = pt.get_future();
+ callable ca( pt);
+ sched.make_fiber( ca);
+
+ for (;;)
+ {
+ while ( sched.run() );
+ if ( sched.empty() ) break;
+ }
+
+ std::cout << fu.get() << std::endl;
+
+ return EXIT_SUCCESS;
+ }
+ catch ( boost::system::system_error const& e)
+ { std::cerr << "system_error: " << e.code().value() << std::endl; }
+ catch ( boost::fibers::scheduler_error const& e)
+ { std::cerr << "scheduler_error: " << e.what() << std::endl; }
+ catch ( std::exception const& e)
+ { std::cerr << "exception: " << e.what() << std::endl; }
+ catch (...)
+ { std::cerr << "unhandled exception" << std::endl; }
+ return EXIT_FAILURE;
+}

Modified: sandbox/fiber/libs/fiber/examples/interrupt.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/examples/interrupt.cpp (original)
+++ sandbox/fiber/libs/fiber/examples/interrupt.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -24,7 +24,7 @@
 
 void fn_2()
 {
- boost::fibers::disable_interruption disabled;
+ boost::this_fiber::disable_interruption disabled;
         for ( int i = 0; i < 10; ++i)
         {
                 ++value2;
@@ -36,12 +36,12 @@
 
 void fn_3()
 {
- boost::fibers::disable_interruption disabled;
+ boost::this_fiber::disable_interruption disabled;
         for ( int i = 0; i < 10; ++i)
         {
                 ++value3;
                 std::cout << "fn_3() increment value3 " << value3 << std::endl;
- boost::fibers::restore_interruption restored( disabled);
+ boost::this_fiber::restore_interruption restored( disabled);
                 boost::this_fiber::interruption_point();
                 boost::this_fiber::yield();
         }
@@ -65,7 +65,7 @@
 {
         try
         {
- boost::fibers::scheduler sched;
+ boost::fibers::scheduler<> sched;
 
                 boost::fiber f1( fn_1);
                 sched.submit_fiber( f1);
@@ -111,7 +111,7 @@
         }
         catch ( boost::system::system_error const& e)
         { std::cerr << "system_error: " << e.code().value() << std::endl; }
- catch ( boost::fibers::scheduler_error const& e)
+ catch ( boost::fibers::scheduler<>_error const& e)
         { std::cerr << "scheduler_error: " << e.what() << std::endl; }
         catch ( std::exception const& e)
         { std::cerr << "exception: " << e.what() << std::endl; }

Modified: sandbox/fiber/libs/fiber/examples/join.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/examples/join.cpp (original)
+++ sandbox/fiber/libs/fiber/examples/join.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -40,7 +40,7 @@
 {
         try
         {
- boost::fibers::scheduler sched;
+ boost::fibers::scheduler<> sched;
 
                 boost::fiber f( fn_1);
                 sched.submit_fiber( f);

Modified: sandbox/fiber/libs/fiber/examples/ping_pong.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/examples/ping_pong.cpp (original)
+++ sandbox/fiber/libs/fiber/examples/ping_pong.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -62,7 +62,7 @@
         send_buf->deactivate();
 }
 
-void f( boost::fibers::scheduler & sched)
+void f( boost::fibers::scheduler<> & sched)
 {
         fifo_ptr_t buf1( new fifo_t() );
         fifo_ptr_t buf2( new fifo_t() );
@@ -75,7 +75,7 @@
 {
         try
         {
- boost::fibers::scheduler sched;
+ boost::fibers::scheduler<> sched;
 
                 sched.make_fiber( & f, boost::ref( sched) );
 

Modified: sandbox/fiber/libs/fiber/examples/simple.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/examples/simple.cpp (original)
+++ sandbox/fiber/libs/fiber/examples/simple.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -21,7 +21,7 @@
 {
         try
         {
- boost::fibers::scheduler sched;
+ boost::fibers::scheduler<> sched;
 
                 boost::fiber f( fn, "abc", 5);
                 sched.submit_fiber( boost::move( f) );

Modified: sandbox/fiber/libs/fiber/examples/simple_mt.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/examples/simple_mt.cpp (original)
+++ sandbox/fiber/libs/fiber/examples/simple_mt.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -25,7 +25,7 @@
 
 void run_thread(
                 boost::barrier & b,
- boost::fibers::scheduler & sched,
+ boost::fibers::scheduler<> & sched,
                 std::string const& msg, int n)
 {
                 std::ostringstream os;
@@ -47,7 +47,7 @@
 {
         try
         {
- boost::fibers::scheduler sched;
+ boost::fibers::scheduler<> sched;
 
                 std::cout << "start" << std::endl;
 

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-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -10,7 +10,7 @@
 
 #include <boost/fiber/detail/fiber_state.hpp>
 #include <boost/fiber/exceptions.hpp>
-#include <boost/fiber/scheduler.hpp>
+#include <boost/fiber/strategy.hpp>
 
 #include <boost/config/abi_prefix.hpp>
 
@@ -121,14 +121,15 @@
 {
         if ( ! info_base_) throw fiber_moved();
         info_base_->priority = prio;
- if ( is_alive() ) scheduler::reschedule( get_id() );
+ if ( is_alive() )
+ info_base_->st->reschedule( get_id() );
 }
 
 void
 fiber::interrupt()
 {
         if ( ! info_base_) throw fiber_moved();
- scheduler::interrupt( get_id() );
+ info_base_->st->interrupt( get_id() );
 }
 
 bool
@@ -142,14 +143,14 @@
 fiber::cancel()
 {
         if ( ! info_base_) throw fiber_moved();
- scheduler::cancel( get_id() );
+ info_base_->st->cancel( get_id() );
 }
 
 void
 fiber::join()
 {
         if ( ! info_base_) throw fiber_moved();
- scheduler::join( get_id() );
+ info_base_->st->join( get_id() );
 }
 
 }}

Modified: sandbox/fiber/libs/fiber/src/fiber_posix.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/fiber_posix.cpp (original)
+++ sandbox/fiber/libs/fiber/src/fiber_posix.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -60,7 +60,7 @@
 void
 fiber::switch_to_( fiber & to)
 {
- if ( ! info_base_) throw fiber_moved();
+ if ( ! info_base_ || ! to.info_base_) throw fiber_moved();
 
         if ( ::swapcontext( & info_base_->uctx, & to.info_base_->uctx) != 0)
                 throw system::system_error(

Modified: sandbox/fiber/libs/fiber/src/fiber_windows.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/fiber_windows.cpp (original)
+++ sandbox/fiber/libs/fiber/src/fiber_windows.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -57,7 +57,7 @@
 void
 fiber::switch_to_( fiber & to)
 {
- if ( ! info_base_) throw fiber_moved();
+ if ( ! info_base_ || ! to.info_base_) throw fiber_moved();
 
         ::SwitchToFiber( to.info_base_->uctx);
 }

Modified: sandbox/fiber/libs/fiber/src/round_robin.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/round_robin.cpp (original)
+++ sandbox/fiber/libs/fiber/src/round_robin.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -4,14 +4,14 @@
 // (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-#include <boost/fiber/detail/round_robin.hpp>
+#include <boost/fiber/round_robin.hpp>
 
+#include <memory>
 #include <utility>
 
 #include <boost/assert.hpp>
 #include <boost/foreach.hpp>
 
-#include <boost/fiber/detail/fiber_info.hpp>
 #include <boost/fiber/detail/move.hpp>
 #include <boost/fiber/detail/fiber_state.hpp>
 #include <boost/fiber/exceptions.hpp>
@@ -20,67 +20,26 @@
 
 namespace boost {
 namespace fibers {
-namespace detail {
-
-#define SET_STATE_NOT_STARTED( f) \
- f.info_()->state = STATE_NOT_STARTED;
-
-#define SET_STATE_READY( f) \
- f.info_()->state = STATE_READY;
-
-#define SET_STATE_RUNNING( f) \
- f.info_()->state = STATE_RUNNING;
-
-#define SET_STATE_WAIT_FOR_JOIN( f) \
- f.info_()->state = STATE_WAIT_FOR_JOIN;
-
-#define SET_STATE_TERMINATED( f) \
- f.info_()->state = STATE_TERMINATED
-
-#define IN_STATE_MASTER( f) \
- ( f.info_()->state == STATE_MASTER)
-
-#define IN_STATE_NOT_STARTED( f) \
- ( f.info_()->state == STATE_NOT_STARTED)
-
-#define IN_STATE_READY( f) \
- ( f.info_()->state == STATE_READY)
-
-#define IN_STATE_RUNNING( f) \
- ( f.info_()->state == STATE_RUNNING)
-
-#define IN_STATE_WAIT_FOR_JOIN( f) \
- ( f.info_()->state == STATE_WAIT_FOR_JOIN)
-
-#define IN_STATE_TERMINATED( f) \
- ( f.info_()->state == STATE_TERMINATED)
 
 round_robin::round_robin() :
- master_(),
- active_(),
         fibers_(),
         runnable_fibers_(),
         terminated_fibers_()
-{
- fiber::convert_thread_to_fiber();
- master_ = fiber(
- fiber_info_base::ptr_t(
- new fiber_info_default() ) );
-}
-
-round_robin::~round_robin()
-{ fiber::convert_fiber_to_thread(); }
+{}
 
 void
-round_robin::add( fiber const& f)
+round_robin::add( fiber f)
 {
         if ( ! f) throw fiber_moved();
 
- BOOST_ASSERT( ! IN_STATE_MASTER( f) );
- BOOST_ASSERT( IN_STATE_NOT_STARTED( f) );
+ BOOST_ASSERT( ! is_master( f) );
+ BOOST_ASSERT( in_state_not_started( f) );
 
         // set state to ready
- SET_STATE_READY( f);
+ set_state_ready( f);
+
+ // attach to this scheduler
+ attach( f);
 
         // insert fiber to fiber-list
         std::pair< std::map< fiber::id, schedulable >::iterator, bool > result(
@@ -96,171 +55,24 @@
         runnable_fibers_.push_back( result.first->first);
 }
 
-fiber::id
-round_robin::get_id() const
-{
- BOOST_ASSERT( IN_STATE_RUNNING( active_) );
-// BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- return active_.get_id();
-}
-
 void
-round_robin::yield()
+round_robin::yield( fiber::id const& id)
 {
- BOOST_ASSERT( IN_STATE_RUNNING( active_) );
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
+ BOOST_ASSERT( active_fiber->get_id() == id);
+ BOOST_ASSERT( in_state_running( ( * active_fiber) ) );
+ BOOST_ASSERT( ! fibers_[active_fiber->get_id()].waiting_on);
 
         // set state ready
- SET_STATE_READY( active_);
+ set_state_ready( ( * active_fiber) );
 
         // put fiber to runnable-queue
- runnable_fibers_.push_back( active_.get_id() );
+ runnable_fibers_.push_back( id);
 
         // switch to master-fiber
- active_.switch_to_( master_);
+ switch_between( * active_fiber, master_fiber);
 }
 
 void
-round_robin::cancel()
-{
- BOOST_ASSERT( IN_STATE_RUNNING( active_) );
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- schedulable s( fibers_[active_.get_id()]);
- // invoke each fiber waiting on this fiber
- BOOST_FOREACH( fiber::id id__, s.joining_fibers)
- {
- schedulable s__( fibers_[id__]);
- fiber f__( s__.f);
- BOOST_ASSERT( s__.waiting_on);
- BOOST_ASSERT( active_.get_id() == * s__.waiting_on);
- BOOST_ASSERT( IN_STATE_WAIT_FOR_JOIN( f__) );
-
- // clear waiting-on
- fibers_[id__].waiting_on.reset();
-
- // put fiber on runnable-queue
- SET_STATE_READY( f__);
- runnable_fibers_.push_back( id__);
- }
- // clear waiting-queue
- fibers_[active_.get_id()].joining_fibers.clear();
-
- // set state to terminated
- SET_STATE_TERMINATED( active_);
-
- // put fiber to terminated-queue
- terminated_fibers_.push( active_.get_id() );
-
- // switch to master-fiber
- active_.switch_to_( master_);
-}
-
-void
-round_robin::interrupt()
-{
- BOOST_ASSERT( IN_STATE_RUNNING( active_) );
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- // gets invoked by interruption-points
- // if interruption flag is set throw fiber_interrupted
- // exceptions
- if ( INTERRUPTION_ENABLED == active_.info_()->interrupt)
- throw fiber_interrupted();
-}
-
-bool
-round_robin::interruption_requested() const
-{
- BOOST_ASSERT( IN_STATE_RUNNING( active_) );
-// BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- return active_.interruption_requested();
-}
-
-bool
-round_robin::interruption_enabled() const
-{
- BOOST_ASSERT( IN_STATE_RUNNING( active_) );
-// BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- return active_.info_()->interrupt == detail::INTERRUPTION_ENABLED;
-}
-
-fiber_interrupt_t &
-round_robin::interrupt_flags()
-{
- BOOST_ASSERT( IN_STATE_RUNNING( active_) );
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- return active_.info_()->interrupt;
-}
-
-int
-round_robin::priority() const
-{
- BOOST_ASSERT( IN_STATE_RUNNING( active_) );
-// BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- return active_.priority();
-}
-
-void
-round_robin::priority( int prio)
-{
- BOOST_ASSERT( IN_STATE_RUNNING( active_) );
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- // set priority
- active_.priority( prio);
-}
-
-void
-round_robin::at_exit( callable_t ca)
-{
- BOOST_ASSERT( IN_STATE_RUNNING( active_) );
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- // push a exit-callback on fibers stack
- active_.info_()->at_exit.push( ca);
-}
-
-void
-round_robin::interrupt( fiber::id const& id)
-{
- container::iterator i = fibers_.find( id);
- if ( i == fibers_.end() ) return;
- schedulable s( i->second);
- fiber f( s.f);
- BOOST_ASSERT( f);
- BOOST_ASSERT( ! IN_STATE_MASTER( f) );
- BOOST_ASSERT( ! IN_STATE_NOT_STARTED( f) );
-
- // nothing to do for al terminated fiber
- if ( IN_STATE_TERMINATED( f) ) return;
-
- // remove disabled flag
- f.info_()->interrupt &= ~detail::INTERRUPTION_DISABLED;
-
- // set enabled flag
- f.info_()->interrupt |= detail::INTERRUPTION_ENABLED;
-
- // if fiber is waiting
- if ( IN_STATE_WAIT_FOR_JOIN( f) )
- {
- // fiber is waiting (joining) on another fiber
- // remove it from the waiting-queue, reset waiting-on
- // and reset the waiting state
- BOOST_ASSERT( s.waiting_on);
- fibers_[* s.waiting_on].joining_fibers.remove( id);
- fibers_[id].waiting_on.reset();
- SET_STATE_READY( f);
- runnable_fibers_.push_back( id);
- }
-}
-
-void
 round_robin::cancel( fiber::id const& id)
 {
         container::iterator i = fibers_.find( id);
@@ -268,11 +80,11 @@
         schedulable s( i->second);
         fiber f( s.f);
         BOOST_ASSERT( f);
- BOOST_ASSERT( ! IN_STATE_MASTER( f) );
- BOOST_ASSERT( ! IN_STATE_NOT_STARTED( f) );
+ BOOST_ASSERT( ! is_master( f) );
+ BOOST_ASSERT( ! in_state_not_started( f) );
 
         // nothing to do for al terminated fiber
- if ( IN_STATE_TERMINATED( f) ) return;
+ if ( in_state_terminated( f) ) return;
 
         // invoke each fiber waiting on this fiber
         BOOST_FOREACH( fiber::id id__, s.joining_fibers)
@@ -280,13 +92,13 @@
                 schedulable s__( fibers_[id__]);
                 fiber f__( s__.f);
                 BOOST_ASSERT( s__.waiting_on);
- BOOST_ASSERT( IN_STATE_WAIT_FOR_JOIN( f__) );
+ BOOST_ASSERT( in_state_wait_for_join( f__) );
 
                 // clear waiting-on
                 fibers_[id__].waiting_on.reset();
 
                 // put fiber on runnable-queue
- SET_STATE_READY( f__);
+ set_state_ready( f__);
                 runnable_fibers_.push_back( id__);
         }
         // clear waiting-queue
@@ -294,28 +106,29 @@
 
         // if fiber is ready remove it from the runnable-queue
         // and put it to terminated-queue
- if ( IN_STATE_READY( f) )
+ if ( in_state_ready( f) )
         {
- SET_STATE_TERMINATED( f);
+ set_state_terminated( f);
                 runnable_fibers_.remove( id);
                 terminated_fibers_.push( id);
         }
         // if fiber is running (== active fiber)
+ // reset active fiber
         // put it to terminated-queue and switch
         // to master fiber
- else if ( IN_STATE_RUNNING( f) )
+ else if ( in_state_running( f) )
         {
- BOOST_ASSERT( active_.get_id() == id);
- SET_STATE_TERMINATED( f);
+ BOOST_ASSERT( active_fiber->get_id() == id);
+ set_state_terminated( f);
                 terminated_fibers_.push( id);
- f.switch_to_( master_);
+ switch_between( f, master_fiber);
         }
         // if fiber is waiting then remove it from the
         // waiting-queue and put it to terminated-queue
- else if ( IN_STATE_WAIT_FOR_JOIN( f) )
+ else if ( in_state_wait_for_join( f) )
         {
                 BOOST_ASSERT( s.waiting_on);
- SET_STATE_TERMINATED( f);
+ set_state_terminated( f);
                 fibers_[* s.waiting_on].joining_fibers.remove( id);
                 terminated_fibers_.push( id);
         }
@@ -331,48 +144,77 @@
         schedulable s( i->second);
         fiber f( s.f);
         BOOST_ASSERT( f);
- BOOST_ASSERT( ! IN_STATE_MASTER( f) );
- BOOST_ASSERT( ! IN_STATE_NOT_STARTED( f) );
+ BOOST_ASSERT( ! is_master( f) );
+ BOOST_ASSERT( ! in_state_not_started( f) );
 
         // nothing to do for a terminated fiber
- if ( IN_STATE_TERMINATED( f) ) return;
+ if ( in_state_terminated( f) ) return;
 
         // prevent self-join
- if ( active_.get_id() == id) throw scheduler_error("self-join denied");
+ if ( active_fiber->get_id() == id)
+ throw scheduler_error("self-join denied");
 
         // register on fiber to be joined
- fibers_[id].joining_fibers.push_back( active_.get_id() );
+ fibers_[id].joining_fibers.push_back( active_fiber->get_id() );
 
         // set state waiting
- SET_STATE_WAIT_FOR_JOIN( active_);
+ set_state_wait_for_join( ( * active_fiber) );
 
         // set fiber-id waiting-on
- fibers_[active_.get_id()].waiting_on = id;
+ fibers_[active_fiber->get_id()].waiting_on = id;
 
         // switch to master-fiber
- active_.switch_to_( master_);
+ switch_between( * active_fiber, master_fiber);
 
         // fiber returned
- BOOST_ASSERT( IN_STATE_RUNNING( active_) );
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
+ BOOST_ASSERT( in_state_running( ( * active_fiber) ) );
+ BOOST_ASSERT( ! fibers_[active_fiber->get_id()].waiting_on);
 
         // check if interruption was requested
- interrupt();
+ if ( interruption_enabled( * active_fiber) )
+ throw fiber_interrupted();
 }
 
 void
+round_robin::interrupt( fiber::id const& id)
+{
+ container::iterator i = fibers_.find( id);
+ if ( i == fibers_.end() ) return;
+ schedulable s( i->second);
+ fiber f( s.f);
+ BOOST_ASSERT( f);
+ BOOST_ASSERT( ! is_master( f) );
+ BOOST_ASSERT( ! in_state_not_started( f) );
+
+ // nothing to do for al terminated fiber
+ if ( in_state_terminated( f) ) return;
+
+ enable_interruption( f);
+
+ // if fiber is waiting
+ if ( in_state_wait_for_join( f) )
+ {
+ // fiber is waiting (joining) on another fiber
+ // remove it from the waiting-queue, reset waiting-on
+ // and reset the waiting state
+ BOOST_ASSERT( s.waiting_on);
+ fibers_[* s.waiting_on].joining_fibers.remove( id);
+ fibers_[id].waiting_on.reset();
+ set_state_ready( f);
+ runnable_fibers_.push_back( id);
+ }
+}
+
+void
 round_robin::reschedule( fiber::id const& id)
 {
         container::iterator i = fibers_.find( id);
         if ( i == fibers_.end() ) return;
         fiber f( i->second.f);
         BOOST_ASSERT( f);
- BOOST_ASSERT( ! IN_STATE_MASTER( f) );
- BOOST_ASSERT( ! IN_STATE_NOT_STARTED( f) );
- BOOST_ASSERT( ! IN_STATE_TERMINATED( f) );
-
- // TODO: re-schedule fiber == remove from
- // runnable_fibers + re-insert
+ BOOST_ASSERT( ! is_master( f) );
+ BOOST_ASSERT( ! in_state_not_started( f) );
+ BOOST_ASSERT( ! in_state_terminated( f) );
 }
 
 bool
@@ -382,16 +224,16 @@
         if ( ! runnable_fibers_.empty() )
         {
                 schedulable s = fibers_[runnable_fibers_.front()];
- active_ = s.f;
+ std::auto_ptr< fiber > orig( active_fiber.release() );
+ active_fiber.reset( new fiber( s.f) );
                 BOOST_ASSERT( ! s.waiting_on);
- BOOST_ASSERT( IN_STATE_READY( active_) );
- SET_STATE_RUNNING( active_);
- master_.switch_to_( active_);
+ BOOST_ASSERT( in_state_ready( ( * active_fiber) ) );
+ set_state_running( ( * active_fiber) );
+ switch_between( master_fiber, * active_fiber);
+ active_fiber.reset( orig.release() );
                 runnable_fibers_.pop_front();
                 result = true;
         }
- else
- active_.move();
 
         while ( ! terminated_fibers_.empty() )
         {
@@ -399,7 +241,7 @@
                 fiber f( s.f);
                 terminated_fibers_.pop();
                 BOOST_ASSERT( s.joining_fibers.empty() );
- BOOST_ASSERT( IN_STATE_TERMINATED( f) );
+ BOOST_ASSERT( in_state_terminated( f) );
                 fibers_.erase( f.get_id() );
                 result = true;
         }
@@ -407,25 +249,13 @@
 }
 
 bool
-round_robin::empty() const
+round_robin::empty()
 { return fibers_.empty(); }
 
 std::size_t
-round_robin::size() const
+round_robin::size()
 { return fibers_.size(); }
 
-#undef IN_STATE_MASTER
-#undef IN_STATE_NOT_STARTED
-#undef IN_STATE_READY
-#undef IN_STATE_RUNNING
-#undef IN_STATE_WAIT_FOR_JOIN
-#undef IN_STATE_TERMINATED
-#undef SET_STATE_NOT_STARTED
-#undef SET_STATE_READY
-#undef SET_STATE_RUNNING
-#undef SET_STATE_WAIT_FOR_JOIN
-#undef SET_STATE_TERMINATED
-
-}}}
+}}
 
 #include <boost/config/abi_suffix.hpp>

Deleted: sandbox/fiber/libs/fiber/src/scheduler.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/scheduler.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
+++ (empty file)
@@ -1,165 +0,0 @@
-
-// Copyright Oliver Kowalke 2009.
-// 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)
-
-#include <boost/fiber/scheduler.hpp>
-
-#include <boost/fiber/detail/move.hpp>
-#include <boost/fiber/detail/round_robin.hpp>
-#include <boost/fiber/exceptions.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost {
-namespace fibers {
-
-scheduler::impl_t scheduler::impl_;
-
-bool
-scheduler::runs_as_fiber()
-{ return impl_.get() != 0; }
-
-fiber::id
-scheduler::get_id()
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- return impl->get_id();
-}
-
-void
-scheduler::yield()
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->yield();
-}
-
-void
-scheduler::cancel()
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->cancel();
-}
-
-void
-scheduler::interrupt()
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->interrupt();
-}
-
-bool
-scheduler::interruption_requested()
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- return impl->interruption_requested();
-}
-
-bool
-scheduler::interruption_enabled()
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- return impl->interruption_enabled();
-}
-
-detail::fiber_interrupt_t &
-scheduler::interrupt_flags()
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- return impl->interrupt_flags();
-}
-
-int
-scheduler::priority()
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- return impl->priority();
-}
-
-void
-scheduler::priority( int prio)
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->priority( prio);
-}
-
-void
-scheduler::at_exit( callable_t ca)
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->at_exit( ca);
-}
-
-void
-scheduler::interrupt( fiber::id const& id)
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->interrupt( id);
-}
-
-void
-scheduler::cancel( fiber::id const& id)
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->cancel( id);
-}
-
-void
-scheduler::join( fiber::id const& id)
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->join( id);
-}
-
-void
-scheduler::reschedule( fiber::id const& id)
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->reschedule( id);
-}
-
-detail::strategy *
-scheduler::access_()
-{
- if ( ! impl_.get() )
- impl_.reset( new detail::round_robin() );
- return impl_.get();
-}
-
-scheduler::~scheduler()
-{ impl_.reset(); }
-
-bool
-scheduler::run()
-{ return access_()->run(); }
-
-bool
-scheduler::empty()
-{ return access_()->empty(); }
-
-std::size_t
-scheduler::size()
-{ return access_()->size(); }
-
-void
-scheduler::submit_fiber( fiber f)
-{ access_()->add( f); }
-
-}}
-
-#include <boost/config/abi_suffix.hpp>

Added: sandbox/fiber/libs/fiber/src/strategy.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/strategy.cpp 2009-11-28 06:46:10 EST (Sat, 28 Nov 2009)
@@ -0,0 +1,173 @@
+#include <boost/fiber/strategy.hpp>
+
+#include <boost/assert.hpp>
+
+#include <boost/fiber/detail/fiber_info.hpp>
+#include <boost/fiber/detail/fiber_info_base.hpp>
+#include <boost/fiber/exceptions.hpp>
+
+namespace boost {
+namespace fibers {
+
+strategy::active_fiber_t strategy::active_fiber;
+
+bool
+strategy::runs_as_fiber()
+{ return active_fiber.get() != 0; }
+
+fiber::id
+strategy::get_id()
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ return active->get_id();
+}
+
+void
+strategy::interruption_point()
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ if ( active->info_()->interrupt == detail::INTERRUPTION_ENABLED)
+ throw fiber_interrupted();
+}
+
+bool
+strategy::interruption_requested()
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ return active->interruption_requested();
+}
+
+detail::fiber_interrupt_t &
+strategy::interrupt_flags()
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ return active->info_()->interrupt;
+}
+
+bool
+strategy::interruption_enabled()
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ return active->info_()->interrupt & detail::INTERRUPTION_ENABLED;
+}
+
+int
+strategy::priority()
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ return active->priority();
+}
+
+void
+strategy::priority( int prio)
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ active->priority( prio);
+}
+
+void
+strategy::at_fiber_exit( callable_t ca)
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ active->info_()->at_exit.push( ca);
+}
+
+void
+strategy::yield()
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ active->info_()->st->yield( active->get_id() );
+}
+
+void
+strategy::cancel()
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ active->info_()->st->cancel( active->get_id() );
+}
+
+strategy::strategy() :
+ master_fiber()
+{
+ fiber::convert_thread_to_fiber();
+ master_fiber = fiber(
+ detail::fiber_info_base::ptr_t(
+ new detail::fiber_info_default() ) );
+}
+
+strategy::~strategy()
+{ fiber::convert_fiber_to_thread(); }
+
+void
+strategy::attach( fiber & f)
+{ f.info_()->st = this; }
+
+void
+strategy::switch_between( fiber & from, fiber & to)
+{ from.switch_to_( to); }
+
+void
+strategy::enable_interruption( fiber & f)
+{
+ // remove disabled flag
+ f.info_()->interrupt &= ~detail::INTERRUPTION_DISABLED;
+
+ // set enabled flag
+ f.info_()->interrupt |= detail::INTERRUPTION_ENABLED;
+}
+
+bool
+strategy::interruption_enabled( fiber const& f)
+{ return detail::INTERRUPTION_ENABLED == f.info_()->interrupt; }
+
+bool
+strategy::is_master( fiber const& f)
+{ return master_fiber == f; }
+
+bool
+strategy::in_state_not_started( fiber const& f)
+{ return detail::STATE_NOT_STARTED == f.info_()->state; }
+
+bool
+strategy::in_state_ready( fiber const& f)
+{ return detail::STATE_READY == f.info_()->state; }
+
+bool
+strategy::in_state_running( fiber const& f)
+{ return detail::STATE_RUNNING == f.info_()->state; }
+
+bool
+strategy::in_state_wait_for_join( fiber const& f)
+{ return detail::STATE_WAIT_FOR_JOIN == f.info_()->state; }
+
+bool
+strategy::in_state_terminated( fiber const& f)
+{ return detail::STATE_TERMINATED == f.info_()->state; }
+
+void
+strategy::set_state_ready( fiber & f)
+{ f.info_()->state = detail::STATE_READY; }
+
+void
+strategy::set_state_running( fiber & f)
+{ f.info_()->state = detail::STATE_RUNNING; }
+
+void
+strategy::set_state_wait_for_join( fiber & f)
+{ f.info_()->state = detail::STATE_WAIT_FOR_JOIN; }
+
+void
+strategy::set_state_terminated( fiber & f)
+{ f.info_()->state = detail::STATE_TERMINATED; }
+
+}}


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