Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57496 - in sandbox/fiber: boost boost/fiber boost/fiber/detail libs/fiber/build libs/fiber/src libs/fiber/test
From: oliver.kowalke_at_[hidden]
Date: 2009-11-08 14:13:47


Author: olli
Date: 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
New Revision: 57496
URL: http://svn.boost.org/trac/boost/changeset/57496

Log:
- atomic-ops added
- mutex, condition, unique:lock, auto_reset-/manual_reset-/count_down-event added

Added:
   sandbox/fiber/boost/fiber/auto_reset_event.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/condition.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/count_down_event.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/atomic.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/atomic_aix.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/atomic_gcc.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/atomic_gcc_ppc.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/atomic_gcc_x86.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/atomic_hpux.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/atomic_interlocked.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/atomic_interprocess.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/atomic_solaris.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/atomic_sync.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/fiber_info_windows.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/detail/has_sync.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/manual_reset_event.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/mutex.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/unique_lock.hpp (contents, props changed)
   sandbox/fiber/libs/fiber/src/auto_reset_event.cpp (contents, props changed)
   sandbox/fiber/libs/fiber/src/condition.cpp (contents, props changed)
   sandbox/fiber/libs/fiber/src/count_down_event.cpp (contents, props changed)
   sandbox/fiber/libs/fiber/src/fiber_info_windows.cpp (contents, props changed)
   sandbox/fiber/libs/fiber/src/fiber_windows.cpp (contents, props changed)
   sandbox/fiber/libs/fiber/src/manual_reset_event.cpp (contents, props changed)
   sandbox/fiber/libs/fiber/src/mutex.cpp (contents, props changed)
   sandbox/fiber/libs/fiber/test/test_mutex.cpp (contents, props changed)
Text files modified:
   sandbox/fiber/boost/fiber.hpp | 7 +++++++
   sandbox/fiber/boost/fiber/exceptions.hpp | 8 ++++++++
   sandbox/fiber/boost/fiber/utility.hpp | 4 ++++
   sandbox/fiber/libs/fiber/build/Jamfile.v2 | 8 ++++++++
   sandbox/fiber/libs/fiber/test/Jamfile.v2 | 1 +
   5 files changed, 28 insertions(+), 0 deletions(-)

Modified: sandbox/fiber/boost/fiber.hpp
==============================================================================
--- sandbox/fiber/boost/fiber.hpp (original)
+++ sandbox/fiber/boost/fiber.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -8,8 +8,15 @@
 #define BOOST_FIBER_H
 
 #include <boost/fiber/attributes.hpp>
+#include <boost/fiber/auto_reset_event.hpp>
+#include <boost/fiber/condition.hpp>
+#include <boost/fiber/count_down_event.hpp>
 #include <boost/fiber/exceptions.hpp>
+#include <boost/fiber/fiber.hpp>
+#include <boost/fiber/manual_reset_event.hpp>
+#include <boost/fiber/mutex.hpp>
 #include <boost/fiber/scheduler.hpp>
+#include <boost/fiber/unique_lock.hpp>
 #include <boost/fiber/utility.hpp>
 
 #endif // BOOST_FIBER_H

Added: sandbox/fiber/boost/fiber/auto_reset_event.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/auto_reset_event.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,46 @@
+
+// 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_FIBER_AUTO_RESET_EVENT_H
+#define BOOST_FIBER_AUTO_RESET_EVENT_H
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/utility.hpp>
+
+namespace boost {
+namespace fiber {
+
+class auto_reset_event : private noncopyable
+{
+private:
+ enum state_t
+ {
+ RESET = 0,
+ SET
+ };
+
+ volatile uint32_t state_;
+
+public:
+ explicit auto_reset_event( bool = false);
+
+ 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); }
+
+ bool try_wait();
+};
+
+}}
+
+#endif // BOOST_FIBER_AUTO_RESET_EVENT_H

Added: sandbox/fiber/boost/fiber/condition.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/condition.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,122 @@
+
+// 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_condition
+
+#ifndef BOOST_FIBER_CONDITION_H
+#define BOOST_FIBER_CONDITION_H
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/exceptions.hpp>
+#include <boost/fiber/mutex.hpp>
+
+namespace boost {
+namespace fiber {
+
+class condition : private noncopyable
+{
+private:
+ enum command_t
+ {
+ SLEEPING = 0,
+ NOTIFY_ONE,
+ NOTIFY_ALL
+ };
+
+ volatile uint32_t cmd_;
+ volatile uint32_t waiters_;
+ mutex enter_mtx_;
+ mutex check_mtx_;
+
+ void wait_( mutex &);
+ bool wait_( mutex &, system_time const&);
+ void notify_( uint32_t);
+
+public:
+ 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() );
+ }
+
+ template< typename Lock >
+ bool timed_wait( Lock & lk, system_time const& abs_time)
+ {
+ if ( abs_time.is_infinity() )
+ {
+ wait( lk);
+ return true;
+ }
+
+ if ( ! lk)
+ throw lock_error();
+ return wait_( * lk.mutex(), abs_time);
+ }
+
+ template<
+ typename Lock,
+ typename Pred
+ >
+ bool timed_wait( Lock & lk, system_time const& abs_time, Pred pred)
+ {
+ if ( abs_time.is_infinity() )
+ {
+ wait( lk, pred);
+ return true;
+ }
+
+ if ( ! lk)
+ throw lock_error();
+
+ while ( ! pred() )
+ if ( ! wait_( * lk.mutex(), abs_time) )
+ return pred();
+ return true;
+ }
+
+ template<
+ typename Lock,
+ typename TimeDuration
+ >
+ bool timed_wait( Lock & lk, TimeDuration const& rel_time)
+ { return timed_wait( lk, get_system_time() + rel_time); }
+
+ template<
+ typename Lock,
+ typename TimeDuration,
+ typename Pred
+ >
+ bool timed_wait( Lock & lk, TimeDuration const& rel_time, Pred pred)
+ { return timed_wait( lk, get_system_time() + rel_time, pred); }
+};
+
+}}
+
+#endif // BOOST_FIBER_CONDITION_H

