$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r58228 - in sandbox/fiber: boost boost/fiber libs/fiber/build libs/fiber/src libs/fiber/test
From: oliver.kowalke_at_[hidden]
Date: 2009-12-07 15:49:42
Author: olli
Date: 2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
New Revision: 58228
URL: http://svn.boost.org/trac/boost/changeset/58228
Log:
- introduction of spinning sync. objects (spin_mutex, spin_condition, ...)
- non-spinning sync. objects (mutex, condition,...) take scheduler as argument in ctor
- tests added and adapted
Added:
   sandbox/fiber/boost/fiber/spin_auto_reset_event.hpp   (contents, props changed)
   sandbox/fiber/boost/fiber/spin_condition.hpp   (contents, props changed)
   sandbox/fiber/boost/fiber/spin_count_down_event.hpp   (contents, props changed)
   sandbox/fiber/boost/fiber/spin_manual_reset_event.hpp   (contents, props changed)
   sandbox/fiber/boost/fiber/spin_mutex.hpp   (contents, props changed)
   sandbox/fiber/libs/fiber/src/spin_auto_reset_event.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/src/spin_condition.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/src/spin_count_down_event.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/src/spin_manual_reset_event.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/src/spin_mutex.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/test/test_lock.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/test/test_spin_auto_reset_event.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/test/test_spin_condition.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/test/test_spin_count_down_event.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/test/test_spin_lock.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/test/test_spin_manual_reset_event.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/test/test_spin_mutex.cpp   (contents, props changed)
Text files modified: 
   sandbox/fiber/boost/fiber.hpp                             |     5 +++                                     
   sandbox/fiber/boost/fiber/auto_reset_event.hpp            |    13 ++++++++                                
   sandbox/fiber/boost/fiber/condition.hpp                   |    13 ++++++++                                
   sandbox/fiber/boost/fiber/count_down_event.hpp            |    11 +++++++                                 
   sandbox/fiber/boost/fiber/manual_reset_event.hpp          |    15 ++++++++++                              
   sandbox/fiber/boost/fiber/mutex.hpp                       |    10 ++++++                                  
   sandbox/fiber/boost/fiber/round_robin.hpp                 |     4 +-                                      
   sandbox/fiber/boost/fiber/scheduler.hpp                   |    44 +++++++++++++++++--------------         
   sandbox/fiber/boost/fiber/strategy.hpp                    |    25 ++++++++---------                       
   sandbox/fiber/libs/fiber/build/Jamfile.v2                 |    10 +++++++                                 
   sandbox/fiber/libs/fiber/src/auto_reset_event.cpp         |    15 ++--------                              
   sandbox/fiber/libs/fiber/src/condition.cpp                |    18 ++----------                            
   sandbox/fiber/libs/fiber/src/count_down_event.cpp         |    14 ++--------                              
   sandbox/fiber/libs/fiber/src/manual_reset_event.cpp       |    17 ++----------                            
   sandbox/fiber/libs/fiber/src/mutex.cpp                    |    12 ++------                                
   sandbox/fiber/libs/fiber/src/round_robin.cpp              |     4 +-                                      
   sandbox/fiber/libs/fiber/src/strategy.cpp                 |    46 ---------------------------------       
   sandbox/fiber/libs/fiber/test/Jamfile.v2                  |    18 ++++++++----                            
   sandbox/fiber/libs/fiber/test/test_auto_reset_event.cpp   |     6 ++--                                    
   sandbox/fiber/libs/fiber/test/test_condition.cpp          |    12 ++++----                                
   sandbox/fiber/libs/fiber/test/test_count_down_event.cpp   |     4 +-                                      
   sandbox/fiber/libs/fiber/test/test_manual_reset_event.cpp |     8 ++--                                    
   sandbox/fiber/libs/fiber/test/test_mutex.cpp              |    54 +++++++++++---------------------------- 
   23 files changed, 172 insertions(+), 206 deletions(-)
Modified: sandbox/fiber/boost/fiber.hpp
==============================================================================
--- sandbox/fiber/boost/fiber.hpp	(original)
+++ sandbox/fiber/boost/fiber.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -17,6 +17,11 @@
 #include <boost/fiber/manual_reset_event.hpp>
 #include <boost/fiber/mutex.hpp>
 #include <boost/fiber/scheduler.hpp>
+#include <boost/fiber/spin_auto_reset_event.hpp>
+#include <boost/fiber/spin_condition.hpp>
+#include <boost/fiber/spin_count_down_event.hpp>
+#include <boost/fiber/spin_manual_reset_event.hpp>
+#include <boost/fiber/spin_mutex.hpp>
 #include <boost/fiber/unbounded_fifo.hpp>
 #include <boost/fiber/utility.hpp>
 
Modified: sandbox/fiber/boost/fiber/auto_reset_event.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/auto_reset_event.hpp	(original)
+++ sandbox/fiber/boost/fiber/auto_reset_event.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -11,6 +11,8 @@
 #include <boost/utility.hpp>
 
 #include <boost/fiber/object/id.hpp>
