Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r56721 - in sandbox/task: boost boost/task boost/task/detail libs/task/build libs/task/src
From: oliver.kowalke_at_[hidden]
Date: 2009-10-11 16:13:13


Author: olli
Date: 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
New Revision: 56721
URL: http://svn.boost.org/trac/boost/changeset/56721

Log:
- spin events (auto-reset, manual-reset)

Added:
   sandbox/task/boost/task/bounded_buffer.hpp (contents, props changed)
   sandbox/task/boost/task/spin_auto_reset_event.hpp (contents, props changed)
   sandbox/task/boost/task/spin_count_down_event.hpp (contents, props changed)
   sandbox/task/boost/task/spin_manual_reset_event.hpp (contents, props changed)
   sandbox/task/libs/task/src/spin_auto_reset_event.cpp (contents, props changed)
   sandbox/task/libs/task/src/spin_count_down_event.cpp (contents, props changed)
   sandbox/task/libs/task/src/spin_manual_reset_event.cpp (contents, props changed)
Text files modified:
   sandbox/task/boost/task.hpp | 2 +
   sandbox/task/boost/task/detail/atomic_aix.hpp | 15 +++++++---
   sandbox/task/boost/task/detail/atomic_gcc.hpp | 4 ++
   sandbox/task/boost/task/detail/atomic_gcc_ppc.hpp | 15 +++++++---
   sandbox/task/boost/task/detail/atomic_gcc_x86.hpp | 15 +++++++---
   sandbox/task/boost/task/detail/atomic_hpux.hpp | 15 +++++++---
   sandbox/task/boost/task/detail/atomic_interlocked.hpp | 15 +++++++---
   sandbox/task/boost/task/detail/atomic_interprocess.hpp | 15 +++++++---
   sandbox/task/boost/task/detail/atomic_solaris.hpp | 15 +++++++---
   sandbox/task/boost/task/detail/atomic_sync.hpp | 15 +++++++---
   sandbox/task/boost/task/detail/worker.hpp | 8 ++--
   sandbox/task/boost/task/new_thread.hpp | 7 ++--
   sandbox/task/boost/task/spin_condition.hpp | 9 ++----
   sandbox/task/libs/task/build/Jamfile.v2 | 2 +
   sandbox/task/libs/task/src/spin_condition.cpp | 56 ++++++++++++++++++++-------------------
   15 files changed, 127 insertions(+), 81 deletions(-)

Modified: sandbox/task/boost/task.hpp
==============================================================================
--- sandbox/task/boost/task.hpp (original)
+++ sandbox/task/boost/task.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -9,6 +9,7 @@
 
 #include <boost/task/as_sub_task.hpp>
 #include <boost/task/async.hpp>
+#include <boost/task/bounded_buffer.hpp>
 #include <boost/task/bounded_twolock_fifo.hpp>
 #include <boost/task/bounded_onelock_fifo.hpp>
 #include <boost/task/bounded_onelock_prio_queue.hpp>
@@ -25,6 +26,7 @@
 #include <boost/task/poolsize.hpp>
 #include <boost/task/scanns.hpp>
 #include <boost/task/semaphore.hpp>
+#include <boost/task/spin_auto_reset_event.hpp>
 #include <boost/task/spin_condition.hpp>
 #include <boost/task/spin_lock.hpp>
 #include <boost/task/spin_mutex.hpp>