Added: sandbox/fiber/boost/fiber/count_down_event.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/count_down_event.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 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_FIBER_COUNT_DOWN_EVENT_H
+#define BOOST_FIBER_COUNT_DOWN_EVENT_H
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/mutex.hpp>
+
+namespace boost {
+namespace fiber {
+
+class count_down_event : private noncopyable
+{
+private:
+ uint32_t initial_;
+ volatile uint32_t current_;
+
+public:
+ explicit 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_FIBER_COUNT_DOWN_EVENT_H

Added: sandbox/fiber/boost/fiber/detail/atomic.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/atomic.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 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)
+
+#ifndef BOOST_FIBER_DETAIL_ATOMIC_H
+#define BOOST_FIBER_DETAIL_ATOMIC_H
+
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+
+#include <boost/fiber/detail/has_sync.hpp>
+
+# if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+#include <boost/fiber/detail/atomic_interlocked.hpp>
+
+# elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
+#include <boost/fiber/detail/atomic_gcc_x86.hpp>
+
+# elif defined( __GNUC__ ) && ( defined(__PPC__) || defined(__ppc__) )
+#include <boost/fiber/detail/atomic_gcc_ppc.hpp>
+
+# elif defined( BOOST_fiber_HAS_SYNC)
+#include <boost/fiber/detail/atomic_sync.hpp>
+
+# elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
+#include <boost/fiber/detail/atomic_gcc.hpp>
+
+# elif defined(__IBMCPP__) || defined(_AIX)
+#include <boost/fiber/detail/atomic_aix.hpp>
+
+# elif defined(__hpux)
+#include <boost/fiber/detail/atomic_hpux.hpp>
+
+# elif defined(sun) || defined(__sun)
+#include <boost/fiber/detail/atomic_solaris.hpp>
+
+# else
+#include <boost/fiber/detail/atomic_interprocess.hpp>
+
+# endif
+
+#endif // BOOST_FIBER_DETAIL_ATOMIC_H

Added: sandbox/fiber/boost/fiber/detail/atomic_aix.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/atomic_aix.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,55 @@
+
+// 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_FIBER_DETAIL_ATOMIC_AIX_H
+#define BOOST_FIBER_DETAIL_ATOMIC_AIX_H
+
+extern "C"
+{
+#include <sys/atomic_ops.h>
+}
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+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; }
+
+inline
+bool atomic_compare_exchange_strong( uint32_t volatile * object, uint32_t * expected, uint32_t desired)
+{ return ::compare_and_swap( object, expected, desired); }
+
+inline
+uint32_t atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return ::fetch_and_add( object, 1);
+}
+
+inline
+uint32_t atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return ::fetch_and_add( object, -1);
+}
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBER_DETAIL_ATOMIC_AIX_H
+

Added: sandbox/fiber/boost/fiber/detail/atomic_gcc.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/atomic_gcc.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,77 @@
+
+// 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_FIBER_DETAIL_ATOMIC_GCC_H
+#define BOOST_FIBER_DETAIL_ATOMIC_GCC_H
+
+// based on boost/smart_ptr/detail/atomic_count_gcc.hpp
+
+# if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
+#include <ext/atomicity.h>
+# else
+#include <bits/atomicity.h>
+# endif
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/interprocess/detail/atomic.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+namespace detail {
+
+#if defined(__GLIBCXX__) // g++ 3.4+
+
+using __gnu_cxx::__atomic_add;
+using __gnu_cxx::__exchange_and_add;
+
+#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?
+ * object = desired;
+}
+
+inline
+bool atomic_compare_exchange_strong( uint32_t volatile * object, uint32_t * expected, uint32_t desired)
+{
+ uint32_t prev = interprocess::detail::atomic_cas32( object, desired, * expected);
+ if ( prev != * expected)
+ {
+ * expected = prev;
+ return false;
+ }
+ return true;
+}
+
+inline
+uint32_t atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return __exchange_and_add( ( _Atomic_word volatile *) object, 1) + 1;
+}
+
+inline
+uint32_t atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return __exchange_and_add( ( _Atomic_word volatile *) object, -1) - 1;
+}
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBER_DETAIL_ATOMIC_GCC_H
+