+#include <boost/fiber/scheduler.hpp>
+#include <boost/fiber/strategy.hpp>
 
 namespace boost {
 namespace fibers {
@@ -26,9 +28,18 @@
 
         volatile uint32_t	state_;
         object::id			id_;
+	strategy::ptr_t		strategy_;
 
 public:
-	explicit auto_reset_event( bool = false);
+	template< typename Strategy >
+	auto_reset_event( scheduler< Strategy > & sched, bool isset = false) :
+		state_(
+			isset ?
+			static_cast< uint32_t >( SET) :
+			static_cast< uint32_t >( RESET) ),
+		id_( * this),
+		strategy_( sched.strategy_)
+	{ strategy_->register_object( id_); }
 
         ~auto_reset_event();
 
Modified: sandbox/fiber/boost/fiber/condition.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/condition.hpp	(original)
+++ sandbox/fiber/boost/fiber/condition.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -15,6 +15,8 @@
 #include <boost/fiber/object/id.hpp>
 #include <boost/fiber/exceptions.hpp>
 #include <boost/fiber/mutex.hpp>
+#include <boost/fiber/scheduler.hpp>
+#include <boost/fiber/strategy.hpp>
 
 namespace boost {
 namespace fibers {
@@ -34,11 +36,20 @@
         mutex				enter_mtx_;
         mutex				check_mtx_;
         object::id			id_;
+	strategy::ptr_t		strategy_;
 
         void wait_( mutex &);
 
 public:
-	condition();
+	template< typename Strategy >
+	condition( scheduler< Strategy > & sched) :
+		cmd_( static_cast< uint32_t >( SLEEPING) ),
+		waiters_( 0),
+		enter_mtx_( sched),
+		check_mtx_( sched),
+		id_( * this),
+		strategy_( sched.strategy_)
+	{ strategy_->register_object( id_); }
 
         ~condition();
 
Modified: sandbox/fiber/boost/fiber/count_down_event.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/count_down_event.hpp	(original)
+++ sandbox/fiber/boost/fiber/count_down_event.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -12,6 +12,8 @@
 
 #include <boost/fiber/object/id.hpp>
 #include <boost/fiber/mutex.hpp>
+#include <boost/fiber/scheduler.hpp>
+#include <boost/fiber/strategy.hpp>
 
 namespace boost {
 namespace fibers {
@@ -22,9 +24,16 @@
         uint32_t			initial_;
         volatile uint32_t	current_;
         object::id			id_;
+	strategy::ptr_t		strategy_;
 
 public:
-	explicit count_down_event( uint32_t);
+	template< typename Strategy >
+	count_down_event( scheduler< Strategy > & sched, uint32_t initial) :
+		initial_( initial),
+		current_( initial_),
+		id_( * this),
+		strategy_( sched.strategy_)
+	{ strategy_->register_object( id_); }
 
         ~count_down_event();
 
Modified: sandbox/fiber/boost/fiber/manual_reset_event.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/manual_reset_event.hpp	(original)
+++ sandbox/fiber/boost/fiber/manual_reset_event.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -12,6 +12,8 @@
 
 #include <boost/fiber/object/id.hpp>
 #include <boost/fiber/mutex.hpp>
+#include <boost/fiber/scheduler.hpp>
+#include <boost/fiber/strategy.hpp>
 
 namespace boost {
 namespace fibers {
@@ -29,9 +31,20 @@
         volatile uint32_t	waiters_;
         mutex				enter_mtx_;
         object::id			id_;
+	strategy::ptr_t		strategy_;
 
 public:
-	explicit manual_reset_event( bool = false);
+	template< typename Strategy >
+	manual_reset_event( scheduler< Strategy > & sched, bool isset = false) :
+		state_(
+			isset ?
+				static_cast< uint32_t >( SET) :
+				static_cast< uint32_t >( RESET) ),
+		waiters_( 0),
+		enter_mtx_( sched),
+		id_( * this),
+		strategy_( sched.strategy_)
+	{ strategy_->register_object( id_); }
 
         ~manual_reset_event();
 
Modified: sandbox/fiber/boost/fiber/mutex.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/mutex.hpp	(original)
+++ sandbox/fiber/boost/fiber/mutex.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -14,6 +14,8 @@
 #include <boost/utility.hpp>
 
 #include <boost/fiber/object/id.hpp>
+#include <boost/fiber/scheduler.hpp>
+#include <boost/fiber/strategy.hpp>
 
 namespace boost {
 namespace fibers {
@@ -23,11 +25,17 @@
 private:
         volatile uint32_t	state_;
         object::id			id_;
+	strategy::ptr_t		strategy_;
 
 public:
         typedef unique_lock< mutex >			scoped_lock;
 
-	mutex();
+	template< typename Strategy >
+	mutex( scheduler< Strategy > & sched) :
+		state_( 0),
+		id_( * this),
+		strategy_( sched.strategy_)
+	{ strategy_->register_object( id_); }
 
         ~mutex();
 
Modified: sandbox/fiber/boost/fiber/round_robin.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/round_robin.hpp	(original)
+++ sandbox/fiber/boost/fiber/round_robin.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -53,16 +53,16 @@
                 {}
         };
 
-	typedef std::map< fiber::id, schedulable >		fiber_map;
         typedef std::list< fiber::id >					fiber_id_list;
         typedef std::map< object::id, fiber_id_list >	object_map;
+	typedef std::map< fiber::id, schedulable >		fiber_map;
         typedef std::list< fiber::id >					runnable_queue;
         typedef std::queue< fiber::id >					terminated_queue;
 
         fiber_map			fibers_;
+	object_map			objects_;
         runnable_queue		runnable_fibers_;
         terminated_queue	terminated_fibers_;
-	object_map			objects_;
 
 public:
         round_robin();
Modified: sandbox/fiber/boost/fiber/scheduler.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/scheduler.hpp	(original)
+++ sandbox/fiber/boost/fiber/scheduler.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -11,7 +11,7 @@
 #include <memory>
 
 #include <boost/preprocessor/repetition.hpp>
-#include <boost/thread/tss.hpp>
+#include <boost/intrusive_ptr.hpp>
 #include <boost/utility.hpp>
 
 #include <boost/fiber/detail/config.hpp>
@@ -29,49 +29,53 @@
 namespace boost {
 namespace fibers {
 
+class auto_reset_event;
+class condition;
+class count_down_event;
+class manual_reset_event;
+class mutex;
+
 template< typename Strategy = round_robin >
 class BOOST_FIBER_DECL scheduler : private noncopyable
 {
 private:
+	friend class auto_reset_event;
+	friend class condition;
+	friend class count_down_event;
+	friend class manual_reset_event;
+	friend class mutex;
 
-	typedef thread_specific_ptr< strategy >	impl_t;
-
-	impl_t	impl_;
+	typedef intrusive_ptr< strategy >	strategy_t;
 
-	strategy * access_()
-	{
-		if ( ! impl_.get() )
-			impl_.reset( new Strategy() );
-		return impl_.get();
-	}
+	strategy_t	strategy_;
 
 public:
         scheduler() :
-		impl_()
+		strategy_( new Strategy() )
         {}
 
         ~scheduler()
-	{ impl_.reset(); }
+	{} 
 
         bool run()
-	{ return access_()->run(); }
+	{ return strategy_->run(); }
 
         bool empty()
-	{ return access_()->empty(); }
+	{ return strategy_->empty(); }
 
         std::size_t size()
-	{ return access_()->size(); }
+	{ return strategy_->size(); }
 
         void submit_fiber( fiber f)
-	{ access_()->add( f); }
+	{ strategy_->add( f); }
 
         template< typename Fn >
         void make_fiber( Fn fn)
-	{ access_()->add( fiber( fn) ); }
+	{ strategy_->add( fiber( fn) ); }
 
         template< typename Fn >
         void make_fiber( std::size_t stack_size, Fn fn)
-	{ access_()->add( fiber( stack_size, fn) ); }
+	{ strategy_->add( fiber( stack_size, fn) ); }
 
 #ifndef BOOST_FIBER_MAX_ARITY
 #define BOOST_FIBER_MAX_ARITY 10
@@ -84,10 +88,10 @@
 #define BOOST_FIBER_MAKE_FIBER_FUNCTION(z, n, unused) \
         template< typename Fn, BOOST_PP_ENUM_PARAMS(n, typename A) > \
         void make_fiber( Fn fn, BOOST_ENUM_FIBER_ARGS(n)) \
-	{ access_()->add( fiber( fn, BOOST_PP_ENUM_PARAMS(n, a) ) ); } \
+	{ strategy_->add( fiber( fn, BOOST_PP_ENUM_PARAMS(n, a) ) ); } \
         template< typename Fn, BOOST_PP_ENUM_PARAMS(n, typename A) > \
         void make_fiber( std::size_t stack_size, Fn fn, BOOST_ENUM_FIBER_ARGS(n)) \
-	{ access_()->add( fiber( stack_size, fn, BOOST_PP_ENUM_PARAMS(n, a) ) ); }
+	{ strategy_->add( fiber( stack_size, fn, BOOST_PP_ENUM_PARAMS(n, a) ) ); }
 
 BOOST_PP_REPEAT_FROM_TO( 1, BOOST_FIBER_MAX_ARITY, BOOST_FIBER_MAKE_FIBER_FUNCTION, ~)
 
Added: sandbox/fiber/boost/fiber/spin_auto_reset_event.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/spin_auto_reset_event.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,39 @@
+
+//          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_SPIN_AUTO_RESET_EVENT_H
+#define BOOST_FIBERS_SPIN_AUTO_RESET_EVENT_H
+
+#include <boost/cstdint.hpp>
+#include <boost/utility.hpp>
+
+namespace boost {
+namespace fibers {
+
+class spin_auto_reset_event : private noncopyable
+{
+private:
+	enum state_t
+	{
+		RESET = 0,
+		SET
+	};
+
+	volatile uint32_t	state_;
+
+public:
+	explicit spin_auto_reset_event( bool = false);
+
+	void set();
+
+	void wait();
+
+	bool try_wait();
+};
+
+}}
+
+#endif // BOOST_FIBERS_SPIN_AUTO_RESET_EVENT_H
Added: sandbox/fiber/boost/fiber/spin_condition.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/spin_condition.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,71 @@
+
+//          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)
+//
+//  based on boost::interprocess::sync::interprocess_spin_condition
+
+#ifndef BOOST_FIBERS_SPIN_CONDITION_H
+#define BOOST_FIBERS_SPIN_CONDITION_H
+
+#include <boost/cstdint.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/exceptions.hpp>
+#include <boost/fiber/spin_mutex.hpp>
+
+namespace boost {
+namespace fibers {
+
+class spin_condition : private noncopyable
+{
+private:
+	enum command_t
+	{
+		SLEEPING = 0,
+		NOTIFY_ONE,
+		NOTIFY_ALL
+	};
+
+	volatile uint32_t	cmd_;
+	volatile uint32_t	waiters_;
+	spin_mutex				enter_mtx_;
+	spin_mutex				check_mtx_;
+
+	void wait_( spin_mutex &);
+
+	void notify_( uint32_t);
+
+public:
+	spin_condition();
+
+	void notify_one();
+
+	void notify_all();
+
+	template< typename Lock >
+	void wait( Lock & lk)
+	{
+		if ( ! lk)
+			throw lock_error();
+		wait_( * lk.mutex() );
+	}
+
+	template<
+		typename Lock,
+		typename Pred
+	>
+	void wait( Lock & lk, Pred pred)
+	{
+		if ( ! lk)
+			throw lock_error();
+
+		while ( ! pred() )
+			wait_( * lk.mutex() );
+	}
+};
+
+}}
+
+#endif // BOOST_FIBERS_SPIN_CONDITION_H
Added: sandbox/fiber/boost/fiber/spin_count_down_event.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/spin_count_down_event.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,38 @@
+
+//          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_SPIN_COUNT_DOWN_EVENT_H
+#define BOOST_FIBERS_SPIN_COUNT_DOWN_EVENT_H
+
+#include <boost/cstdint.hpp>
+#include <boost/utility.hpp>
+
+namespace boost {
+namespace fibers {
+
+class spin_count_down_event : private noncopyable
+{
+private:
+	uint32_t			initial_;
+	volatile uint32_t	current_;
+
+public:
+	explicit spin_count_down_event( uint32_t);
+
+	uint32_t initial() const;
+
+	uint32_t current() const;
+
+	bool is_set() const;
+
+	void set();
+
+	void wait();
+};
+
+}}
+
+#endif // BOOST_FIBERS_SPIN_COUNT_DOWN_EVENT_H
Added: sandbox/fiber/boost/fiber/spin_manual_reset_event.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/spin_manual_reset_event.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,45 @@
+
+//          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_SPIN_MANUAL_RESET_EVENT_H
+#define BOOST_FIBERS_SPIN_MANUAL_RESET_EVENT_H
+
+#include <boost/cstdint.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/spin_mutex.hpp>
+
+namespace boost {
+namespace fibers {
+
+class spin_manual_reset_event : private noncopyable
+{
+private:
+	enum state_t
+	{
+		RESET = 0,
+		SET
+	};
+
+	volatile uint32_t	state_;
+	volatile uint32_t	waiters_;
+	spin_mutex				enter_mtx_;
+
+public:
+	explicit spin_manual_reset_event( bool = false);
+
+	void set();
+
+	void reset();
+
+	void wait();
+
+	bool try_wait();
+};
+
+}}
+
+#endif // BOOST_FIBERS_SPIN_MANUAL_RESET_EVENT_H
Added: sandbox/fiber/boost/fiber/spin_mutex.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/spin_mutex.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,40 @@
+
+//          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)
+//
+//  based on boost::interprocess::sync::interprocess_spin_mutex
+
+#ifndef BOOST_FIBERS_SPIN_MUTEX_H
+#define BOOST_FIBERS_SPIN_MUTEX_H
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/utility.hpp>
+
+namespace boost {
+namespace fibers {
+
+class spin_mutex : private noncopyable
+{
+private:
+	volatile uint32_t	state_;
+
+public:
+	typedef unique_lock< spin_mutex >	scoped_lock;
+
+	spin_mutex();
+
+	void lock();
+
+	bool try_lock();
+
+	void unlock();
+};
+
+typedef spin_mutex try_spin_mutex;
+
+}}
+
+#endif // BOOST_FIBERS_SPIN_MUTEX_H
Modified: sandbox/fiber/boost/fiber/strategy.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/strategy.hpp	(original)
+++ sandbox/fiber/boost/fiber/strategy.hpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -8,10 +8,9 @@
 #define BOOST_FIBERS_STRATEGY_H
 
 #include <cstddef>
-#include <list>
-#include <map>
 
 #include <boost/function.hpp>
+#include <boost/intrusive_ptr.hpp>
 #include <boost/thread/tss.hpp>
 
 #include <boost/fiber/detail/interrupt_flags.hpp>
@@ -80,7 +79,7 @@
         friend class manual_reset_event;
         friend class mutex;
 
-	typedef function< void() >				callable_t;
+	typedef function< void() >						callable_t;
 
         static bool runs_as_fiber_();
 
@@ -104,20 +103,12 @@
 
         static void cancel_();
 
-	static void register_object_( object::id const&);
-
-	static void unregister_object_( object::id const&);
-
-	static void wait_for_object_( object::id const&);
-
-	static void object_notify_one_( object::id const&);
-
-	static void object_notify_all_( object::id const&);
+	uint32_t	use_count_;
 
 protected:
         typedef thread_specific_ptr< fiber >			fiber_t;
 
-	static fiber_t	active_fiber;
+	static fiber_t		active_fiber;
 
         fiber			master_fiber;
 
@@ -156,6 +147,8 @@
         void set_state_terminated( fiber &);
 
 public:
+	typedef intrusive_ptr< strategy >	ptr_t;
+
         strategy();
 
         virtual ~strategy();
@@ -187,6 +180,12 @@
         virtual bool empty() = 0;
 
         virtual std::size_t size() = 0;
+
+	inline friend void intrusive_ptr_add_ref( strategy * p)
+	{ ++p->use_count_; }
+	
+	inline friend void intrusive_ptr_release( strategy * p)
+	{ if ( --p->use_count_ == 0) delete p; }
 };
 
 }}
Modified: sandbox/fiber/libs/fiber/build/Jamfile.v2
==============================================================================
--- sandbox/fiber/libs/fiber/build/Jamfile.v2	(original)
+++ sandbox/fiber/libs/fiber/build/Jamfile.v2	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -50,6 +50,11 @@
         manual_reset_event.cpp
         mutex.cpp
         round_robin.cpp
+	spin_auto_reset_event.cpp
+	spin_condition.cpp
+	spin_count_down_event.cpp
+	spin_manual_reset_event.cpp
+	spin_mutex.cpp
         strategy.cpp
     : ## requirements ##
       <fiberapi>win32
@@ -66,6 +71,11 @@
         manual_reset_event.cpp
         mutex.cpp
         round_robin.cpp
+	spin_auto_reset_event.cpp
+	spin_condition.cpp
+	spin_count_down_event.cpp
+	spin_manual_reset_event.cpp
+	spin_mutex.cpp
         strategy.cpp
     : ## requirements ##
       <fiberapi>posix
Modified: sandbox/fiber/libs/fiber/src/auto_reset_event.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/auto_reset_event.cpp	(original)
+++ sandbox/fiber/libs/fiber/src/auto_reset_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -7,27 +7,18 @@
 #include "boost/fiber/auto_reset_event.hpp"
 
 #include <boost/fiber/detail/atomic.hpp>
-#include <boost/fiber/strategy.hpp>
 
 namespace boost {
 namespace fibers {
 
-auto_reset_event::auto_reset_event( bool isset) :
-	state_(
-		isset ?
-		static_cast< uint32_t >( SET) :
-		static_cast< uint32_t >( RESET) ),
-	id_( * this)
-{ strategy::register_object_( id_); }
-
 auto_reset_event::~auto_reset_event()
-{ strategy::unregister_object_( id_); }
+{ strategy_->unregister_object( id_); }
 
 void
 auto_reset_event::set()
 {
         detail::atomic_exchange( & state_, static_cast< uint32_t >( SET) );
-	strategy::object_notify_one_( id_);
+	strategy_->object_notify_one( id_);
 }
 
 void
@@ -38,7 +29,7 @@
                         & state_, & expected,
                         static_cast< uint32_t >( RESET) ) )
         {
-		strategy::wait_for_object_( id_);
+		strategy_->wait_for_object( id_);
                 expected = static_cast< uint32_t >( SET);
         }
 }
Modified: sandbox/fiber/libs/fiber/src/condition.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/condition.cpp	(original)
+++ sandbox/fiber/libs/fiber/src/condition.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -10,8 +10,6 @@
 #include <boost/thread.hpp>
 
 #include <boost/fiber/detail/atomic.hpp>
-#include <boost/fiber/mutex.hpp>
-#include <boost/fiber/strategy.hpp>
 #include <boost/fiber/utility.hpp>
 
 namespace boost {
@@ -31,7 +29,7 @@
         for (;;)
         {
                 while ( static_cast< uint32_t >( SLEEPING) == detail::atomic_load( & cmd_) )
-			strategy::wait_for_object_( id_);
+			strategy_->wait_for_object( id_);
 
                 mutex::scoped_lock lk( check_mtx_);
                 BOOST_ASSERT( lk);
@@ -68,16 +66,8 @@
         mtx.lock();
 }
 
-condition::condition() :
-	cmd_( static_cast< uint32_t >( SLEEPING) ),
-	waiters_( 0),
-	enter_mtx_(),
-	check_mtx_(),
-	id_( * this)
-{ strategy::register_object_( id_); }
-
 condition::~condition()
-{ strategy::unregister_object_( id_); }
+{ strategy_->unregister_object( id_); }
 
 void
 condition::notify_one()
@@ -96,7 +86,7 @@
                                 & cmd_, & expected, cmd) )
                 this_fiber::yield();
         
-	strategy::object_notify_one_( id_);
+	strategy_->object_notify_one( id_);
 }
 
 void
@@ -116,7 +106,7 @@
                                 & cmd_, & expected, cmd) )
                 this_fiber::yield();
 
-	strategy::object_notify_all_( id_);
+	strategy_->object_notify_all( id_);
 }
 
 }}
Modified: sandbox/fiber/libs/fiber/src/count_down_event.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/count_down_event.cpp	(original)
+++ sandbox/fiber/libs/fiber/src/count_down_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -7,20 +7,12 @@
 #include "boost/fiber/count_down_event.hpp"
 
 #include <boost/fiber/detail/atomic.hpp>
-#include <boost/fiber/mutex.hpp>
-#include <boost/fiber/strategy.hpp>
 
 namespace boost {
 namespace fibers {
 
-count_down_event::count_down_event( uint32_t initial) :
-	initial_( initial),
-	current_( initial_),
-	id_( * this)
-{ strategy::register_object_( id_); }
-
 count_down_event::~count_down_event()
-{ strategy::unregister_object_( id_); }
+{ strategy_->unregister_object( id_); }
 
 uint32_t
 count_down_event::initial() const
@@ -46,14 +38,14 @@
                         break;
         }
         if ( 0 == detail::atomic_load( & current_) )
-		strategy::object_notify_all_( id_);
+		strategy_->object_notify_all( id_);
 }
 
 void
 count_down_event::wait()
 {
         while ( 0 != detail::atomic_load( & current_) )
-		strategy::wait_for_object_( id_);
+		strategy_->wait_for_object( id_);
 }
 
 }}