Added: sandbox/task/boost/task/bounded_buffer.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/bounded_buffer.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -0,0 +1,358 @@
+
+// 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_TASK_BOUNDED_BUFFER_H
+#define BOOST_TASK_BOUNDED_BUFFER_H
+
+#include <cstddef>
+#include <deque>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/optional.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/exceptions.hpp>
+#include <boost/task/semaphore.hpp>
+#include <boost/task/spin_condition.hpp>
+#include <boost/task/spin_lock.hpp>
+#include <boost/task/spin_mutex.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost { namespace task
+{
+template< typename T >
+class bounded_buffer
+{
+private:
+ typedef T value_type;
+
+ class base
+ {
+ private:
+ volatile uint32_t state_;
+ std::deque< value_type > queue_;
+ spin_mutex mtx_;
+ spin_condition not_empty_cond_;
+ spin_condition not_full_cond_;
+ std::size_t hwm_;
+ std::size_t lwm_;
+
+ base( base &);
+ base & operator=( base const&);
+
+ bool active_() const
+ { return 0 == state_; }
+
+ void deactivate_()
+ { detail::atomic_fetch_add( & state_, 1); }
+
+ bool empty_() const
+ { return queue_.empty(); }
+
+ bool full_() const
+ { return size_() >= hwm_; }
+
+ std::size_t size_() const
+ { return queue_.size(); }
+
+ void upper_bound_( std::size_t hwm)
+ {
+ if ( lwm_ > hwm )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ std::size_t tmp( hwm_);
+ hwm_ = hwm;
+ if ( hwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ void lower_bound_( std::size_t lwm)
+ {
+ if ( lwm > hwm_ )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ std::size_t tmp( lwm_);
+ lwm_ = lwm;
+ if ( lwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ void put_(
+ value_type const& va,
+ spin_lock< spin_mutex > & lk)
+ {
+ if ( full_() )
+ {
+ not_full_cond_.wait(
+ lk,
+ bind(
+ & base::producers_activate_,
+ this) );
+ }
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+ queue_.push_back( va);
+ not_empty_cond_.notify_one();
+ }
+
+ template< typename TimeDuration >
+ void put_(
+ value_type const& va,
+ TimeDuration const& rel_time,
+ spin_lock< spin_mutex > & lk)
+ {
+ if ( full_() )
+ {
+ if ( ! not_full_cond_.timed_wait(
+ lk,
+ rel_time,
+ bind(
+ & base::producers_activate_,
+ this) ) )
+ throw task_rejected("timed out");
+ }
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+ queue_.push_back( va);
+ not_empty_cond_.notify_one();
+ }
+
+ bool take_(
+ optional< value_type > & va,
+ spin_lock< spin_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ not_empty_cond_.wait(
+ lk,
+ bind(
+ & base::consumers_activate_,
+ this) );
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ va = queue_.front();
+ queue_.pop_front();
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // for submiting an action object
+ not_full_cond_.notify_all();
+ }
+ return va;
+ }
+
+ template< typename TimeDuration >
+ bool take_(
+ optional< value_type > & va,
+ TimeDuration const& rel_time,
+ spin_lock< spin_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ if ( ! not_empty_cond_.timed_wait(
+ lk,
+ rel_time,
+ bind(
+ & base::consumers_activate_,
+ this) ) )
+ return false;
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ va = queue_.front();
+ queue_.pop_front();
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // in order to submit an task
+ not_full_cond_.notify_all();
+ }
+ return va;
+ }
+
+ bool try_take_( optional< value_type > & va)
+ {
+ if ( empty_() )
+ return false;
+ va = queue_.front();
+ queue_.pop_front();
+ bool valid = va;
+ if ( valid && size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // in order to submit an task
+ not_full_cond_.notify_all();
+ }
+ return valid;
+ }
+
+ bool producers_activate_() const
+ { return ! active_() || ! full_(); }
+
+ bool consumers_activate_() const
+ { return ! active_() || ! empty_(); }
+
+ public:
+ base(
+ high_watermark const& hwm,
+ low_watermark const& lwm)
+ :
+ state_( 0),
+ queue_(),
+ mtx_(),
+ not_empty_cond_(),
+ not_full_cond_(),
+ hwm_( hwm),
+ lwm_( lwm)
+ {}
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty()
+ {
+ spin_lock< spin_mutex > lk( mtx_);
+ return empty_();
+ }
+
+ std::size_t upper_bound()
+ {
+ spin_lock< spin_mutex > lk( mtx_);
+ return hwm_;
+ }
+
+ void upper_bound( std::size_t hwm)
+ {
+ spin_lock< spin_mutex > lk( mtx_);
+ upper_bound_( hwm);
+ }
+
+ std::size_t lower_bound()
+ {
+ spin_lock< spin_mutex > lk( mtx_);
+ return lwm_;
+ }
+
+ void lower_bound( std::size_t lwm)
+ {
+ spin_lock< spin_mutex > lk( mtx_);
+ lower_bound_( lwm);
+ }
+
+ void put( value_type const& va)
+ {
+ spin_lock< spin_mutex > lk( mtx_);
+ put_( va);
+ }
+
+ template< typename TimeDuration >
+ void put(
+ value_type const& va,
+ TimeDuration const& rel_time)
+ {
+ spin_lock< spin_mutex > lk( mtx_);
+ put_( va, rel_time, lk);
+ }
+
+ bool take( optional< value_type > & va)
+ {
+ spin_lock< spin_mutex > lk( mtx_);
+ return take_( va, lk);
+ }
+
+ template< typename TimeDuration >
+ bool take(
+ optional< value_type > & va,
+ TimeDuration const& rel_time)
+ {
+ spin_lock< spin_mutex > lk( mtx_);
+ return take_( va, rel_time, lk);
+ }
+
+ bool try_take( optional< value_type > & va)
+ {
+ spin_lock< spin_mutex > lk( mtx_);
+ return try_take_( va);
+ }
+ };
+
+ shared_ptr< base > impl_;
+
+public:
+ bounded_buffer()
+ : impl_( new base)
+ {}
+
+ void deactivate()
+ { impl_->deactivate(); }
+
+ bool empty()
+ { return impl_->empty(); }
+
+ std::size_t upper_bound()
+ { return impl_->upper_bound(); }
+
+ void upper_bound( std::size_t hwm)
+ { impl_->upper_bound( hwm); }
+
+ std::size_t lower_bound()
+ { return impl_->lower_bound; }
+
+ void lower_bound( std::size_t lwm)
+ { impl_->lower_bound( lwm); }
+
+ void put( T const& t)
+ { impl_->put( t); }
+
+ template< typename TimeDuration >
+ void put(
+ value_type const& va,
+ TimeDuration const& rel_time)
+ { impl_->put( va, rel_time); }
+
+ bool take( optional< T > & t)
+ { return impl_->take( t); }
+
+ template< typename TimeDuration >
+ bool take(
+ optional< T > & t,
+ TimeDuration const& rel_time)
+ { return impl_->take( t, rel_time); }
+
+ bool try_take( optional< T > & t)
+ { return impl_->try_take_( t); }
+};
+}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_TASK_BOUNDED_BUFFER_H

Modified: sandbox/task/boost/task/detail/atomic_aix.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_aix.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_aix.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -17,10 +17,14 @@
 
 #include <boost/config/abi_prefix.hpp>
 
-namespace boost { namespace task
-{
-namespace detail
-{
+namespace boost {
+namespace task {
+namespace detail {
+
+inline
+uint32_t atomic_load( uint32_t const volatile * object)
+{ return * object; }
+
 inline
 void atomic_exchange( uint32_t volatile * object, uint32_t desired)
 { * object = desired; }
@@ -42,7 +46,8 @@
         BOOST_ASSERT( operand == 1);
         return ::fetch_and_add( object, -1);
 }
-} } }
+
+}}}
 
 #include <boost/config/abi_suffix.hpp>
 

Modified: sandbox/task/boost/task/detail/atomic_gcc.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_gcc.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_gcc.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -34,6 +34,10 @@
 #endif
 
 inline
+uint32_t atomic_load( uint32_t const volatile * object)
+{ return * object; }
+
+inline
 void atomic_exchange( uint32_t volatile * object, uint32_t desired)
 {
   // inline asm xchg for i386 || x86_64?

Modified: sandbox/task/boost/task/detail/atomic_gcc_ppc.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_gcc_ppc.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_gcc_ppc.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -12,10 +12,14 @@
 
 #include <boost/config/abi_prefix.hpp>
 
-namespace boost { namespace task
-{
-namespace detail
-{
+namespace boost {
+namespace task {
+namespace detail {
+
+inline
+uint32_t atomic_load( uint32_t const volatile * object)
+{ return * object; }
+
 inline
 void atomic_exchange( uint32_t volatile * object, uint32_t desired)
 {
@@ -101,7 +105,8 @@
 
         return r;
 }
-} } }
+
+}}}
 
 #include <boost/config/abi_suffix.hpp>
 

Modified: sandbox/task/boost/task/detail/atomic_gcc_x86.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_gcc_x86.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_gcc_x86.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -12,10 +12,14 @@
 
 #include <boost/config/abi_prefix.hpp>
 
-namespace boost { namespace task
-{
-namespace detail
-{
+namespace boost {
+namespace task {
+namespace detail {
+
+inline
+uint32_t atomic_load( uint32_t const volatile * object)
+{ return * object; }
+
 inline
 void atomic_exchange( uint32_t volatile * object, uint32_t desired)
 {
@@ -78,7 +82,8 @@
 
         return r;
 }
-} } }
+
+}}}
 
 #include <boost/config/abi_suffix.hpp>
 

Modified: sandbox/task/boost/task/detail/atomic_hpux.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_hpux.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_hpux.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -16,10 +16,14 @@
 #include <boost/cstdint.hpp>
 #include <boost/config/abi_prefix.hpp>
 
-namespace boost { namespace task
-{
-namespace detail
-{
+namespace boost {
+namespace task {
+namespace detail {
+
+inline
+uint32_t atomic_load( uint32_t const volatile * object)
+{ return * object; }
+
 inline
 void atomic_exchange( uint32_t volatile * object, uint32_t desired)
 { * object = desired; }
@@ -49,7 +53,8 @@
         BOOST_ASSERT( operand == 1);
         return ::atomic_dec( object);
 }
-} } }
+
+}}}
 
 #include <boost/config/abi_suffix.hpp>
 

Modified: sandbox/task/boost/task/detail/atomic_interlocked.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_interlocked.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_interlocked.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -13,10 +13,14 @@
 
 #include <boost/config/abi_prefix.hpp>
 
-namespace boost { namespace task
-{
-namespace detail
-{
+namespace boost {
+namespace task {
+namespace detail {
+
+inline
+uint32_t atomic_load( uint32_t const volatile * object)
+{ return * object; }
+
 inline
 void atomic_exchange( uint32_t volatile * object, uint32_t desired)
 { BOOST_INTERLOCKED_EXCHANGE( reinterpret_cast< long volatile * >( object), desired); }
@@ -46,7 +50,8 @@
         BOOST_ASSERT( operand == 1);
         return BOOST_INTERLOCKED_DECREMENT( reinterpret_cast< long volatile * >( object) ) + 1;
 }
-} } }
+
+}}}
 
 #include <boost/config/abi_suffix.hpp>
 