Added: sandbox/fiber/boost/fiber/detail/atomic_gcc_ppc.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/atomic_gcc_ppc.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,114 @@
+
+// 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_FIBER_DETAIL_ATOMIC_GCC_PPC_H
+#define BOOST_FIBER_DETAIL_ATOMIC_GCC_PPC_H
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+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)
+{
+ uint32_t r;
+
+ __asm__ __volatile__
+ (
+ "0:\n\t"
+ "lwarx %0, 0, %2 \n\t"
+ "stwcx. %1, 0, %2 \n\t"
+ "bne- 1b" :
+ "=r" ( r) :
+ "r" ( desired), "r" ( object)
+ );
+}
+
+inline
+bool atomic_compare_exchange_strong( uint32_t volatile * object, uint32_t * expected, uint32_t desired)
+{
+ uint32_t prev = * expected;
+
+ __asm__ __volatile__
+ (
+ "0:\n\t"
+ "lwarx %0,0,%1\n\t"
+ "cmpw %0,%3\n\t"
+ "bne- 1f\n\t"
+ "stwcx. %2,0,%1\n\t"
+ "bne- 0b\n\t"
+ "1:"
+ : "=&r"( * expected)
+ : "b" ( object), "r" ( desired), "r" ( * expected)
+ : "memory", "cc"
+ );
+ if ( prev != * expected)
+ {
+ * expected = prev;
+ return false;
+ }
+ return true;
+}
+
+inline
+uint32_t atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
+{
+ int object_ = static_cast< int >( object);
+ int operand_ = static_cast< int >( operand);
+ int r, t;
+
+ __asm__ __volatile__
+ (
+ "0:\n\t"
+ "lwarx %0,0,%2\n\t"
+ "add %1,%0,%3\n\t"
+ "stwcx. %1,0,%2\n\t"
+ "bne- 0b"
+ : "=&r" ( r), "=&r" ( t)
+ : "b" ( object_), "r" ( operand_)
+ : "memory", "cc"
+ );
+
+ return r;
+}
+
+inline
+uint32_t atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
+{
+ int object_ = static_cast< int >( object);
+ int operand_ = static_cast< int >( -1 * operand);
+ int r;
+
+ __asm__ __volatile__
+ (
+ "0:\n\t"
+ "lwarx %0,0,%2\n\t"
+ "add %1,%0,%3\n\t"
+ "stwcx. %1,0,%2\n\t"
+ "bne- 0b"
+ : "=&r" ( r), "=&r" ( t)
+ : "b" ( object_), "r" ( operand_)
+ : "memory", "cc"
+ );
+
+ return r;
+}
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBER_DETAIL_ATOMIC_GCC_PPC_H
+

Added: sandbox/fiber/boost/fiber/detail/atomic_gcc_x86.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/atomic_gcc_x86.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,91 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBER_DETAIL_ATOMIC_GCC_X86_H
+#define BOOST_FIBER_DETAIL_ATOMIC_GCC_X86_H
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+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)
+{
+ __asm__ __volatile__
+ (
+ "xchg %0, %1" :
+ "+r" ( desired), "+m" ( * object)
+ );
+}
+
+inline
+bool atomic_compare_exchange_strong( uint32_t volatile * object, uint32_t * expected, uint32_t desired)
+{
+ uint32_t prev = * expected;
+
+ __asm__ __volatile__
+ (
+ "lock\n\t"
+ "cmpxchg %3, %1"
+ : "=a" ( * expected), "=m" ( * object)
+ : "a" ( prev), "r" ( desired)
+ : "memory", "cc"
+ );
+
+ return prev == * expected;
+}
+
+inline
+long atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
+{
+ int operand_ = static_cast< int >( operand);
+ int r;
+
+ __asm__ __volatile__
+ (
+ "lock\n\t"
+ "xadd %1, %0" :
+ "+m"( * object), "=r"( r):
+ "1"( operand_):
+ "memory", "cc"
+ );
+
+ return r;
+}
+
+inline
+long atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
+{
+ int operand_ = static_cast< int >( -1 * operand);
+ int r;
+
+ __asm__ __volatile__
+ (
+ "lock\n\t"
+ "xadd %1, %0":
+ "+m"( * object), "=r"( r ):
+ "1"( operand_):
+ "memory", "cc"
+ );
+
+ return r;
+}
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBER_DETAIL_ATOMIC_GCC_X86_H
+

Added: sandbox/fiber/boost/fiber/detail/atomic_hpux.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/atomic_hpux.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,62 @@
+
+// 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_FIBER_DETAIL_ATOMIC_HPUX_H
+#define BOOST_FIBER_DETAIL_ATOMIC_HPUX_H
+
+extern "C"
+{
+#include <atomic.h>
+}
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+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; }
+
+inline
+bool atomic_compare_exchange_strong( uint32_t volatile * object, uint32_t * expected, uint32_t desired)
+{
+ uint32_t prev = ::atomic_cas_32( object, * expected, desired);
+ if ( prev != * expected)
+ {
+ * expected = prev;
+ return false;
+ }
+ return true;
+}
+
+inline
+uint32_t atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return ::atomic_inc( object);
+}
+
+inline
+uint32_t atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return ::atomic_dec( object);
+}
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBER_DETAIL_ATOMIC_HPUX_H
+