Modified: sandbox/fiber/libs/fiber/src/manual_reset_event.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/manual_reset_event.cpp	(original)
+++ sandbox/fiber/libs/fiber/src/manual_reset_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -9,23 +9,12 @@
 #include <boost/assert.hpp>
 
 #include <boost/fiber/detail/atomic.hpp>
-#include <boost/fiber/strategy.hpp>
 
 namespace boost {
 namespace fibers {
 
-manual_reset_event::manual_reset_event( bool isset) :
-	state_(
-		isset ?
-			static_cast< uint32_t >( SET) :
-			static_cast< uint32_t >( RESET) ),
-	waiters_( 0),
-	enter_mtx_(),
-	id_( * this)
-{ strategy::register_object_( id_); }
-
 manual_reset_event::~manual_reset_event()
-{ strategy::unregister_object_( id_); }
+{ strategy_->unregister_object( id_); }
 
 void
 manual_reset_event::set()
@@ -39,7 +28,7 @@
                 ! detail::atomic_load( & waiters_ ) )
                 enter_mtx_.unlock();
         else
-		strategy::object_notify_all_( id_);
+		strategy_->object_notify_all( id_);
 }
 
 void
@@ -62,7 +51,7 @@
         }
 
         while ( static_cast< uint32_t >( RESET) == detail::atomic_load( & state_) )