Modified: sandbox/task/boost/task/detail/atomic_interprocess.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_interprocess.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_interprocess.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -13,10 +13,14 @@
 
 #include <boost/config/abi_prefix.hpp>
 
-namespace boost { namespace task
-{
-namespace detail
-{
+namespace boost {
+namespace task {
+namespace detail {
+
+inline
+uint32_t atomic_load( uint32_t const volatile * object)
+{ return * object; }
+
 inline
 void atomic_exchange( uint32_t volatile * object, uint32_t desired)
 { interprocess::detail::atomic_write32( object, desired); }
@@ -46,7 +50,8 @@
         BOOST_ASSERT( operand == 1);
         return interprocess::detail::atomic_dec32( object);
 }
-} } }
+
+}}}
 
 #include <boost/config/abi_suffix.hpp>
 

Modified: sandbox/task/boost/task/detail/atomic_solaris.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_solaris.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_solaris.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -17,10 +17,14 @@
 
 #include <boost/config/abi_prefix.hpp>
 
-namespace boost { namespace task
-{
-namespace detail
-{
+namespace boost {
+namespace task {
+namespace detail {
+
+inline
+uint32_t atomic_load( uint32_t const volatile * object)
+{ return * object; }
+
 inline
 void atomic_exchange( uint32_t volatile * object, uint32_t desired)
 { * object = desired; }
@@ -50,7 +54,8 @@
         BOOST_ASSERT( operand == 1);
         return ::atomic_dec_32( object);
 }
-} } }
+
+}}}
 
 #include <boost/config/abi_suffix.hpp>
 