Added: sandbox/fiber/boost/fiber/detail/atomic_interlocked.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/atomic_interlocked.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,66 @@
+
+// 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_FIBER_DETAIL_ATOMIC_INTERLOCKED_H
+#define BOOST_FIBER_DETAIL_ATOMIC_INTERLOCKED_H
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/detail/interlocked.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+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),
+ static_cast< long >( desired) );
+}
+
+inline
+bool atomic_compare_exchange_strong( uint32_t volatile * object, uint32_t * expected, uint32_t desired)
+{
+ uint32_t prev = BOOST_INTERLOCKED_COMPARE_EXCHANGE(
+ reinterpret_cast< long volatile * >( object),
+ static_cast< long >( desired),
+ static_cast< long >( * expected) );
+ if ( prev != * expected)
+ {
+ * expected = prev;
+ return false;
+ }
+ return true;
+}
+
+inline
+uint32_t atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return BOOST_INTERLOCKED_INCREMENT( reinterpret_cast< long volatile * >( object) ) - 1;
+}
+
+inline
+uint32_t atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return BOOST_INTERLOCKED_DECREMENT( reinterpret_cast< long volatile * >( object) ) + 1;
+}
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBER_DETAIL_ATOMIC_INTERLOCKED_H
+

Added: sandbox/fiber/boost/fiber/detail/atomic_interprocess.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/atomic_interprocess.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,59 @@
+
+// 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_FIBER_DETAIL_ATOMIC_INTERPROCESS_H
+#define BOOST_FIBER_DETAIL_ATOMIC_INTERPROCESS_H
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/interprocess/detail/atomic.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+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); }
+
+inline
+bool atomic_compare_exchange_strong( uint32_t volatile * object, uint32_t * expected, uint32_t desired)
+{
+ uint32_t prev = interprocess::detail::atomic_cas32( object, desired, * expected);
+ if ( prev != * expected)
+ {
+ * expected = prev;
+ return false;
+ }
+ return true;
+}
+
+inline
+unsigned int atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return interprocess::detail::atomic_inc32( object);
+}
+
+inline
+unsigned int atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return interprocess::detail::atomic_dec32( object);
+}
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBER_DETAIL_ATOMIC_INTERPROCESS_H
+

Added: sandbox/fiber/boost/fiber/detail/atomic_solaris.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/atomic_solaris.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,63 @@
+
+// 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_FIBER_DETAIL_ATOMIC_SOLARIS_H
+#define BOOST_FIBER_DETAIL_ATOMIC_SOLARIS_H
+
+extern "C"
+{
+#include <atomic.h>
+}
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+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; }
+
+inline
+bool atomic_compare_exchange_strong( uint32_t volatile * object, uint32_t * expected, uint32_t desired)
+{
+ uint32_t prev = ::atomic_cas_32( object, * expected, desired);
+ if ( prev != * expected)
+ {
+ * expected = prev;
+ return false;
+ }
+ return true;
+}
+
+inline
+uint32_t atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return ::atomic_inc_32( object);
+}
+
+inline
+uint32_t atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return ::atomic_dec_32( object);
+}
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBER_DETAIL_ATOMIC_SOLARIS_H
+

Added: sandbox/fiber/boost/fiber/detail/atomic_sync.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/atomic_sync.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 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)
+
+#ifndef BOOST_FIBER_DETAIL_ATOMIC_SYNC_H
+#define BOOST_FIBER_DETAIL_ATOMIC_SYNC_H
+
+// based on boost/smart_ptr/detail/atomic_count_gc.hpp
+
+# if defined( __ia64__ ) && defined( __INTEL_COMPILER )
+extern "C"
+{
+#include<ia64intrin.h>
+}
+# endif
+
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+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; }
+
+inline
+bool atomic_compare_exchange_strong( uint32_t volatile * object, uint32_t * expected, uint32_t desired)
+{
+ uint32_t prev = __sync_val_compare_and_swap( object, * expected, desired);
+ if ( prev != * expected)
+ {
+ * expected = prev;
+ return false;
+ }
+ return true;
+}
+
+inline
+uint32_t atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return __sync_fetch_and_add( object, 1);
+}
+
+inline
+uint32_t atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
+{
+ BOOST_ASSERT( operand == 1);
+ return __sync_fetch_and_add( object, -1);
+}
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBER_DETAIL_ATOMIC_SYNC_H
+

Added: sandbox/fiber/boost/fiber/detail/fiber_info_windows.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/fiber_info_windows.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,86 @@
+
+// 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_FIBER_DETAIL_FIBER_INFO_WINDOWS_H
+#define BOOST_FIBER_DETAIL_FIBER_INFO_WINDOWS_H
+
+extern "C" {
+
+#include <windows.h>
+#include <winnt.h>
+
+}
+
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/shared_array.hpp>
+
+#include <boost/fiber/attributes.hpp>
+#include <boost/fiber/detail/config.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+namespace detail {
+
+struct BOOST_FIBER_DECL fiber_info_base
+{
+ typedef intrusive_ptr< fiber_info_base > ptr_t;
+
+ uint32_t use_count;
+ attributes attribs;
+ LPVOID uctx;
+
+ static void convert_thread_to_fiber() {}
+
+ fiber_info_base();
+
+ fiber_info_base( attributes const&);
+
+ virtual ~fiber_info_base() {}
+
+ virtual void run() = 0;
+
+#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+
+ inline friend void intrusive_ptr_add_ref( fiber_info_base * p)
+ { ++p->use_count; }
+
+ inline friend void intrusive_ptr_release( fiber_info_base * p)
+ { if ( --p->use_count == 0) delete p; }
+
+#else
+
+ void add_ref()
+ { ++use_count; }
+
+ void release()
+ { if ( --use_count == 0) delete this; }
+
+#endif
+};
+
+}}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+
+inline
+void intrusive_ptr_add_ref( fiber::detail::fiber_info_base * p)
+{ p->add_ref(); }
+
+inline
+void intrusive_ptr_release( fiber::detail::fiber_info_base * p)
+{ p->release(); }
+
+#endif
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBER_DETAIL_FIBER_INFO_WINDOWS_H