-		strategy::wait_for_object_( id_);
+		strategy_->wait_for_object( id_);
 
         if ( 1 == detail::atomic_fetch_sub( & waiters_, 1) )
                 enter_mtx_.unlock();
Modified: sandbox/fiber/libs/fiber/src/mutex.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/mutex.cpp	(original)
+++ sandbox/fiber/libs/fiber/src/mutex.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -7,18 +7,12 @@
 #include <boost/fiber/mutex.hpp>
 
 #include <boost/fiber/detail/atomic.hpp>
-#include <boost/fiber/strategy.hpp>
 
 namespace boost {
 namespace fibers {
 
-mutex::mutex() :
-	state_( 0),
-	id_( * this)
-{ strategy::register_object_( id_); }
-
 mutex::~mutex()
-{ strategy::unregister_object_( id_); }
+{ strategy_->unregister_object( id_); }
 
 void
 mutex::lock()
@@ -29,7 +23,7 @@
                 if ( detail::atomic_compare_exchange_strong( & state_, & expected, 1) )
                         break;
                 else
-			strategy::wait_for_object_( id_);
+			strategy_->wait_for_object( id_);
         }
 }
 
@@ -44,7 +38,7 @@
 mutex::unlock()
 {
         detail::atomic_exchange( & state_, 0);
-	strategy::object_notify_one_( id_);
+	strategy_->object_notify_one( id_);
 }
 
 }}
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-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -22,9 +22,9 @@
 
 round_robin::round_robin() :
         fibers_(),
+	objects_(),
         runnable_fibers_(),
-	terminated_fibers_(),
-	objects_()
+	terminated_fibers_()
 {}
 
 round_robin::~round_robin()
Added: sandbox/fiber/libs/fiber/src/spin_auto_reset_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/spin_auto_reset_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,48 @@
+
+//          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/spin_auto_reset_event.hpp"
+
+#include <boost/fiber/detail/atomic.hpp>
+#include <boost/fiber/utility.hpp>
+
+namespace boost {
+namespace fibers {
+
+spin_auto_reset_event::spin_auto_reset_event( bool isset) :
+	state_(
+		isset ?
+		static_cast< uint32_t >( SET) :
+		static_cast< uint32_t >( RESET) )
+{}
+
+void
+spin_auto_reset_event::set()
+{ detail::atomic_exchange( & state_, static_cast< uint32_t >( SET) ); }
+
+void
+spin_auto_reset_event::wait()
+{
+	uint32_t expected = static_cast< uint32_t >( SET);
+	while ( ! detail::atomic_compare_exchange_strong(
+			& state_, & expected,
+			static_cast< uint32_t >( RESET) ) )
+	{
+		this_fiber::yield();
+		expected = static_cast< uint32_t >( SET);
+	}
+}
+
+bool
+spin_auto_reset_event::try_wait()
+{
+	uint32_t expected = static_cast< uint32_t >( SET);
+	return detail::atomic_compare_exchange_strong(
+			& state_, & expected,
+			static_cast< uint32_t >( RESET) );
+}
+
+}}
Added: sandbox/fiber/libs/fiber/src/spin_condition.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/spin_condition.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,102 @@
+
+//          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/spin_condition.hpp"
+
+#include <boost/assert.hpp>
+#include <boost/thread.hpp>
+
+#include <boost/fiber/detail/atomic.hpp>
+#include <boost/fiber/spin_mutex.hpp>
+#include <boost/fiber/utility.hpp>
+
+namespace boost {
+namespace fibers {
+
+void
+spin_condition::notify_( uint32_t cmd)
+{
+	enter_mtx_.lock();
+
+	if ( 0 == detail::atomic_load( & waiters_) )
+	{
+		enter_mtx_.unlock();
+		return;
+	}
+
+	uint32_t expected = static_cast< uint32_t >( SLEEPING);
+	while ( ! detail::atomic_compare_exchange_strong(
+				& cmd_, & expected, cmd) )
+		this_fiber::yield();	
+}
+
+void
+spin_condition::wait_( spin_mutex & mtx)
+{
+	{
+		spin_mutex::scoped_lock lk( enter_mtx_);
+		BOOST_ASSERT( lk);
+		detail::atomic_fetch_add( & waiters_, 1);
+		mtx.unlock();
+	}
+
+	bool unlock_enter_mtx = false;
+	for (;;)
+	{
+		while ( static_cast< uint32_t >( SLEEPING) == detail::atomic_load( & cmd_) )
+			this_fiber::yield();	
+
+		spin_mutex::scoped_lock lk( check_mtx_);
+		BOOST_ASSERT( lk);
+
+		uint32_t expected = static_cast< uint32_t >( NOTIFY_ONE);
+		detail::atomic_compare_exchange_strong(
+				& cmd_, & expected,
+				static_cast< uint32_t >( SLEEPING) );
+		if ( static_cast< uint32_t >( SLEEPING) == expected)
+			continue;
+		else if ( static_cast< uint32_t >( NOTIFY_ONE) == expected)
+		{
+			unlock_enter_mtx = true;
+			detail::atomic_fetch_sub( & waiters_, 1);
+			break;
+		}
+		else
+		{
+			unlock_enter_mtx = 1 == detail::atomic_fetch_sub( & waiters_, 1);
+			if ( unlock_enter_mtx)
+			{
+				expected = static_cast< uint32_t >( NOTIFY_ALL);
+				detail::atomic_compare_exchange_strong(
+						& cmd_, & expected,
+						static_cast< uint32_t >( SLEEPING) );
+			}
+			break;
+		}
+	}
+
+	if ( unlock_enter_mtx)
+		enter_mtx_.unlock();
+
+	mtx.lock();
+}
+
+spin_condition::spin_condition() :
+	cmd_( static_cast< uint32_t >( SLEEPING) ),
+	waiters_( 0),
+	enter_mtx_(),
+	check_mtx_()
+{}
+
+void
+spin_condition::notify_one()
+{ notify_( static_cast< uint32_t >( NOTIFY_ONE) ); }
+
+void
+spin_condition::notify_all()
+{ notify_( static_cast< uint32_t >( NOTIFY_ALL) ); }
+
+}}
Added: sandbox/fiber/libs/fiber/src/spin_count_down_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/spin_count_down_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,53 @@
+
+//          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/spin_count_down_event.hpp"
+
+#include <boost/fiber/detail/atomic.hpp>
+#include <boost/fiber/spin_mutex.hpp>
+#include <boost/fiber/utility.hpp>
+
+namespace boost {
+namespace fibers {
+
+spin_count_down_event::spin_count_down_event( uint32_t initial) :
+	initial_( initial),
+	current_( initial_)
+{}
+
+uint32_t
+spin_count_down_event::initial() const
+{ return initial_; }
+
+uint32_t
+spin_count_down_event::current() const
+{ return detail::atomic_load( & current_); }
+
+bool
+spin_count_down_event::is_set() const
+{ return 0 == detail::atomic_load( & current_); }
+
+void
+spin_count_down_event::set()
+{
+	for (;;)
+	{
+		if ( 0 == detail::atomic_load( & current_) )
+			return;
+		uint32_t expected = current_;
+		if ( detail::atomic_compare_exchange_strong( & current_, & expected, expected - 1) )
+			return;
+	}
+}
+
+void
+spin_count_down_event::wait()
+{
+	while ( 0 != detail::atomic_load( & current_) )
+		this_fiber::yield();	
+}
+
+}}
Added: sandbox/fiber/libs/fiber/src/spin_manual_reset_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/spin_manual_reset_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,82 @@
+
+//          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/spin_manual_reset_event.hpp"
+
+#include <boost/assert.hpp>
+
+#include <boost/fiber/detail/atomic.hpp>
+#include <boost/fiber/utility.hpp>
+
+namespace boost {
+namespace fibers {
+
+spin_manual_reset_event::spin_manual_reset_event( bool isset) :
+	state_(
+		isset ?
+			static_cast< uint32_t >( SET) :
+			static_cast< uint32_t >( RESET) ),
+	waiters_( 0),
+	enter_mtx_()
+{}
+
+void
+spin_manual_reset_event::set()
+{
+	enter_mtx_.lock();
+
+	uint32_t expected = static_cast< uint32_t >( RESET);
+	if ( ! detail::atomic_compare_exchange_strong(
+			& state_, & expected,
+			static_cast< uint32_t >( SET) ) ||
+		! detail::atomic_load( & waiters_ ) )
+		enter_mtx_.unlock();
+}
+
+void
+spin_manual_reset_event::reset()
+{
+	spin_mutex::scoped_lock lk( enter_mtx_);
+	BOOST_ASSERT( lk);
+
+	detail::atomic_exchange( & state_,
+		static_cast< uint32_t >( RESET) );
+}
+
+void
+spin_manual_reset_event::wait()
+{
+	{
+		spin_mutex::scoped_lock lk( enter_mtx_);
+		BOOST_ASSERT( lk);
+		detail::atomic_fetch_add( & waiters_, 1);
+	}
+
+	while ( static_cast< uint32_t >( RESET) == detail::atomic_load( & state_) )
+		this_fiber::yield();	
+
+	if ( 1 == detail::atomic_fetch_sub( & waiters_, 1) )
+		enter_mtx_.unlock();
+}
+
+bool
+spin_manual_reset_event::try_wait()
+{
+	{
+		spin_mutex::scoped_lock lk( enter_mtx_);
+		BOOST_ASSERT( lk);
+		detail::atomic_fetch_add( & waiters_, 1);
+	}
+
+	bool result = static_cast< uint32_t >( SET) == detail::atomic_load( & state_);
+
+	if ( 1 == detail::atomic_fetch_sub( & waiters_, 1) )
+		enter_mtx_.unlock();
+
+	return result;
+}
+
+}}
Added: sandbox/fiber/libs/fiber/src/spin_mutex.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/spin_mutex.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,43 @@
+
+//          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/spin_mutex.hpp>
+
+#include <boost/fiber/detail/atomic.hpp>
+#include <boost/fiber/utility.hpp>
+
+namespace boost {
+namespace fibers {
+
+spin_mutex::spin_mutex() :
+	state_( 0)
+{}
+
+void
+spin_mutex::lock()
+{
+	for (;;)
+	{
+		uint32_t expected = 0;
+		if ( detail::atomic_compare_exchange_strong( & state_, & expected, 1) )
+			break;
+		else
+			this_fiber::yield();	
+	}
+}
+
+bool
+spin_mutex::try_lock()
+{
+	uint32_t expected = 0;
+	return detail::atomic_compare_exchange_strong( & state_, & expected, 1);
+}
+
+void
+spin_mutex::unlock()
+{ detail::atomic_exchange( & state_, 0); }
+
+}}
Modified: sandbox/fiber/libs/fiber/src/strategy.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/strategy.cpp	(original)
+++ sandbox/fiber/libs/fiber/src/strategy.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -101,52 +101,8 @@
         active->info_()->st->cancel( active_fiber->get_id() );
 }
 