Modified: sandbox/task/boost/task/detail/atomic_sync.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_sync.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_sync.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -21,10 +21,14 @@
 
 #include <boost/config/abi_prefix.hpp>
 
-namespace boost { namespace task
-{
-namespace detail
-{
+namespace boost {
+namespace task {
+namespace detail {
+
+inline
+uint32_t atomic_load( uint32_t const volatile * object)
+{ return * object; }
+
 inline
 void atomic_exchange( uint32_t volatile * object, uint32_t desired)
 { * object = desired; }
@@ -54,7 +58,8 @@
         BOOST_ASSERT( operand == 1);
         return __sync_fetch_and_add( object, -1);
 }
-} } }
+
+}}}
 
 #include <boost/config/abi_suffix.hpp>
 

Modified: sandbox/task/boost/task/detail/worker.hpp
==============================================================================
--- sandbox/task/boost/task/detail/worker.hpp (original)
+++ sandbox/task/boost/task/detail/worker.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -189,11 +189,11 @@
                                 }
                                 else if ( ! ums_.has_blocked() )
                                 {
- try
- { this_thread::sleep( asleep_); }
- catch ( thread_interrupted const&)
- { return; }
+ if ( take_global_callable_( ca) )
+ execute_( ca);
                                 }
+ else
+ this_thread::yield();
                                 scns_ = 0;
                         }
                         else

Modified: sandbox/task/boost/task/new_thread.hpp
==============================================================================
--- sandbox/task/boost/task/new_thread.hpp (original)
+++ sandbox/task/boost/task/new_thread.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -21,10 +21,9 @@
 
 #include <boost/config/abi_prefix.hpp>
 