Added: sandbox/fiber/boost/fiber/detail/has_sync.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/has_sync.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,49 @@
+#ifndef BOOST_FIBER_DETAIL_HAS_SYNC_H
+#define BOOST_FIBER_DETAIL_HAS_SYNC_H
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// based on boost/smart_ptr/detail/sp_has_sync.hpp
+//
+// Copyright (c) 2008, 2009 Peter Dimov
+//
+// 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)
+//
+// Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics
+// are available.
+//
+
+#if defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+
+#define BOOST_FIBER_HAS_SYNC
+
+#if defined( __arm__ ) || defined( __armel__ )
+#undef BOOST_FIBER_HAS_SYNC
+#endif
+
+#if defined( __hppa ) || defined( __hppa__ )
+#undef BOOST_FIBER_HAS_SYNC
+#endif
+
+#if defined( __m68k__ )
+#undef BOOST_FIBER_HAS_SYNC
+#endif
+
+#if defined( __sparc__ )
+#undef BOOST_FIBER_HAS_SYNC
+#endif
+
+#if defined( __INTEL_COMPILER ) && !defined( __ia64__ )
+#undef BOOST_FIBER_HAS_SYNC
+#endif
+
+#endif // __GNUC__ * 100 + __GNUC_MINOR__ >= 401
+
+#endif // BOOST_FIBER_DETAIL_HAS_SYNC_H

Modified: sandbox/fiber/boost/fiber/exceptions.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/exceptions.hpp (original)
+++ sandbox/fiber/boost/fiber/exceptions.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -31,6 +31,14 @@
         {}
 };
 
+class lock_error : public std::logic_error
+{
+public:
+ lock_error() :
+ std::logic_error("lock invalid")
+ {}
+};
+
 class scheduler_error : public std::runtime_error
 {
 public:

Added: sandbox/fiber/boost/fiber/manual_reset_event.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/manual_reset_event.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,52 @@
+
+// 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_FIBEr_MANUAL_RESET_EVENT_H
+#define BOOST_FIBEr_MANUAL_RESET_EVENT_H
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/mutex.hpp>
+
+namespace boost {
+namespace fiber {
+
+class manual_reset_event : private noncopyable
+{
+private:
+ enum state_t
+ {
+ RESET = 0,
+ SET
+ };
+
+ volatile uint32_t state_;
+ volatile uint32_t waiters_;
+ mutex enter_mtx_;
+
+public:
+ explicit 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); }
+
+ bool try_wait();
+};
+
+}}
+
+#endif // BOOST_FIBER_MANUAL_RESET_EVENT_H

Added: sandbox/fiber/boost/fiber/mutex.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/mutex.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 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)
+//
+// based on boost::interprocess::sync::interprocess_mutex
+
+#ifndef BOOST_FIBER_MUTEX_H
+#define BOOST_FIBER_MUTEX_H
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/unique_lock.hpp>
+
+namespace boost {
+namespace fiber {
+
+class mutex : private noncopyable
+{
+private:
+ volatile uint32_t state_;
+
+public:
+ typedef unique_lock< mutex > scoped_lock;
+
+ mutex();
+
+ void lock();
+
+ bool try_lock();
+
+ bool timed_lock( system_time const& abs_time);
+
+ template< typename TimeDuration >
+ bool timed_lock( TimeDuration const& rel_time)
+ { return timed_lock( get_system_time() + rel_time); }
+
+ void unlock();
+};
+
+typedef mutex try_mutex;
+
+}}
+
+#endif // BOOST_FIBER_MUTEX_H