-void
-strategy::register_object_( object::id const& oid)
-{
-	fiber * active( active_fiber.get() );
-	if ( ! active) throw fiber_error("not a fiber");
-	if ( ! active->info_()->st) throw scheduler_error("no valid scheduler");
-	active->info_()->st->register_object( oid);
-}
-
-void
-strategy::unregister_object_( object::id const& oid)
-{
-	fiber * active( active_fiber.get() );
-	if ( ! active) throw fiber_error("not a fiber");
-	if ( ! active->info_()->st) throw scheduler_error("no valid scheduler");
-	active->info_()->st->unregister_object( oid);
-}
-
-void
-strategy::wait_for_object_( object::id const& oid)
-{
-	fiber * active( active_fiber.get() );
-	if ( ! active) throw fiber_error("not a fiber");
-	if ( ! active->info_()->st) throw scheduler_error("no valid scheduler");
-	active->info_()->st->wait_for_object( oid);
-}
-
-void
-strategy::object_notify_one_( object::id const& oid)
-{
-	fiber * active( active_fiber.get() );
-	if ( ! active) throw fiber_error("not a fiber");
-	if ( ! active->info_()->st) throw scheduler_error("no valid scheduler");
-	active->info_()->st->object_notify_one( oid);
-}
-
-void
-strategy::object_notify_all_( object::id const& oid)
-{
-	fiber * active( active_fiber.get() );
-	if ( ! active) throw fiber_error("not a fiber");
-	if ( ! active->info_()->st) throw scheduler_error("no valid scheduler");
-	active->info_()->st->object_notify_all( oid);
-}
-
 strategy::strategy() :
