|
Boost-Commit : |
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;
+}
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