Added: sandbox/fiber/boost/fiber/unique_lock.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/unique_lock.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,147 @@
+
+// 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::scoped_lock
+
+#ifndef BOOST_FIBER_UNIQUE_LOCK_H
+#define BOOST_FIBER_UNIQUE_LOCK_H
+
+#include <algorithm>
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/thread_time.hpp>
+
+#include <boost/fiber/exceptions.hpp>
+
+namespace boost {
+namespace fiber {
+
+template< typename Mutex >
+class unique_lock
+{
+private:
+ typedef unique_lock< Mutex > lock_t;
+ typedef bool unique_lock::*unspecified_bool_type;
+
+ Mutex * mtx_;
+ bool locked_;
+
+ unique_lock( unique_lock &);
+ unique_lock & operator=( unique_lock &);
+
+public:
+ unique_lock() :
+ mtx_( 0),
+ locked_( false)
+ {}
+
+ explicit unique_lock( Mutex & mtx) :
+ mtx_( & mtx),
+ locked_( false)
+ {
+ mtx_->lock();
+ locked_ = true;
+ }
+
+ unique_lock( Mutex & mtx, adopt_lock_t) :
+ mtx_( & mtx),
+ locked_( true)
+ {}
+
+ unique_lock( Mutex & mtx, defer_lock_t) :
+ mtx_( & mtx),
+ locked_( false)
+ {}
+
+ unique_lock( Mutex & mtx, try_to_lock_t) :
+ mtx_( & mtx),
+ locked_( mtx_->try_lock() )
+ {}
+
+ unique_lock( Mutex & mtx, system_time const& abs_time) :
+ mtx_( & mtx),
+ locked_( mtx_->timed_lock( abs_time) )
+ {}
+
+ template< typename TimeDuration >
+ unique_lock( Mutex & mtx, TimeDuration const& rel_time) :
+ mtx_( & mtx),
+ locked_( mtx_->timed_lock( rel_time) )
+ {}
+
+ ~unique_lock()
+ {
+ try
+ { if ( locked_ && mtx_) mtx_->unlock(); }
+ catch (...) {}
+ }
+
+ void lock()
+ {
+ if ( ! mtx_ || locked_)
+ throw lock_error();
+ mtx_->lock();
+ locked_ = true;
+ }
+
+ bool try_lock()
+ {
+ if ( ! mtx_ || locked_)
+ throw lock_error();
+ locked_ = mtx_->try_lock();
+ return locked_;
+ }
+
+ bool timed_lock( system_time const& abs_time)
+ {
+ if ( ! mtx_ || locked_)
+ throw lock_error();
+ locked_ = mtx_->timed_lock( abs_time);
+ return locked_;
+ }
+
+ template< typename TimeDuration >
+ bool timed_lock( TimeDuration const& rel_time)
+ { return timed_lock( get_system_time() + rel_time); }
+
+ void unlock()
+ {
+ if ( ! mtx_ || ! locked_)
+ throw lock_error();
+ mtx_->unlock();
+ locked_ = false;
+ }
+
+ bool owns_lock() const
+ { return locked_ && mtx_; }
+
+ operator unspecified_bool_type() const
+ { return locked_ ? & lock_t::locked_ : 0; }
+
+ bool operator!() const
+ { return ! locked_; }
+
+ Mutex * mutex() const
+ { return mtx_; }
+
+ Mutex * release()
+ {
+ Mutex * mtx = mtx_;
+ mtx_ = 0;
+ locked_ = false;
+ return mtx;
+ }
+
+ void swap( unique_lock & other)
+ {
+ std::swap( mtx_, other.mtx_);
+ std::swap( locked_, other.locked_);
+ }
+};
+
+}}
+
+#endif // BOOST_FIBER_UNIQUE_LOCK_H