-namespace boost { namespace task
-{
-namespace detail
-{
+namespace boost {
+namespace task {
+namespace detail {
 
 struct joiner
 {

Added: sandbox/task/boost/task/spin_auto_reset_event.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/spin_auto_reset_event.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -0,0 +1,44 @@
+
+// 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_TASK_SPIN_AUTO_RESET_EVENT_H
+#define BOOST_TASK_SPIN_AUTO_RESET_EVENT_H
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/utility.hpp>
+
+namespace boost {
+namespace task {
+
+class spin_auto_reset_event : private noncopyable
+{
+private:
+ enum state_t
+ {
+ RESET = 0,
+ SET
+ };
+
+ volatile state_t state_;
+
+public:
+ spin_auto_reset_event();
+
+ void set();
+
+ void wait();
+
+ bool wait( system_time const&);
+
+ template< typename TimeDuration >
+ bool wait( TimeDuration const& rel_time)
+ { return wait( get_system_time() + rel_time); }
+};
+
+}}
+
+#endif // BOOST_TASK_SPIN_AUTO_RESET_EVENT_H

Modified: sandbox/task/boost/task/spin_condition.hpp
==============================================================================
--- sandbox/task/boost/task/spin_condition.hpp (original)
+++ sandbox/task/boost/task/spin_condition.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -20,24 +20,21 @@
 class spin_condition : private noncopyable
 {
 private:
- enum command
+ enum command_t
         {
                 SLEEPING = 0,
                 NOTIFY_ONE,
                 NOTIFY_ALL
         };
 
- volatile uint32_t cmd_;
+ volatile command_t cmd_;
         volatile uint32_t waiters_;
         spin_mutex enter_mtx_;
         spin_mutex check_mtx_;
 
- spin_condition( spin_condition const&);
- spin_condition & operator=( spin_condition const&);
-
         void wait_( spin_mutex &);
         bool wait_( spin_mutex &, system_time const&);
- void notify_( command);
+ void notify_( command_t);
 
 public:
         spin_condition();

Added: sandbox/task/boost/task/spin_count_down_event.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/spin_count_down_event.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -0,0 +1,47 @@
+
+// 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_TASK_SPIN_COUNT_DOWN_EVENT_H
+#define BOOST_TASK_SPIN_COUNT_DOWN_EVENT_H
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/task/spin_mutex.hpp>
+
+namespace boost {
+namespace task {
+
+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();
+
+ bool wait( system_time const&);
+
+ template< typename TimeDuration >
+ bool wait( TimeDuration const& rel_time)
+ { return wait( get_system_time() + rel_time); }
+};
+
+}}
+
+#endif // BOOST_TASK_SPIN_COUNT_DOWN_EVENT_H

Added: sandbox/task/boost/task/spin_manual_reset_event.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/spin_manual_reset_event.hpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -0,0 +1,50 @@
+
+// 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_TASK_SPIN_MANUAL_RESET_EVENT_H
+#define BOOST_TASK_SPIN_MANUAL_RESET_EVENT_H
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/task/spin_mutex.hpp>
+
+namespace boost {
+namespace task {
+
+class spin_manual_reset_event : private noncopyable
+{
+private:
+ enum state_t
+ {
+ RESET = 0,
+ SET
+ };
+
+ volatile state_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 wait( system_time const&);
+
+ template< typename TimeDuration >
+ bool wait( TimeDuration const& rel_time)
+ { return wait( get_system_time() + rel_time); }
+};
+
+}}
+
+#endif // BOOST_TASK_SPIN_MANUAL_RESET_EVENT_H

Modified: sandbox/task/libs/task/build/Jamfile.v2
==============================================================================
--- sandbox/task/libs/task/build/Jamfile.v2 (original)
+++ sandbox/task/libs/task/build/Jamfile.v2 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -41,6 +41,7 @@
         poolsize.cpp
         scanns.cpp
         semaphore_windows.cpp
+ spin_auto_reset_event.cpp
         spin_condition.cpp
         spin_mutex.cpp
         stacksize.cpp
@@ -60,6 +61,7 @@
         poolsize.cpp
         scanns.cpp
         semaphore_posix.cpp
+ spin_auto_reset_event.cpp
         spin_condition.cpp
         spin_mutex.cpp
         stacksize.cpp

Added: sandbox/task/libs/task/src/spin_auto_reset_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/src/spin_auto_reset_event.cpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -0,0 +1,67 @@
+
+// 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/task/spin_auto_reset_event.hpp"
+
+#include <boost/thread.hpp>
+
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/utility.hpp>
+
+namespace boost {
+namespace task {
+
+spin_auto_reset_event::spin_auto_reset_event( bool isset)
+: state_( isset ? SET : RESET)
+{}
+
+void
+spin_auto_reset_event::set()
+{
+ detail::atomic_exchange(
+ static_cast< uint32_t volatile* >( & state_),
+ static_cast< uint32_t >( SET) );
+}
+
+void
+spin_auto_reset_event::wait()
+{
+ state_t expected = SET;
+ while ( ! detail::atomic_compare_exchange_strong(
+ static_cast< uint32_t volatile* >( & state_),
+ static_cast< uint32_t * >( & expected),
+ static_cast< uint32_t >( RESET) ) )
+ {
+ if ( this_task::runs_in_pool() )
+ this_task::block();
+ else
+ this_thread::yield();
+ }
+}
+
+bool
+spin_auto_reset_event::wait( system_time const& abs_time)
+{
+ if ( get_system_time() >= abs_time) return false;
+
+ state_t expected = SET;
+ while ( ! detail::atomic_compare_exchange_strong(
+ static_cast< uint32_t volatile* >( & state_),
+ static_cast< uint32_t * >( & expected),
+ static_cast< uint32_t >( RESET) ) )
+ {
+ if ( this_task::runs_in_pool() )
+ this_task::block();
+ else
+ this_thread::yield();
+
+ if ( get_system_time() >= abs_time) return false;
+ }
+
+ return true;
+}
+
+}}

Modified: sandbox/task/libs/task/src/spin_condition.cpp
==============================================================================
--- sandbox/task/libs/task/src/spin_condition.cpp (original)
+++ sandbox/task/libs/task/src/spin_condition.cpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -6,6 +6,7 @@
 
 #include "boost/task/spin_condition.hpp"
 
+#include <boost/assert.hpp>
 #include <boost/thread.hpp>
 
 #include <boost/task/detail/atomic.hpp>
@@ -17,19 +18,21 @@
 namespace task {
 
 void
-spin_condition::notify_( command cmd)
+spin_condition::notify_( command_t cmd)
 {
         enter_mtx_.lock();
 
- if ( waiters_ == 0)
+ if ( 0 == detail::atomic_load( & waiters_) )
         {
                 enter_mtx_.unlock();
                 return;
         }
 
- uint32_t expected = static_cast< uint32_t >( SLEEPING);
+ command_t expected = SLEEPING;
         while ( ! detail::atomic_compare_exchange_strong(
- static_cast< uint32_t volatile* >( & cmd_), & expected, cmd) )
+ static_cast< uint32_t volatile* >( & cmd_),
+ static_cast< uint32_t * >( & expected),
+ cmd) )
         {
                 if ( this_task::runs_in_pool() )
                         this_task::block();
@@ -43,7 +46,7 @@
 {
         {
                 spin_lock< spin_mutex > lk( enter_mtx_);
- if ( ! lk) return;
+ BOOST_ASSERT( lk);
                 detail::atomic_fetch_add( & waiters_, 1);
                 mtx.unlock();
         }
@@ -51,7 +54,7 @@
         bool unlock_enter_mtx = false;
         for (;;)
         {
- while ( SLEEPING == cmd_)
+ while ( SLEEPING == detail::atomic_load( static_cast< uint32_t volatile* >( & cmd_) ) )
                 {
                         if ( this_task::runs_in_pool() )
                                 this_task::block();
@@ -60,15 +63,13 @@
                 }
 
                 spin_lock< spin_mutex > lk( check_mtx_);
- if ( ! lk)
- {
- unlock_enter_mtx = true;
- break;
- }
+ BOOST_ASSERT( lk);
 
- uint32_t expected = static_cast< uint32_t >( NOTIFY_ONE);
+ command_t expected = NOTIFY_ONE;
                 detail::atomic_compare_exchange_strong(
- static_cast< uint32_t volatile* >( & cmd_), & expected, SLEEPING);
+ static_cast< uint32_t volatile* >( & cmd_),
+ static_cast< uint32_t * >( & expected),
+ static_cast< uint32_t >( SLEEPING) );
                 if ( SLEEPING == expected)
                         continue;
                 else if ( NOTIFY_ONE == expected)
@@ -82,9 +83,11 @@
                         unlock_enter_mtx = 1 == detail::atomic_fetch_sub( & waiters_, 1);
                         if ( unlock_enter_mtx)
                         {
- expected = static_cast< uint32_t >( NOTIFY_ALL);
+ expected = NOTIFY_ALL;
                                 detail::atomic_compare_exchange_strong(
- static_cast< uint32_t volatile* >( & cmd_), & expected, SLEEPING);
+ static_cast< uint32_t volatile* >( & cmd_),
+ static_cast< uint32_t * >( & expected),
+ static_cast< uint32_t >( SLEEPING) );
                         }
                         break;
                 }
@@ -103,7 +106,7 @@
 
         {
                 spin_lock< spin_mutex > lk( enter_mtx_, abs_time);
- if ( ! lk) return false;
+ BOOST_ASSERT( lk);
                 detail::atomic_fetch_add( & waiters_, 1);
                 mtx.unlock();
         }
@@ -111,7 +114,7 @@
         bool timed_out = false, unlock_enter_mtx = false;
         for (;;)
         {
- while ( SLEEPING == cmd_)
+ while ( SLEEPING == detail::atomic_load( static_cast< uint32_t volatile* >( & cmd_) ) )
                 {
                         if ( this_task::runs_in_pool() )
                                 this_task::block();
@@ -136,16 +139,13 @@
                 else
                 {
                         spin_lock< spin_mutex > lk( check_mtx_);
- if ( ! lk)
- {
- timed_out = true;
- unlock_enter_mtx = true;
- break;
- }
+ BOOST_ASSERT( lk);
 
- uint32_t expected = static_cast< uint32_t >( NOTIFY_ONE);
+ command_t expected = NOTIFY_ONE;
                         detail::atomic_compare_exchange_strong(
- static_cast< uint32_t volatile* >( & cmd_), & expected, SLEEPING);
+ static_cast< uint32_t volatile* >( & cmd_),
+ static_cast< uint32_t * >( & expected),
+ static_cast< uint32_t >( SLEEPING) );
                         if ( SLEEPING == expected)
                                 continue;
                         else if ( NOTIFY_ONE == expected)
@@ -159,9 +159,11 @@
                                 unlock_enter_mtx = 1 == detail::atomic_fetch_sub( & waiters_, 1);
                                 if ( unlock_enter_mtx)
                                 {
- expected = static_cast< uint32_t >( NOTIFY_ALL);
+ expected = NOTIFY_ALL;
                                         detail::atomic_compare_exchange_strong(
- static_cast< uint32_t volatile* >( & cmd_), & expected, SLEEPING);
+ static_cast< uint32_t volatile* >( & cmd_),
+ static_cast< uint32_t * >( & expected),
+ static_cast< uint32_t >( SLEEPING) );
                                 }
                                 break;
                         }

Added: sandbox/task/libs/task/src/spin_count_down_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/src/spin_count_down_event.cpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -0,0 +1,177 @@
+
+// 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/task/spin_count_down_event.hpp"
+
+#include <boost/thread.hpp>
+
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/spin_mutex.hpp>
+#include <boost/task/spin_lock.hpp>
+#include <boost/task/utility.hpp>
+
+namespace boost {
+namespace task {
+
+spin_count_down_event::spin_count_down_event( uint32_t intial)
+:
+intial_( intial),
+current_( intial_)
+{}
+
+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()
+{
+ enter_mtx_.lock();
+
+ detail::atomic_fetch_sub( & current_, 1);
+}
+
+void
+spin_count_down_event::wait()
+{
+ {
+ spin_lock< spin_mutex > lk( enter_mtx_);
+ if ( ! lk) return;
+ detail::atomic_fetch_add( & waiters_, 1);
+ }
+
+ bool unlock_enter_mtx = false;
+ for (;;)
+ {
+ while ( SLEEPING == detail::atomic_load( & cmd_) )
+ {
+ if ( this_task::runs_in_pool() )
+ this_task::block();
+ else
+ this_thread::yield();
+ }
+
+ spin_lock< spin_mutex > lk( check_mtx_);
+ if ( ! lk)
+ {
+ unlock_enter_mtx = true;
+ break;
+ }
+
+ uint32_t expected = static_cast< uint32_t >( NOTIFY_ONE);
+ detail::atomic_compare_exchange_strong(
+ static_cast< uint32_t volatile* >( & cmd_), & expected, SLEEPING);
+ if ( SLEEPING == expected)
+ continue;
+ else if ( 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(
+ static_cast< uint32_t volatile* >( & cmd_), & expected, SLEEPING);
+ }
+ break;
+ }
+ }
+
+ if ( unlock_enter_mtx)
+ enter_mtx_.unlock();
+}
+
+bool
+spin_count_down_event::wait( system_time const& abs_time)
+{
+ if ( get_system_time() >= abs_time) return false;
+
+ {
+ spin_lock< spin_mutex > lk( enter_mtx_, abs_time);
+ if ( ! lk) return false;
+ detail::atomic_fetch_add( & waiters_, 1);
+ }
+
+ bool timed_out = false, unlock_enter_mtx = false;
+ for (;;)
+ {
+ while ( SLEEPING == detail::atomic_load( & cmd_) )
+ {
+ if ( this_task::runs_in_pool() )
+ this_task::block();
+ else
+ this_thread::yield();
+
+ if ( get_system_time() >= abs_time)
+ {
+ timed_out = enter_mtx_.try_lock();
+ if ( ! timed_out)
+ continue;
+ break;
+ }
+ }
+
+ if ( timed_out)
+ {
+ detail::atomic_fetch_sub( & waiters_, 1);
+ unlock_enter_mtx = true;
+ break;
+ }
+ else
+ {
+ spin_lock< spin_mutex > lk( check_mtx_);
+ if ( ! lk)
+ {
+ timed_out = true;
+ unlock_enter_mtx = true;
+ break;
+ }
+
+ uint32_t expected = static_cast< uint32_t >( NOTIFY_ONE);
+ detail::atomic_compare_exchange_strong(
+ static_cast< uint32_t volatile* >( & cmd_), & expected, SLEEPING);
+ if ( SLEEPING == expected)
+ continue;
+ else if ( 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(
+ static_cast< uint32_t volatile* >( & cmd_), & expected, SLEEPING);
+ }
+ break;
+ }
+ }
+ }
+
+ if ( unlock_enter_mtx)
+ enter_mtx_.unlock();
+
+ return ! timed_out;
+}
+
+}}

Added: sandbox/task/libs/task/src/spin_manual_reset_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/src/spin_manual_reset_event.cpp 2009-10-11 16:13:11 EDT (Sun, 11 Oct 2009)
@@ -0,0 +1,90 @@
+
+// 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/task/spin_manual_reset_event.hpp"
+
+#include <boost/assert.hpp>
+#include <boost/thread.hpp>
+
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/spin_lock.hpp>
+#include <boost/task/utility.hpp>
+
+namespace boost {
+namespace task {
+
+spin_manual_reset_event::spin_manual_reset_event( bool isset)
+:
+state_( isset ? SET : RESET),
+waiters_( 0),
+enter_mtx_()
+{}
+
+void
+spin_manual_reset_event::set()
+{
+ enter_mtx_.lock();
+
+ state_t expected = RESET;
+ if ( ! detail::atomic_compare_exchange_strong(
+ static_cast< uint32_t volatile* >( & state_),
+ static_cast< uint32_t * >( & expected),
+ static_cast< uint32_t >( SET) ) ||
+ ! detail::atomic_load( static_cast< uint32_t volatile* >( & waiters_) ) )
+ enter_mtx_.unlock();
+}
+
+void
+spin_manual_reset_event::reset()
+{
+ spin_lock< spin_mutex > lk( enter_mtx_);
+ BOOST_ASSERT( lk);
+
+ detail::atomic_exchange(
+ static_cast< uint32_t volatile* >( & state_),
+ static_cast< uint32_t >( RESET) );
+}
+
+void
+spin_manual_reset_event::wait()
+{
+ {
+ spin_lock< spin_mutex > lk( enter_mtx_);
+ BOOST_ASSERT( lk);
+ detail::atomic_fetch_add( & waiters_, 1);
+ }
+
+ while ( RESET == detail::atomic_load( static_cast< uint32_t volatile* >( & state_) ) )
+ {
+ if ( this_task::runs_in_pool() )
+ this_task::block();
+ else
+ this_thread::yield();
+ }
+
+ if ( 1 == detail::atomic_fetch_sub( & waiters_, 1) )
+ enter_mtx_.unlock();
+}
+
+bool
+spin_manual_reset_event::wait( system_time const& abs_time)
+{
+ if ( get_system_time() >= abs_time) return false;
+
+ while ( RESET == detail::atomic_load( & state_) )
+ {
+ if ( this_task::runs_in_pool() )
+ this_task::block();
+ else
+ this_thread::yield();
+
+ if ( get_system_time() >= abs_time) return false;
+ }
+
+ return true;
+}
+
+}}


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