+	use_count_( 0),
         master_fiber()
 {
         fiber::convert_thread_to_fiber();
Modified: sandbox/fiber/libs/fiber/test/Jamfile.v2
==============================================================================
--- sandbox/fiber/libs/fiber/test/Jamfile.v2	(original)
+++ sandbox/fiber/libs/fiber/test/Jamfile.v2	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -33,10 +33,16 @@
     [ fiber-test test_join ]
     [ fiber-test test_interrupt ]
     [ fiber-test test_at_exit ]
-#   [ fiber-test test_mutex ]
-#   [ fiber-test test_auto_reset_event ]
-#   [ fiber-test test_manual_reset_event ]
-#   [ fiber-test test_count_down_event ]
-#   [ fiber-test test_unique_lock ]
-#   [ fiber-test test_condition ]
+    [ fiber-test test_mutex ]
+    [ fiber-test test_lock ]
+    [ fiber-test test_auto_reset_event ]
+    [ fiber-test test_manual_reset_event ]
+    [ fiber-test test_count_down_event ]
+    [ fiber-test test_condition ]
+    [ fiber-test test_spin_mutex ]
+    [ fiber-test test_spin_lock ]
+    [ fiber-test test_spin_auto_reset_event ]
+    [ fiber-test test_spin_manual_reset_event ]
+    [ fiber-test test_spin_count_down_event ]
+    [ fiber-test test_spin_condition ]
     ;
Modified: sandbox/fiber/libs/fiber/test/test_auto_reset_event.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_auto_reset_event.cpp	(original)
+++ sandbox/fiber/libs/fiber/test/test_auto_reset_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -32,8 +32,8 @@
 void test_case_1()
 {
         value = 0;
-	boost::fibers::auto_reset_event ev;
         boost::fibers::scheduler<> sched;
+	boost::fibers::auto_reset_event ev( sched);
 
         sched.make_fiber(
                 wait_fn,
@@ -70,8 +70,8 @@
 void test_case_2()
 {
         value = 0;
-	boost::fibers::auto_reset_event ev( true);
         boost::fibers::scheduler<> sched;
+	boost::fibers::auto_reset_event ev( sched, true);
 
         sched.make_fiber(
                 wait_fn,
@@ -101,8 +101,8 @@
 
 void test_case_3()
 {
-	boost::fibers::auto_reset_event ev;
         boost::fibers::scheduler<> sched;
+	boost::fibers::auto_reset_event ev( sched);
 
         BOOST_CHECK_EQUAL( false, ev.try_wait() );
 
Modified: sandbox/fiber/libs/fiber/test/test_condition.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_condition.cpp	(original)
+++ sandbox/fiber/libs/fiber/test/test_condition.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -44,9 +44,9 @@
 void test_case_1()
 {
         value = 0;
-	boost::fibers::mutex mtx;
-	boost::fibers::condition cond;
         boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx( sched);
+	boost::fibers::condition cond( sched);
 
         sched.make_fiber(
                 wait_fn,
@@ -88,9 +88,9 @@
 void test_case_2()
 {
         value = 0;
-	boost::fibers::mutex mtx;
-	boost::fibers::condition cond;
         boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx( sched);
+	boost::fibers::condition cond( sched);
 
         sched.make_fiber(
                 wait_fn,
@@ -150,9 +150,9 @@
 void test_case_3()
 {
         value = 0;
-	boost::fibers::mutex mtx;
-	boost::fibers::condition cond;
         boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx( sched);
+	boost::fibers::condition cond( sched);
 
         sched.make_fiber(
                 wait_fn,
Modified: sandbox/fiber/libs/fiber/test/test_count_down_event.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_count_down_event.cpp	(original)
+++ sandbox/fiber/libs/fiber/test/test_count_down_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -30,8 +30,8 @@
 void test_case_1()
 {
         boost::uint32_t n = 3;
-	boost::fibers::count_down_event ev( n);
         boost::fibers::scheduler<> sched;
+	boost::fibers::count_down_event ev( sched, n);
 
         BOOST_CHECK_EQUAL( ev.initial(), n);
         BOOST_CHECK_EQUAL( ev.current(), n);
@@ -57,8 +57,8 @@
 {
         value = 0;
         boost::uint32_t n = 3;
-	boost::fibers::count_down_event ev( n);
         boost::fibers::scheduler<> sched;
+	boost::fibers::count_down_event ev( sched, n);
 
         BOOST_CHECK_EQUAL( ev.initial(), n);
         BOOST_CHECK_EQUAL( ev.current(), n);
Added: sandbox/fiber/libs/fiber/test/test_lock.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/test/test_lock.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,209 @@
+
+//          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)
+//
+// This test is based on the tests of Boost.Thread 
+
+#include <cstdlib>
+#include <iostream>
+#include <map>
+#include <stdexcept>
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber.hpp>
+
+struct dummy_mutex
+{
+	bool is_locked;
+	
+	dummy_mutex() :
+	    is_locked( false)
+	{}
+	
+	void lock()
+	{ is_locked = true; }
+	
+	bool try_lock()
+	{
+	    if ( is_locked)
+	        return false;
+	    is_locked = true;
+	    return true;
+	}
+	
+	void unlock()
+	{ is_locked = false; }
+};
+
+void test_lock()
+{
+	boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx( sched);
+	boost::unique_lock< boost::fibers::mutex > lk( mtx);
+
+	BOOST_CHECK( lk);
+	BOOST_CHECK( lk.owns_lock() );
+
+	lk.unlock();
+
+	BOOST_CHECK( ! lk);
+	BOOST_CHECK( ! lk.owns_lock() );
+}
+
+void test_defer_lock()
+{
+	boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx( sched);
+	boost::unique_lock< boost::fibers::mutex > lk( mtx, boost::defer_lock);
+
+	BOOST_CHECK( ! lk);
+	BOOST_CHECK( ! lk.owns_lock() );
+
+	lk.lock();
+
+	BOOST_CHECK( lk);
+	BOOST_CHECK( lk.owns_lock() );
+}
+
+void test_adopt_lock()
+{
+	boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx( sched);
+	mtx.lock();
+	boost::unique_lock< boost::fibers::mutex > lk( mtx, boost::adopt_lock);
+
+	BOOST_CHECK( lk);
+	BOOST_CHECK( lk.owns_lock() );
+}
+
+void test_try_lock()
+{
+	boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx( sched);
+	boost::unique_lock< boost::fibers::mutex > lk( mtx, boost::defer_lock);
+
+	BOOST_CHECK( ! lk);
+	BOOST_CHECK( ! lk.owns_lock() );
+
+	lk.try_lock();
+
+	BOOST_CHECK( lk);
+	BOOST_CHECK( lk.owns_lock() );
+}
+
+void test_lock_twice()
+{
+	boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx( sched);
+	boost::unique_lock< boost::fibers::mutex > lk( mtx);
+
+	BOOST_CHECK_THROW( lk.lock(), boost::lock_error);
+}
+
+void test_try_lock_twice()
+{
+	boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx( sched);
+	boost::unique_lock< boost::fibers::mutex > lk( mtx);
+
+	BOOST_CHECK_THROW( lk.try_lock(), boost::lock_error);
+}
+
+void test_unlock_twice()
+{
+	boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx( sched);
+	boost::unique_lock< boost::fibers::mutex > lk( mtx);
+	lk.unlock();
+
+	BOOST_CHECK_THROW( lk.unlock(), boost::lock_error);
+}
+
+void test_default_ctor()
+{
+	boost::unique_lock< boost::fibers::mutex > lk;
+
+	BOOST_CHECK( ! lk);
+	BOOST_CHECK( ! lk.owns_lock() );
+}
+
+void test_lock_concept()
+{
+	boost::fibers::scheduler<> sched;
+    boost::fibers::mutex mtx1( sched), mtx2( sched), mtx3( sched);
+
+    boost::fibers::mutex::scoped_lock lk1( mtx1, boost::defer_lock),
+        lk2( mtx2, boost::defer_lock),
+        lk3( mtx3, boost::defer_lock);
+
+    BOOST_CHECK( ! lk1.owns_lock() );
+    BOOST_CHECK( ! lk2.owns_lock() );
+    BOOST_CHECK( ! lk3.owns_lock() );
+    
+    boost::lock( lk1, lk2, lk3);
+    
+    BOOST_CHECK( lk1.owns_lock() );
+    BOOST_CHECK( lk2.owns_lock() );
+    BOOST_CHECK( lk3.owns_lock() );
+}
+
+void test_try_lock_concept()
+{
+    dummy_mutex mtx1, mtx2;
+    mtx2.lock();
+
+    boost::unique_lock< dummy_mutex > lk1( mtx1, boost::defer_lock),
+        lk2( mtx2, boost::defer_lock);
+
+    int res = boost::try_lock( lk1, lk2);
+    
+    BOOST_CHECK( res == 1);
+    BOOST_CHECK( ! mtx1.is_locked);
+    BOOST_CHECK( mtx2.is_locked);
+    BOOST_CHECK( ! lk1.owns_lock() );
+    BOOST_CHECK( ! lk2.owns_lock() );
+}
+
+void test_swap()
+{
+	boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx1( sched), mtx2( sched);
+	
+	boost::unique_lock< boost::fibers::mutex > lk1( mtx1), lk2( mtx2);
+	
+	BOOST_CHECK_EQUAL( lk1.mutex(), & mtx1);
+	BOOST_CHECK_EQUAL( lk2.mutex(), & mtx2);
+	
+	lk1.swap( lk2);
+	
+	BOOST_CHECK_EQUAL( lk1.mutex(), & mtx2);
+	BOOST_CHECK_EQUAL( lk2.mutex(), & mtx1);
+}
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+    boost::unit_test_framework::test_suite * test =
+		BOOST_TEST_SUITE("Boost.Fiber: lock test suite");
+
+    test->add( BOOST_TEST_CASE( & test_lock) );
+    test->add( BOOST_TEST_CASE( & test_defer_lock) );
+    test->add( BOOST_TEST_CASE( & test_adopt_lock) );
+    test->add( BOOST_TEST_CASE( & test_try_lock) );
+    test->add( BOOST_TEST_CASE( & test_lock_twice) );
+    test->add( BOOST_TEST_CASE( & test_try_lock_twice) );
+    test->add( BOOST_TEST_CASE( & test_unlock_twice) );
+    test->add( BOOST_TEST_CASE( & test_default_ctor) );
+    test->add( BOOST_TEST_CASE( & test_lock_concept) );
+    test->add( BOOST_TEST_CASE( & test_try_lock_concept) );
+    test->add( BOOST_TEST_CASE( & test_swap) );
+
+	return test;
+}
Modified: sandbox/fiber/libs/fiber/test/test_manual_reset_event.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_manual_reset_event.cpp	(original)
+++ sandbox/fiber/libs/fiber/test/test_manual_reset_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -31,8 +31,8 @@
 void test_case_1()
 {
         value = 0;
-	boost::fibers::manual_reset_event ev;
         boost::fibers::scheduler<> sched;
+	boost::fibers::manual_reset_event ev( sched);
 
         sched.make_fiber(
                 wait_fn,
@@ -61,8 +61,8 @@
 void test_case_2()
 {
         value = 0;
-	boost::fibers::manual_reset_event ev;
         boost::fibers::scheduler<> sched;
+	boost::fibers::manual_reset_event ev( sched);
 
         sched.make_fiber(
                 wait_fn,
@@ -107,8 +107,8 @@
 void test_case_3()
 {
         value = 0;
-	boost::fibers::manual_reset_event ev( true);
         boost::fibers::scheduler<> sched;
+	boost::fibers::manual_reset_event ev( sched, true);
 
         sched.make_fiber(
                 wait_fn,
@@ -130,8 +130,8 @@
 
 void test_case_4()
 {
-	boost::fibers::manual_reset_event ev;
         boost::fibers::scheduler<> sched;
+	boost::fibers::manual_reset_event ev( sched);
 
         BOOST_CHECK_EQUAL( false, ev.try_wait() );
 
Modified: sandbox/fiber/libs/fiber/test/test_mutex.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_mutex.cpp	(original)
+++ sandbox/fiber/libs/fiber/test/test_mutex.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -27,35 +27,35 @@
     typedef M mutex_type;
     typedef typename M::scoped_lock lock_type;
 
-    void operator()()
+    void operator()( boost::fibers::scheduler<> & sched)
     {
-        mutex_type mutex;
+        mutex_type mtx( sched);
 
         // Test the lock's constructors.
         {
-            lock_type lock(mutex, boost::defer_lock);
-            BOOST_CHECK(!lock);
+            lock_type lk(mtx, boost::defer_lock);
+            BOOST_CHECK(!lk);
         }
-        lock_type lock(mutex);
-        BOOST_CHECK(lock ? true : false);
+        lock_type lk(mtx);
+        BOOST_CHECK(lk ? true : false);
 
         // Test the lock and unlock methods.
-        lock.unlock();
-        BOOST_CHECK(!lock);
-        lock.lock();
-        BOOST_CHECK(lock ? true : false);
+        lk.unlock();
+        BOOST_CHECK(!lk);
+        lk.lock();
+        BOOST_CHECK(lk ? true : false);
     }
 };
 
-void do_test_mutex()
+void do_test_mutex( boost::fibers::scheduler<> & sched)
 {
-    test_lock< boost::fibers::mutex >()();
+    test_lock< boost::fibers::mutex >()( sched);
 }
 
-void test_1()
+void test_case1()
 {
         boost::fibers::scheduler<> sched;
-    sched.make_fiber( & do_test_mutex);
+    sched.make_fiber( & do_test_mutex, boost::ref( sched) );
         sched.run();
 }
 
@@ -77,10 +77,10 @@
         ++value2;
 }
 
-void test_2()
+void test_case2()
 {
-	boost::fibers::mutex mtx;
         boost::fibers::scheduler<> sched;
+	boost::fibers::mutex mtx( sched);
     sched.make_fiber( & test_fn1, boost::ref( mtx) );
     sched.make_fiber( & test_fn2, boost::ref( mtx) );
 
@@ -115,28 +115,6 @@
         BOOST_CHECK_EQUAL( 2, value2);
 }
 
-void test_case1()
-{
-	boost::fibers::scheduler<> sched;
-    sched.make_fiber( & test_1);
-	for (;;)
-	{
-		while ( sched.run() );
-		if ( sched.empty() ) break;
-	}
-}
-
-void test_case2()
-{
-	boost::fibers::scheduler<> sched;
-    sched.make_fiber( & test_2);
-	for (;;)
-	{
-		while ( sched.run() );
-		if ( sched.empty() ) break;
-	}
-}
-
 boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
 {
     boost::unit_test_framework::test_suite * test =
Added: sandbox/fiber/libs/fiber/test/test_spin_auto_reset_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/test/test_spin_auto_reset_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,123 @@
+
+//          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 <cstdlib>
+#include <iostream>
+#include <map>
+#include <stdexcept>
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber.hpp>
+
+int value = 0;
+
+void wait_fn( boost::fibers::spin_auto_reset_event & ev)
+{
+	ev.wait();
+	++value;
+}
+
+// check wait
+void test_case_1()
+{
+	value = 0;
+	boost::fibers::spin_auto_reset_event ev;
+	boost::fibers::scheduler<> sched;
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( ev) );
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( ev) );
+
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	ev.set();
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value);
+
+	ev.set();
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value);
+}
+
+void test_case_2()
+{
+	value = 0;
+	boost::fibers::spin_auto_reset_event ev( true);
+	boost::fibers::scheduler<> sched;
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( ev) );
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( ev) );
+
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value);
+
+	ev.set();
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value);
+}
+
+void test_case_3()
+{
+	boost::fibers::spin_auto_reset_event ev;
+
+	BOOST_CHECK_EQUAL( false, ev.try_wait() );
+
+	ev.set();
+
+	BOOST_CHECK_EQUAL( true, ev.try_wait() );
+	BOOST_CHECK_EQUAL( false, ev.try_wait() );
+}
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+	boost::unit_test::test_suite * test =
+		BOOST_TEST_SUITE("Boost.Fiber: spin-auto-reset-event test suite");
+
+	test->add( BOOST_TEST_CASE( & test_case_1) );
+	test->add( BOOST_TEST_CASE( & test_case_2) );
+	test->add( BOOST_TEST_CASE( & test_case_3) );
+
+	return test;
+}
Added: sandbox/fiber/libs/fiber/test/test_spin_condition.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/test/test_spin_condition.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,228 @@
+
+//          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 <cstdlib>
+#include <iostream>
+#include <map>
+#include <stdexcept>
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber.hpp>
+
+int value = 0;
+
+void notify_one_fn( boost::fibers::spin_condition & cond)
+{
+	cond.notify_one();
+}
+
+void notify_all_fn( boost::fibers::spin_condition & cond)
+{
+	cond.notify_all();
+}
+
+void wait_fn(
+	boost::fibers::spin_mutex & mtx,
+	boost::fibers::spin_condition & cond)
+{
+	boost::fibers::spin_mutex::scoped_lock lk( mtx);
+	cond.wait( lk);
+	++value;
+}
+
+void test_case_1()
+{
+	value = 0;
+	boost::fibers::spin_mutex mtx;
+	boost::fibers::spin_condition cond;
+	boost::fibers::scheduler<> sched;
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( mtx),
+		boost::ref( cond) );
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	sched.make_fiber(
+		notify_one_fn,
+		boost::ref( cond) );
+
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value);
+}
+
+void test_case_2()
+{
+	value = 0;
+	boost::fibers::spin_mutex mtx;
+	boost::fibers::spin_condition cond;
+	boost::fibers::scheduler<> sched;
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( mtx),
+		boost::ref( cond) );
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( mtx),
+		boost::ref( cond) );
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	sched.make_fiber(
+		notify_one_fn,
+		boost::ref( cond) );
+
+	BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value);
+}
+
+void test_case_3()
+{
+	value = 0;
+	boost::fibers::spin_mutex mtx;
+	boost::fibers::spin_condition cond;
+	boost::fibers::scheduler<> sched;
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( mtx),
+		boost::ref( cond) );
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( mtx),
+		boost::ref( cond) );
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	sched.make_fiber(
+		notify_all_fn,
+		boost::ref( cond) );
+
+	BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 3), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value);
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( mtx),
+		boost::ref( cond) );
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value);
+
+	sched.make_fiber(
+		notify_all_fn,
+		boost::ref( cond) );
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+	BOOST_CHECK_EQUAL( 3, value);
+}
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+	boost::unit_test::test_suite * test =
+		BOOST_TEST_SUITE("Boost.Fiber: spin-condition test suite");
+
+	test->add( BOOST_TEST_CASE( & test_case_1) );
+	test->add( BOOST_TEST_CASE( & test_case_2) );
+	test->add( BOOST_TEST_CASE( & test_case_3) );
+
+	return test;
+}
Added: sandbox/fiber/libs/fiber/test/test_spin_count_down_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/test/test_spin_count_down_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 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)
+
+#include <cstdlib>
+#include <iostream>
+#include <map>
+#include <stdexcept>
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber.hpp>
+
+int value = 0;
+
+void wait_fn( boost::fibers::spin_count_down_event & ev)
+{
+	ev.wait();
+	++value;
+}
+
+void test_case_1()
+{
+	boost::uint32_t n = 3;
+	boost::fibers::spin_count_down_event ev( n);
+
+	BOOST_CHECK_EQUAL( ev.initial(), n);
+	BOOST_CHECK_EQUAL( ev.current(), n);
+
+	ev.set();
+	BOOST_CHECK_EQUAL( ev.initial(), n);
+	BOOST_CHECK_EQUAL( ev.current(), static_cast< boost::uint32_t >( 2) );
+
+	ev.set();
+	BOOST_CHECK_EQUAL( ev.initial(), n);
+	BOOST_CHECK_EQUAL( ev.current(), static_cast< boost::uint32_t >( 1) );
+
+	ev.set();
+	BOOST_CHECK_EQUAL( ev.initial(), n);
+	BOOST_CHECK_EQUAL( ev.current(), static_cast< boost::uint32_t >( 0) );
+
+	ev.set();
+	BOOST_CHECK_EQUAL( ev.initial(), n);
+	BOOST_CHECK_EQUAL( ev.current(), static_cast< boost::uint32_t >( 0) );
+}
+
+void test_case_2()
+{
+	value = 0;
+	boost::uint32_t n = 3;
+	boost::fibers::spin_count_down_event ev( n);
+	boost::fibers::scheduler<> sched;
+
+	BOOST_CHECK_EQUAL( ev.initial(), n);
+	BOOST_CHECK_EQUAL( ev.current(), n);
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( ev) );
+
+	for ( boost::uint32_t i = 0; i < n - 1; ++i)
+	{
+		ev.set();
+		BOOST_CHECK( sched.run() );
+		BOOST_CHECK( value != 1);
+	}
+	ev.set();
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( ev.initial(), n);
+	BOOST_CHECK_EQUAL( ev.current(), static_cast< boost::uint32_t >( 0) );
+	BOOST_CHECK_EQUAL( 1, value);
+}
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+	boost::unit_test::test_suite * test =
+		BOOST_TEST_SUITE("Boost.Task: spin-count-down-event test suite");
+
+	test->add( BOOST_TEST_CASE( & test_case_1) );
+	test->add( BOOST_TEST_CASE( & test_case_2) );
+
+	return test;
+}
Added: sandbox/fiber/libs/fiber/test/test_spin_lock.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/test/test_spin_lock.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,200 @@
+
+//          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)
+//
+// This test is based on the tests of Boost.Thread 
+
+#include <cstdlib>
+#include <iostream>
+#include <map>
+#include <stdexcept>
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber.hpp>
+
+struct dummy_mutex
+{
+	bool is_locked;
+	
+	dummy_mutex() :
+	    is_locked( false)
+	{}
+	
+	void lock()
+	{ is_locked = true; }
+	
+	bool try_lock()
+	{
+	    if ( is_locked)
+	        return false;
+	    is_locked = true;
+	    return true;
+	}
+	
+	void unlock()
+	{ is_locked = false; }
+};
+
+void test_lock()
+{
+	boost::fibers::spin_mutex mtx;
+	boost::unique_lock< boost::fibers::spin_mutex > lk( mtx);
+
+	BOOST_CHECK( lk);
+	BOOST_CHECK( lk.owns_lock() );
+
+	lk.unlock();
+
+	BOOST_CHECK( ! lk);
+	BOOST_CHECK( ! lk.owns_lock() );
+}
+
+void test_defer_lock()
+{
+	boost::fibers::spin_mutex mtx;
+	boost::unique_lock< boost::fibers::spin_mutex > lk( mtx, boost::defer_lock);
+
+	BOOST_CHECK( ! lk);
+	BOOST_CHECK( ! lk.owns_lock() );
+
+	lk.lock();
+
+	BOOST_CHECK( lk);
+	BOOST_CHECK( lk.owns_lock() );
+}
+
+void test_adopt_lock()
+{
+	boost::fibers::spin_mutex mtx;
+	mtx.lock();
+	boost::unique_lock< boost::fibers::spin_mutex > lk( mtx, boost::adopt_lock);
+
+	BOOST_CHECK( lk);
+	BOOST_CHECK( lk.owns_lock() );
+}
+
+void test_try_lock()
+{
+	boost::fibers::spin_mutex mtx;
+	boost::unique_lock< boost::fibers::spin_mutex > lk( mtx, boost::defer_lock);
+
+	BOOST_CHECK( ! lk);
+	BOOST_CHECK( ! lk.owns_lock() );
+
+	lk.try_lock();
+
+	BOOST_CHECK( lk);
+	BOOST_CHECK( lk.owns_lock() );
+}
+
+void test_lock_twice()
+{
+	boost::fibers::spin_mutex mtx;
+	boost::unique_lock< boost::fibers::spin_mutex > lk( mtx);
+
+	BOOST_CHECK_THROW( lk.lock(), boost::lock_error);
+}
+
+void test_try_lock_twice()
+{
+	boost::fibers::spin_mutex mtx;
+	boost::unique_lock< boost::fibers::spin_mutex > lk( mtx);
+
+	BOOST_CHECK_THROW( lk.try_lock(), boost::lock_error);
+}
+
+void test_unlock_twice()
+{
+	boost::fibers::spin_mutex mtx;
+	boost::unique_lock< boost::fibers::spin_mutex > lk( mtx);
+	lk.unlock();
+
+	BOOST_CHECK_THROW( lk.unlock(), boost::lock_error);
+}
+
+void test_default_ctor()
+{
+	boost::unique_lock< boost::fibers::spin_mutex > lk;
+
+	BOOST_CHECK( ! lk);
+	BOOST_CHECK( ! lk.owns_lock() );
+}
+
+void test_lock_concept()
+{
+    boost::fibers::spin_mutex mtx1, mtx2, mtx3;
+
+    boost::fibers::spin_mutex::scoped_lock lk1( mtx1, boost::defer_lock),
+        lk2( mtx2, boost::defer_lock),
+        lk3( mtx3, boost::defer_lock);
+
+    BOOST_CHECK( ! lk1.owns_lock() );
+    BOOST_CHECK( ! lk2.owns_lock() );
+    BOOST_CHECK( ! lk3.owns_lock() );
+    
+    boost::lock( lk1, lk2, lk3);
+    
+    BOOST_CHECK( lk1.owns_lock() );
+    BOOST_CHECK( lk2.owns_lock() );
+    BOOST_CHECK( lk3.owns_lock() );
+}
+
+void test_try_lock_concept()
+{
+    dummy_mutex mtx1, mtx2;
+    mtx2.lock();
+
+    boost::unique_lock< dummy_mutex > lk1( mtx1, boost::defer_lock),
+        lk2( mtx2, boost::defer_lock);
+
+    int res = boost::try_lock( lk1, lk2);
+    
+    BOOST_CHECK( res == 1);
+    BOOST_CHECK( ! mtx1.is_locked);
+    BOOST_CHECK( mtx2.is_locked);
+    BOOST_CHECK( ! lk1.owns_lock() );
+    BOOST_CHECK( ! lk2.owns_lock() );
+}
+
+void test_swap()
+{
+	boost::fibers::spin_mutex mtx1, mtx2;
+	
+	boost::unique_lock< boost::fibers::spin_mutex > lk1( mtx1), lk2( mtx2);
+	
+	BOOST_CHECK_EQUAL( lk1.mutex(), & mtx1);
+	BOOST_CHECK_EQUAL( lk2.mutex(), & mtx2);
+	
+	lk1.swap( lk2);
+	
+	BOOST_CHECK_EQUAL( lk1.mutex(), & mtx2);
+	BOOST_CHECK_EQUAL( lk2.mutex(), & mtx1);
+}
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+    boost::unit_test_framework::test_suite * test =
+		BOOST_TEST_SUITE("Boost.Fiber: lock test suite");
+
+    test->add( BOOST_TEST_CASE( & test_lock) );
+    test->add( BOOST_TEST_CASE( & test_defer_lock) );
+    test->add( BOOST_TEST_CASE( & test_adopt_lock) );
+    test->add( BOOST_TEST_CASE( & test_try_lock) );
+    test->add( BOOST_TEST_CASE( & test_lock_twice) );
+    test->add( BOOST_TEST_CASE( & test_try_lock_twice) );
+    test->add( BOOST_TEST_CASE( & test_unlock_twice) );
+    test->add( BOOST_TEST_CASE( & test_default_ctor) );
+    test->add( BOOST_TEST_CASE( & test_lock_concept) );
+    test->add( BOOST_TEST_CASE( & test_try_lock_concept) );
+    test->add( BOOST_TEST_CASE( & test_swap) );
+
+	return test;
+}
Added: sandbox/fiber/libs/fiber/test/test_spin_manual_reset_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/test/test_spin_manual_reset_event.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,157 @@
+
+//          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 <cstdlib>
+#include <iostream>
+#include <map>
+#include <stdexcept>
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber.hpp>
+
+int value = 0;
+
+void wait_fn( boost::fibers::spin_manual_reset_event & ev)
+{
+	ev.wait();
+	++value;
+}
+
+void test_case_1()
+{
+	value = 0;
+	boost::fibers::spin_manual_reset_event ev;
+	boost::fibers::scheduler<> sched;
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( ev) );
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( ev) );
+
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	ev.set();
+
+	while ( sched.run() );
+
+	BOOST_CHECK( ! sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value);
+}
+
+void test_case_2()
+{
+	value = 0;
+	boost::fibers::spin_manual_reset_event ev;
+	boost::fibers::scheduler<> sched;
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( ev) );
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( ev) );
+
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	ev.set();
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value);
+
+	ev.reset();
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value);
+
+	ev.set();
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( ! sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value);
+}
+
+void test_case_3()
+{
+	value = 0;
+	boost::fibers::spin_manual_reset_event ev( true);
+	boost::fibers::scheduler<> sched;
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( ev) );
+
+	sched.make_fiber(
+		wait_fn,
+		boost::ref( ev) );
+
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 0, value);
+
+	while ( sched.run() );
+
+	BOOST_CHECK( ! sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value);
+}
+
+void test_case_4()
+{
+	boost::fibers::spin_manual_reset_event ev;
+
+	BOOST_CHECK_EQUAL( false, ev.try_wait() );
+
+	ev.set();
+
+	BOOST_CHECK_EQUAL( true, ev.try_wait() );
+	BOOST_CHECK_EQUAL( true, ev.try_wait() );
+
+	ev.reset();
+
+	BOOST_CHECK_EQUAL( false, ev.try_wait() );
+}
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+	boost::unit_test::test_suite * test =
+		BOOST_TEST_SUITE("Boost.Fiber: spin-manual-reset-event test suite");
+
+	test->add( BOOST_TEST_CASE( & test_case_1) );
+	test->add( BOOST_TEST_CASE( & test_case_2) );
+	test->add( BOOST_TEST_CASE( & test_case_3) );
+	test->add( BOOST_TEST_CASE( & test_case_4) );
+
+	return test;
+}
Added: sandbox/fiber/libs/fiber/test/test_spin_mutex.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/test/test_spin_mutex.cpp	2009-12-07 15:49:34 EST (Mon, 07 Dec 2009)
@@ -0,0 +1,131 @@
+
+//          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)
+//
+// This test is based on the tests of Boost.Thread 
+
+#include <cstdlib>
+#include <iostream>
+#include <map>
+#include <stdexcept>
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber.hpp>
+
+template< typename M >
+struct test_lock
+{
+    typedef M spin_mutex_type;
+    typedef typename M::scoped_lock lock_type;
+
+    void operator()()
+    {
+        spin_mutex_type spin_mutex;
+        boost::fibers::spin_condition condition;
+
+        // Test the lock's constructors.
+        {
+            lock_type lock(spin_mutex, boost::defer_lock);
+            BOOST_CHECK(!lock);
+        }
+        lock_type lock(spin_mutex);
+        BOOST_CHECK(lock ? true : false);
+
+        // Test the lock and unlock methods.
+        lock.unlock();
+        BOOST_CHECK(!lock);
+        lock.lock();
+        BOOST_CHECK(lock ? true : false);
+    }
+};
+
+void do_test_spin_mutex()
+{
+    test_lock< boost::fibers::spin_mutex >()();
+}
+
+void test_case1()
+{
+	boost::fibers::scheduler<> sched;
+    sched.make_fiber( & do_test_spin_mutex);
+	sched.run();
+}
+
+int value1 = 0;
+int value2 = 0;
+
+void test_fn1( boost::fibers::spin_mutex & mtx)
+{
+	boost::fibers::spin_mutex::scoped_lock lk( mtx);
+	++value1;
+	for ( int i = 0; i < 3; ++i)
+		boost::this_fiber::yield();
+}
+
+void test_fn2( boost::fibers::spin_mutex & mtx)
+{
+	boost::fibers::spin_mutex::scoped_lock lk( mtx);
+	++value2;
+}
+
+void test_case2()
+{
+	boost::fibers::spin_mutex mtx;
+	boost::fibers::scheduler<> sched;
+    sched.make_fiber( & test_fn1, boost::ref( mtx) );
+    sched.make_fiber( & test_fn2, boost::ref( mtx) );
+
+	BOOST_CHECK_EQUAL( 0, value1);
+	BOOST_CHECK_EQUAL( 0, value2);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value1);
+	BOOST_CHECK_EQUAL( 0, value2);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value1);
+	BOOST_CHECK_EQUAL( 0, value2);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value1);
+	BOOST_CHECK_EQUAL( 0, value2);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value1);
+	BOOST_CHECK_EQUAL( 0, value2);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value1);
+	BOOST_CHECK_EQUAL( 0, value2);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value1);
+	BOOST_CHECK_EQUAL( 1, value2);
+}
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+    boost::unit_test_framework::test_suite * test =
+		BOOST_TEST_SUITE("Boost.Fiber: spin-mutex test suite");
+
+    test->add(BOOST_TEST_CASE(&test_case1));
+    test->add(BOOST_TEST_CASE(&test_case2));
+
+	return test;
+}