Modified: sandbox/fiber/boost/fiber/utility.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/utility.hpp (original)
+++ sandbox/fiber/boost/fiber/utility.hpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -20,6 +20,10 @@
 namespace this_fiber {
 
 inline
+void interruption_point()
+{}
+
+inline
 bool runs_as_fiber()
 { return fiber::scheduler::runs_as_fiber(); }
 

Modified: sandbox/fiber/libs/fiber/build/Jamfile.v2
==============================================================================
--- sandbox/fiber/libs/fiber/build/Jamfile.v2 (original)
+++ sandbox/fiber/libs/fiber/build/Jamfile.v2 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -36,9 +36,13 @@
 alias fiber_sources
     : ## win32 sources ##
         attributes.cpp
+ condition.cpp
+ count_down_event.cpp
         fiber.cpp
         fiber_info_windows.cpp
         fiber_windows.cpp
+ manual_reset_event.cpp
+ mutex.cpp
         rrp.cpp
         scheduler.cpp
     : ## requirements ##
@@ -48,9 +52,13 @@
 alias fiber_sources
     : ## posix sources ##
         attributes.cpp
+ condition.cpp
+ count_down_event.cpp
         fiber.cpp
         fiber_info_posix.cpp
         fiber_posix.cpp
+ manual_reset_event.cpp
+ mutex.cpp
         rrp.cpp
         scheduler.cpp
     : ## requirements ##

Added: sandbox/fiber/libs/fiber/src/auto_reset_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/auto_reset_event.cpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 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)
+
+#include "boost/fiber/auto_reset_event.hpp"
+
+#include <boost/fiber/detail/atomic.hpp>
+#include <boost/fiber/utility.hpp>
+
+namespace boost {
+namespace fiber {
+
+auto_reset_event::auto_reset_event( bool isset) :
+ state_(
+ isset ?
+ static_cast< uint32_t >( SET) :
+ static_cast< uint32_t >( RESET) )
+{}
+
+void
+auto_reset_event::set()
+{ detail::atomic_exchange( & state_, static_cast< uint32_t >( SET) ); }
+
+void
+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::interruption_point();
+ this_fiber::yield();
+ this_fiber::interruption_point();
+ expected = static_cast< uint32_t >( SET);
+ }
+}
+
+bool
+auto_reset_event::wait( system_time const& abs_time)
+{
+ if ( get_system_time() >= abs_time) return false;
+
+ uint32_t expected = static_cast< uint32_t >( SET);
+ while ( ! detail::atomic_compare_exchange_strong(
+ & state_, & expected,
+ static_cast< uint32_t >( RESET) ) )
+ {
+ this_fiber::interruption_point();
+ this_fiber::yield();
+ this_fiber::interruption_point();
+
+ if ( get_system_time() >= abs_time) return false;
+ expected = static_cast< uint32_t >( SET);
+ }
+
+ return true;
+}
+
+bool
+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/condition.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/condition.cpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,185 @@
+
+// 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/condition.hpp"
+
+#include <boost/assert.hpp>
+#include <boost/thread.hpp>
+
+#include <boost/fiber/detail/atomic.hpp>
+#include <boost/fiber/mutex.hpp>
+#include <boost/fiber/utility.hpp>
+
+namespace boost {
+namespace fiber {
+
+void
+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::interruption_point();
+ this_fiber::yield();
+ this_fiber::interruption_point();
+ }
+}
+
+void
+condition::wait_( mutex & mtx)
+{
+ {
+ 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::interruption_point();
+ this_fiber::yield();
+ this_fiber::interruption_point();
+ }
+
+ 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();
+}
+
+bool
+condition::wait_( mutex & mtx, system_time const& abs_time)
+{
+ if ( get_system_time() >= abs_time) return false;
+
+ {
+ mutex::scoped_lock lk( enter_mtx_, abs_time);
+ BOOST_ASSERT( lk);
+ detail::atomic_fetch_add( & waiters_, 1);
+ mtx.unlock();
+ }
+
+ bool timed_out = false, unlock_enter_mtx = false;
+ for (;;)
+ {
+ while ( static_cast< uint32_t >( SLEEPING) == detail::atomic_load( & cmd_) )
+ {
+ this_fiber::interruption_point();
+ this_fiber::yield();
+ this_fiber::interruption_point();
+
+ 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
+ {
+ 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();
+
+ return ! timed_out;
+}
+
+condition::condition() :
+ cmd_( static_cast< uint32_t >( SLEEPING) ),
+ waiters_( 0),
+ enter_mtx_(),
+ check_mtx_()
+{}
+
+void
+condition::notify_one()
+{ notify_( static_cast< uint32_t >( NOTIFY_ONE) ); }
+
+void
+condition::notify_all()
+{ notify_( static_cast< uint32_t >( NOTIFY_ALL) ); }
+
+}}

Added: sandbox/fiber/libs/fiber/src/count_down_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/count_down_event.cpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,74 @@
+
+// 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/count_down_event.hpp"
+
+#include <boost/fiber/detail/atomic.hpp>
+#include <boost/fiber/mutex.hpp>
+#include <boost/fiber/utility.hpp>
+
+namespace boost {
+namespace fiber {
+
+count_down_event::count_down_event( uint32_t initial) :
+ initial_( initial),
+ current_( initial_)
+{}
+
+uint32_t
+count_down_event::initial() const
+{ return initial_; }
+
+uint32_t
+count_down_event::current() const
+{ return detail::atomic_load( & current_); }
+
+bool
+count_down_event::is_set() const
+{ return 0 == detail::atomic_load( & current_); }
+
+void
+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
+count_down_event::wait()
+{
+ while ( 0 != detail::atomic_load( & current_) )
+ {
+ this_fiber::interruption_point();
+ this_fiber::yield();
+ this_fiber::interruption_point();
+ }
+}
+
+bool
+count_down_event::wait( system_time const& abs_time)
+{
+ if ( get_system_time() >= abs_time) return false;
+
+ while ( 0 < detail::atomic_load( & current_) )
+ {
+ this_fiber::interruption_point();
+ this_fiber::yield();
+ this_fiber::interruption_point();
+
+ if ( get_system_time() >= abs_time) return false;
+ }
+
+ return true;
+}
+
+}}

Added: sandbox/fiber/libs/fiber/src/fiber_info_windows.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/fiber_info_windows.cpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 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)
+
+#include <boost/fiber/detail/fiber_info_posix.hpp>
+
+#include <cerrno>
+
+#include <boost/assert.hpp>
+#include <boost/system/system_error.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+namespace detail {
+
+fiber_info_base::fiber_info_base() :
+ attribs(),
+ uctx(),
+ uctx_stack()
+{}
+
+fiber_info_base::fiber_info_base( attributes const& attribs_) :
+ attribs( attribs_),
+ uctx(),
+ uctx_stack( new char[attribs.stack_size()])
+{
+ BOOST_ASSERT( uctx_stack);
+
+ if ( ::getcontext( & uctx) == -1)
+ throw system::system_error(
+ system::error_code(
+ errno,
+ system::system_category) );
+ uctx.uc_stack.ss_sp = uctx_stack.get();
+ uctx.uc_stack.ss_size = attribs.stack_size();
+ uctx.uc_link = 0;
+}
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>

Added: sandbox/fiber/libs/fiber/src/fiber_windows.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/fiber_windows.cpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 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)
+
+#include <boost/fiber/fiber.hpp>
+
+extern "C" {
+
+#include <windows.h>
+#include <winnt.h>
+
+}
+
+#include <cerrno>
+
+#include <boost/system/system_error.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fiber {
+
+void
+fiber::init_()
+{
+ typedef void fn_type( fiber *);
+ typedef void ( * st_fn)();
+ fn_type * fn_ptr( trampoline);
+
+ info_->uctx = ::CreateFiber(
+ info_->stack_size_,
+ static_cast< LPFIBER_START_ROUTINE >( & trampoline< fiber >),
+ static_cast< LPVOID >( this) );
+}
+
+void
+fiber::switch_to( fiber & to)
+{
+ if ( ::SiwtchToFiber( & info_->uctx) != 0)
+ throw system::system_error(
+ system::error_code(
+ ::GetLastError(),
+ system::system_category) );
+}
+
+}}
+
+#include <boost/config/abi_suffix.hpp>

Added: sandbox/fiber/libs/fiber/src/manual_reset_event.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/manual_reset_event.cpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,103 @@
+
+// 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/manual_reset_event.hpp"
+
+#include <boost/assert.hpp>
+
+#include <boost/fiber/detail/atomic.hpp>
+#include <boost/fiber/utility.hpp>
+
+namespace boost {
+namespace fiber {
+
+manual_reset_event::manual_reset_event( bool isset) :
+ state_(
+ isset ?
+ static_cast< uint32_t >( SET) :
+ static_cast< uint32_t >( RESET) ),
+ waiters_( 0),
+ enter_mtx_()
+{}
+
+void
+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
+manual_reset_event::reset()
+{
+ mutex::scoped_lock lk( enter_mtx_);
+ BOOST_ASSERT( lk);
+
+ detail::atomic_exchange( & state_,
+ static_cast< uint32_t >( RESET) );
+}
+
+void
+manual_reset_event::wait()
+{
+ {
+ 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::interruption_point();
+ this_fiber::yield();
+ this_fiber::interruption_point();
+ }
+
+ if ( 1 == detail::atomic_fetch_sub( & waiters_, 1) )
+ enter_mtx_.unlock();
+}
+
+bool
+manual_reset_event::wait( system_time const& abs_time)
+{
+ if ( get_system_time() >= abs_time) return false;
+
+ while ( static_cast< uint32_t >( RESET) == detail::atomic_load( & state_) )
+ {
+ this_fiber::interruption_point();
+ this_fiber::yield();
+ this_fiber::interruption_point();
+
+ if ( get_system_time() >= abs_time) return false;
+ }
+
+ return true;
+}
+
+bool
+manual_reset_event::try_wait()
+{
+ {
+ 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/mutex.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/mutex.cpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,77 @@
+
+// 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/mutex.hpp"
+
+#include "boost/fiber/detail/atomic.hpp"
+#include "boost/fiber/utility.hpp"
+
+namespace boost {
+namespace fiber {
+
+mutex::mutex() :
+ state_( 0)
+{}
+
+void
+mutex::lock()
+{
+ for (;;)
+ {
+ uint32_t expected = 0;
+ if ( detail::atomic_compare_exchange_strong( & state_, & expected, 1) )
+ break;
+ else
+ {
+ this_fiber::interruption_point();
+ this_fiber::yield();
+ this_fiber::interruption_point();
+ }
+ }
+}
+
+bool
+mutex::try_lock()
+{
+ uint32_t expected = 0;
+ return detail::atomic_compare_exchange_strong( & state_, & expected, 1);
+}
+
+bool
+mutex::timed_lock( system_time const& abs_time)
+{
+ if ( abs_time.is_infinity() )
+ {
+ lock();
+ return true;
+ }
+
+ if ( get_system_time() >= abs_time)
+ return false;
+
+ for (;;)
+ {
+ if ( try_lock() ) break;
+
+ if ( get_system_time() >= abs_time)
+ return false;
+
+ this_fiber::interruption_point();
+ this_fiber::yield();
+ this_fiber::interruption_point();
+ }
+
+ return true;
+}
+
+void
+mutex::unlock()
+{
+ uint32_t expected = 1;
+ detail::atomic_compare_exchange_strong( & state_, & expected, 0);
+}
+
+}}

Modified: sandbox/fiber/libs/fiber/test/Jamfile.v2
==============================================================================
--- sandbox/fiber/libs/fiber/test/Jamfile.v2 (original)
+++ sandbox/fiber/libs/fiber/test/Jamfile.v2 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -28,4 +28,5 @@
     [ fiber-test test_fiber ]
     [ fiber-test test_rrp ]
     [ fiber-test test_utility ]
+ [ fiber-test test_mutex ]
     ;

Added: sandbox/fiber/libs/fiber/test/test_mutex.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/test/test_mutex.cpp 2009-11-08 14:13:43 EST (Sun, 08 Nov 2009)
@@ -0,0 +1,83 @@
+
+// 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/date_time/posix_time/posix_time.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber.hpp>
+
+#include <libs/task/test/util.ipp>
+
+template< typename M >
+struct test_lock
+{
+ typedef M mutex_type;
+ typedef typename M::scoped_lock lock_type;
+
+ void operator()()
+ {
+ mutex_type mutex;
+ boost::fiber::condition condition;
+
+ // Test the lock's constructors.
+ {
+ lock_type lock(mutex, boost::defer_lock);
+ BOOST_CHECK(!lock);
+ }
+ lock_type lock(mutex);
+ BOOST_CHECK(lock ? true : false);
+
+ // Construct and initialize an xtime for a fast time out.
+ boost::posix_time::time_duration xt = boost::posix_time::milliseconds( 100);
+
+ // Test the lock and the mutex with condition variables.
+ // No one is going to notify this condition variable. We expect to
+ // time out.
+ BOOST_CHECK(!condition.timed_wait(lock, xt));
+ 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_mutex()
+{
+ test_lock< boost::fiber::mutex >()();
+}
+
+void test_mutex()
+{
+ boost::fiber::scheduler sched;
+ sched.make_fiber( & do_test_mutex);
+ sched.run();
+}
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+ boost::unit_test_framework::test_suite * test =
+ BOOST_TEST_SUITE("Boost.Fiber: mutex test suite");
+
+ test->add(BOOST_TEST_CASE(&test_mutex));
+
+ 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