Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r82840 - in trunk: boost/coroutine boost/coroutine/detail libs/coroutine/build libs/coroutine/detail libs/coroutine/doc libs/coroutine/example libs/coroutine/performance libs/coroutine/src libs/coroutine/src/detail libs/coroutine/test
From: oliver.kowalke_at_[hidden]
Date: 2013-02-12 14:01:35


Author: olli
Date: 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
New Revision: 82840
URL: http://svn.boost.org/trac/boost/changeset/82840

Log:
coroutine: support for segmented stacks added

Added:
   trunk/boost/coroutine/detail/coroutine_context.hpp (contents, props changed)
   trunk/boost/coroutine/detail/segmented_stack_allocator.hpp (contents, props changed)
   trunk/boost/coroutine/detail/standard_stack_allocator.hpp (contents, props changed)
   trunk/boost/coroutine/stack_context.hpp (contents, props changed)
   trunk/libs/coroutine/build/
   trunk/libs/coroutine/build/Jamfile.v2 (contents, props changed)
   trunk/libs/coroutine/detail/
   trunk/libs/coroutine/detail/coroutine_context.cpp (contents, props changed)
   trunk/libs/coroutine/detail/segmented_stack_allocator.cpp (contents, props changed)
   trunk/libs/coroutine/detail/standard_stack_allocator_posix.cpp (contents, props changed)
   trunk/libs/coroutine/detail/standard_stack_allocator_windows.cpp (contents, props changed)
   trunk/libs/coroutine/example/segmented_stack.cpp (contents, props changed)
   trunk/libs/coroutine/src/
   trunk/libs/coroutine/src/detail/
   trunk/libs/coroutine/src/detail/coroutine_context.cpp (contents, props changed)
   trunk/libs/coroutine/src/detail/segmented_stack_allocator.cpp (contents, props changed)
   trunk/libs/coroutine/src/detail/standard_stack_allocator_posix.cpp (contents, props changed)
   trunk/libs/coroutine/src/detail/standard_stack_allocator_windows.cpp (contents, props changed)
Removed:
   trunk/boost/coroutine/detail/stack_allocator_posix.hpp
   trunk/boost/coroutine/detail/stack_allocator_windows.hpp
Text files modified:
   trunk/boost/coroutine/coroutine.hpp | 6
   trunk/boost/coroutine/detail/config.hpp | 7
   trunk/boost/coroutine/detail/coroutine_base.hpp | 34 +++
   trunk/boost/coroutine/detail/coroutine_base_resume.hpp | 88 ++++++------
   trunk/boost/coroutine/detail/coroutine_caller.hpp | 2
   trunk/boost/coroutine/detail/coroutine_object.hpp | 23 +++
   trunk/boost/coroutine/detail/coroutine_object_result_0.ipp | 192 ++++++++++++--------------
   trunk/boost/coroutine/detail/coroutine_object_result_1.ipp | 275 +++++++++++++++++--------------------
   trunk/boost/coroutine/detail/coroutine_object_result_arity.ipp | 275 +++++++++++++++++--------------------
   trunk/boost/coroutine/detail/coroutine_object_void_0.ipp | 190 ++++++++++++-------------
   trunk/boost/coroutine/detail/coroutine_object_void_1.ipp | 287 ++++++++++++++++++---------------------
   trunk/boost/coroutine/detail/coroutine_object_void_arity.ipp | 287 ++++++++++++++++++---------------------
   trunk/boost/coroutine/detail/holder.hpp | 16 +
   trunk/boost/coroutine/stack_allocator.hpp | 30 +++-
   trunk/libs/coroutine/doc/Jamfile.v2 | 14 +
   trunk/libs/coroutine/doc/coro.qbk | 2
   trunk/libs/coroutine/doc/stack.qbk | 72 ++++++++-
   trunk/libs/coroutine/example/Jamfile.v2 | 16 -
   trunk/libs/coroutine/example/fibonacci.cpp | 45 +++++-
   trunk/libs/coroutine/performance/Jamfile.v2 | 4
   trunk/libs/coroutine/performance/performance.cpp | 13 +
   trunk/libs/coroutine/performance/simple_stack_allocator.hpp | 18 +-
   trunk/libs/coroutine/test/Jamfile.v2 | 2
   23 files changed, 983 insertions(+), 915 deletions(-)

Modified: trunk/boost/coroutine/coroutine.hpp
==============================================================================
--- trunk/boost/coroutine/coroutine.hpp (original)
+++ trunk/boost/coroutine/coroutine.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -12,7 +12,6 @@
 
 #include <boost/assert.hpp>
 #include <boost/config.hpp>
-#include <boost/context/fcontext.hpp>
 #include <boost/move/move.hpp>
 #include <boost/range.hpp>
 #include <boost/static_assert.hpp>
@@ -25,6 +24,7 @@
 
 #include <boost/coroutine/attributes.hpp>
 #include <boost/coroutine/detail/arg.hpp>
+#include <boost/coroutine/detail/coroutine_context.hpp>
 #include <boost/coroutine/detail/coroutine_base.hpp>
 #include <boost/coroutine/detail/coroutine_get.hpp>
 #include <boost/coroutine/detail/coroutine_object.hpp>
@@ -118,7 +118,7 @@
     BOOST_MOVABLE_BUT_NOT_COPYABLE( coroutine)
 
     template< typename Allocator >
- coroutine( context::fcontext_t * callee,
+ coroutine( detail::coroutine_context const& callee,
                bool unwind, bool preserve_fpu,
                Allocator const& alloc) :
         detail::coroutine_op<
@@ -665,7 +665,7 @@
     BOOST_MOVABLE_BUT_NOT_COPYABLE( coroutine)
 
     template< typename Allocator >
- coroutine( context::fcontext_t * callee,
+ coroutine( detail::coroutine_context const& callee,
                bool unwind, bool preserve_fpu,
                Allocator const& alloc) :
         detail::coroutine_op<

Modified: trunk/boost/coroutine/detail/config.hpp
==============================================================================
--- trunk/boost/coroutine/detail/config.hpp (original)
+++ trunk/boost/coroutine/detail/config.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -39,4 +39,11 @@
 # include <boost/config/auto_link.hpp>
 #endif
 
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+# if ! (defined(__GNUC__) && __GNUC__ > 3 && __GNUC_MINOR__ > 6)
+# error "compiler does not support segmented stacks"
+# endif
+# define BOOST_COROUTINES_SEGMENTS 10
+#endif
+
 #endif // BOOST_COROUTINES_DETAIL_CONFIG_H

Modified: trunk/boost/coroutine/detail/coroutine_base.hpp
==============================================================================
--- trunk/boost/coroutine/detail/coroutine_base.hpp (original)
+++ trunk/boost/coroutine/detail/coroutine_base.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -16,6 +16,7 @@
 #include <boost/utility.hpp>
 
 #include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/coroutine_context.hpp>
 #include <boost/coroutine/detail/coroutine_base_resume.hpp>
 #include <boost/coroutine/detail/flags.hpp>
 
@@ -25,6 +26,9 @@
 
 namespace boost {
 namespace coroutines {
+
+struct stack_context;
+
 namespace detail {
 
 template< typename Signature >
@@ -45,17 +49,35 @@
     template< typename X, typename Y, typename Z, typename A, typename B, typename C, int >
     friend class coroutine_object;
 
- unsigned int use_count_;
- context::fcontext_t caller_;
- context::fcontext_t * callee_;
- int flags_;
- exception_ptr except_;
+ unsigned int use_count_;
+ coroutine_context caller_;
+ coroutine_context callee_;
+ int flags_;
+ exception_ptr except_;
 
 protected:
     virtual void deallocate_object() = 0;
 
 public:
- coroutine_base( context::fcontext_t * callee, bool unwind, bool preserve_fpu) :
+ coroutine_base( coroutine_context::ctx_fn fn, stack_context * stack_ctx,
+ bool unwind, bool preserve_fpu) :
+ coroutine_base_resume<
+ Signature,
+ coroutine_base< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ use_count_( 0),
+ caller_(),
+ callee_( fn, stack_ctx),
+ flags_( 0),
+ except_()
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ coroutine_base( coroutine_context const& callee, bool unwind, bool preserve_fpu) :
         coroutine_base_resume<
             Signature,
             coroutine_base< Signature >,

Modified: trunk/boost/coroutine/detail/coroutine_base_resume.hpp
==============================================================================
--- trunk/boost/coroutine/detail/coroutine_base_resume.hpp (original)
+++ trunk/boost/coroutine/detail/coroutine_base_resume.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -22,6 +22,7 @@
 
 #include <boost/coroutine/detail/arg.hpp>
 #include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/coroutine_context.hpp>
 #include <boost/coroutine/detail/exceptions.hpp>
 #include <boost/coroutine/detail/holder.hpp>
 
@@ -42,16 +43,15 @@
 public:
     void resume()
     {
- BOOST_ASSERT( static_cast< D * >( this)->callee_);
-
         holder< void > hldr_to( & static_cast< D * >( this)->caller_);
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- hldr_to.ctx,
- static_cast< D * >( this)->callee_,
- reinterpret_cast< intptr_t >( & hldr_to),
- static_cast< D * >( this)->preserve_fpu() ) ) );
- static_cast< D * >( this)->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ hldr_to.ctx->jump(
+ static_cast< D * >( this)->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ static_cast< D * >( this)->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx;
         if ( hldr_from->force_unwind) throw forced_unwind();
         if ( static_cast< D * >( this)->except_)
             rethrow_exception( static_cast< D * >( this)->except_);
@@ -66,16 +66,16 @@
     {
         BOOST_ASSERT( static_cast< D * >( this));
         BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() );
- BOOST_ASSERT( static_cast< D * >( this)->callee_);
 
         holder< void > hldr_to( & static_cast< D * >( this)->caller_);
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- hldr_to.ctx,
- static_cast< D * >( this)->callee_,
- reinterpret_cast< intptr_t >( & hldr_to),
- static_cast< D * >( this)->preserve_fpu() ) ) );
- static_cast< D * >( this)->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ hldr_to.ctx->jump(
+ static_cast< D * >( this)->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ static_cast< D * >( this)->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx;
         result_ = hldr_from->data;
         if ( hldr_from->force_unwind) throw forced_unwind();
         if ( static_cast< D * >( this)->except_)
@@ -99,16 +99,16 @@
     {
         BOOST_ASSERT( static_cast< D * >( this));
         BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() );
- BOOST_ASSERT( static_cast< D * >( this)->callee_);
 
         holder< arg_type > hldr_to( & static_cast< D * >( this)->caller_, a1);
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- hldr_to.ctx,
- static_cast< D * >( this)->callee_,
- reinterpret_cast< intptr_t >( & hldr_to),
- static_cast< D * >( this)->preserve_fpu() ) ) );
- static_cast< D * >( this)->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ hldr_to.ctx->jump(
+ static_cast< D * >( this)->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ static_cast< D * >( this)->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx;
         if ( hldr_from->force_unwind) throw forced_unwind();
         if ( static_cast< D * >( this)->except_)
             rethrow_exception( static_cast< D * >( this)->except_);
@@ -125,17 +125,17 @@
     {
         BOOST_ASSERT( static_cast< D * >( this));
         BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() );
- BOOST_ASSERT( static_cast< D * >( this)->callee_);
 
- context::fcontext_t caller;
+ coroutine_context caller;
         holder< arg_type > hldr_to( & static_cast< D * >( this)->caller_, a1);
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- hldr_to.ctx,
- static_cast< D * >( this)->callee_,
- reinterpret_cast< intptr_t >( & hldr_to),
- static_cast< D * >( this)->preserve_fpu() ) ) );
- static_cast< D * >( this)->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ hldr_to.ctx->jump(
+ static_cast< D * >( this)->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ static_cast< D * >( this)->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx;
         result_ = hldr_from->data;
         if ( hldr_from->force_unwind) throw forced_unwind();
         if ( static_cast< D * >( this)->except_)
@@ -167,18 +167,18 @@
     { \
         BOOST_ASSERT( static_cast< D * >( this)); \
         BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() ); \
- BOOST_ASSERT( static_cast< D * >( this)->callee_); \
 \
         holder< arg_type > hldr_to( \
             & static_cast< D * >( this)->caller_, \
             arg_type(BOOST_COROUTINE_BASE_RESUME_VALS(n) ) ); \
         holder< void > * hldr_from( \
- reinterpret_cast< holder< void > * >( context::jump_fcontext( \
- hldr_to.ctx, \
- static_cast< D * >( this)->callee_, \
- reinterpret_cast< intptr_t >( & hldr_to), \
- static_cast< D * >( this)->preserve_fpu() ) ) ); \
- static_cast< D * >( this)->callee_ = hldr_from->ctx; \
+ reinterpret_cast< holder< void > * >( \
+ hldr_to.ctx->jump( \
+ static_cast< D * >( this)->callee_, \
+ reinterpret_cast< intptr_t >( & hldr_to), \
+ static_cast< D * >( this)->preserve_fpu() ) ) ); \
+ BOOST_ASSERT( hldr_from->ctx); \
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx; \
         if ( hldr_from->force_unwind) throw forced_unwind(); \
         if ( static_cast< D * >( this)->except_) \
             rethrow_exception( static_cast< D * >( this)->except_); \
@@ -195,18 +195,18 @@
     { \
         BOOST_ASSERT( static_cast< D * >( this)); \
         BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() ); \
- BOOST_ASSERT( static_cast< D * >( this)->callee_); \
 \
         holder< arg_type > hldr_to( \
             & static_cast< D * >( this)->caller_, \
             arg_type(BOOST_COROUTINE_BASE_RESUME_VALS(n) ) ); \
         holder< Result > * hldr_from( \
- reinterpret_cast< holder< Result > * >( context::jump_fcontext( \
- hldr_to.ctx, \
- static_cast< D * >( this)->callee_, \
- reinterpret_cast< intptr_t >( & hldr_to), \
- static_cast< D * >( this)->preserve_fpu() ) ) ); \
- static_cast< D * >( this)->callee_ = hldr_from->ctx; \
+ reinterpret_cast< holder< Result > * >( \
+ hldr_to.ctx->jump( \
+ static_cast< D * >( this)->callee_, \
+ reinterpret_cast< intptr_t >( & hldr_to), \
+ static_cast< D * >( this)->preserve_fpu() ) ) ); \
+ BOOST_ASSERT( hldr_from->ctx); \
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx; \
         result_ = hldr_from->data; \
         if ( hldr_from->force_unwind) throw forced_unwind(); \
         if ( static_cast< D * >( this)->except_) \

Modified: trunk/boost/coroutine/detail/coroutine_caller.hpp
==============================================================================
--- trunk/boost/coroutine/detail/coroutine_caller.hpp (original)
+++ trunk/boost/coroutine/detail/coroutine_caller.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -29,7 +29,7 @@
         coroutine_caller< Signature, Allocator >
>::other allocator_t;
 
- coroutine_caller( context::fcontext_t * callee, bool unwind, bool preserve_fpu,
+ coroutine_caller( coroutine_context const& callee, bool unwind, bool preserve_fpu,
                     allocator_t const& alloc) BOOST_NOEXCEPT :
         coroutine_base< Signature >( callee, unwind, preserve_fpu),
         alloc_( alloc)

Added: trunk/boost/coroutine/detail/coroutine_context.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/detail/coroutine_context.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -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_COROUTINES_DETAIL_COROUTINE_CONTEXT_H
+#define BOOST_COROUTINES_DETAIL_COROUTINE_CONTEXT_H
+
+#include <cstddef>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/context/fcontext.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+#include "boost/coroutine/stack_context.hpp"
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+extern "C" void *__splitstack_makecontext(
+ std::size_t, void * [BOOST_COROUTINES_SEGMENTS], std::size_t *);
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+
+class BOOST_COROUTINES_DECL coroutine_context : private noncopyable,
+ private context::fcontext_t,
+ private stack_context
+
+{
+private:
+ stack_context * stack_ctx_;
+ context::fcontext_t * ctx_;
+
+public:
+ typedef void( * ctx_fn)( intptr_t);
+
+ coroutine_context();
+
+ explicit coroutine_context( ctx_fn, stack_context *);
+
+ coroutine_context( coroutine_context const&);
+
+ coroutine_context& operator=( coroutine_context const&);
+
+ intptr_t jump( coroutine_context &, intptr_t = 0, bool = true);
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_COROUTINE_CONTEXT_H

Modified: trunk/boost/coroutine/detail/coroutine_object.hpp
==============================================================================
--- trunk/boost/coroutine/detail/coroutine_object.hpp (original)
+++ trunk/boost/coroutine/detail/coroutine_object.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -7,6 +7,8 @@
 #ifndef BOOST_COROUTINES_DETAIL_COROUTINE_OBJECT_H
 #define BOOST_COROUTINES_DETAIL_COROUTINE_OBJECT_H
 
+#include <cstddef>
+
 #include <boost/assert.hpp>
 #include <boost/config.hpp>
 #include <boost/cstdint.hpp>
@@ -15,6 +17,7 @@
 #include <boost/ref.hpp>
 #include <boost/tuple/tuple.hpp>
 #include <boost/type_traits/function_traits.hpp>
+#include <boost/utility.hpp>
 
 #include <boost/coroutine/attributes.hpp>
 #include <boost/coroutine/detail/arg.hpp>
@@ -25,6 +28,7 @@
 #include <boost/coroutine/detail/holder.hpp>
 #include <boost/coroutine/detail/param.hpp>
 #include <boost/coroutine/flags.hpp>
+#include <boost/coroutine/stack_context.hpp>
 
 #ifdef BOOST_HAS_ABI_HEADERS
 # include BOOST_ABI_PREFIX
@@ -55,6 +59,25 @@
     coro->run( arg);
 }
 
+template< typename StackAllocator >
+struct stack_tuple
+{
+ coroutines::stack_context stack_ctx;
+ StackAllocator stack_alloc;
+
+ stack_tuple( StackAllocator const& stack_alloc_, std::size_t size) :
+ stack_ctx(),
+ stack_alloc( stack_alloc_)
+ {
+ stack_alloc.allocate( stack_ctx, size);
+ }
+
+ ~stack_tuple()
+ {
+ stack_alloc.deallocate( stack_ctx);
+ }
+};
+
 template<
     typename Signature,
     typename Fn, typename StackAllocator, typename Allocator,

Modified: trunk/boost/coroutine/detail/coroutine_object_result_0.ipp
==============================================================================
--- trunk/boost/coroutine/detail/coroutine_object_result_0.ipp (original)
+++ trunk/boost/coroutine/detail/coroutine_object_result_0.ipp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -11,6 +11,7 @@
     typename Result
>
 class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, Result, 0 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -21,12 +22,11 @@
>::other allocator_t;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -40,28 +40,28 @@
     void enter_()
     {
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
- holder< Result > hldr_to( & caller);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -73,10 +73,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -86,10 +86,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< void > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -101,58 +101,52 @@
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( forward< Fn >( fn) ),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 #else
     coroutine_object( Fn fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 #endif
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
@@ -167,6 +161,7 @@
     typename Result
>
 class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 0 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -177,12 +172,11 @@
>::other allocator_t;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -196,28 +190,28 @@
     void enter_()
     {
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
- holder< Result > hldr_to( & caller);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -229,10 +223,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -242,10 +236,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< void > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -256,27 +250,25 @@
     coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
@@ -291,6 +283,7 @@
     typename Result
>
 class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 0 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -301,12 +294,11 @@
>::other allocator_t;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -320,10 +312,11 @@
     void enter_()
     {
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
         this->callee_ = hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
@@ -331,17 +324,16 @@
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
- holder< Result > hldr_to( & caller);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -353,10 +345,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -366,10 +358,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< void > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -380,22 +372,20 @@
     coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()

Modified: trunk/boost/coroutine/detail/coroutine_object_result_1.ipp
==============================================================================
--- trunk/boost/coroutine/detail/coroutine_object_result_1.ipp (original)
+++ trunk/boost/coroutine/detail/coroutine_object_result_1.ipp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -11,6 +11,7 @@
     typename Result
>
 class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, Result, 1 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -22,12 +23,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -41,11 +41,12 @@
     void enter_()
     {
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
@@ -53,31 +54,31 @@
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
             holder< Result > hldr_to( & caller);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -89,10 +90,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -102,10 +103,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -117,109 +118,97 @@
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( forward< Fn >( fn) ),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( forward< Fn >( fn) ),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 #else
     coroutine_object( Fn fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 #endif
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }
@@ -235,6 +224,7 @@
     typename Result
>
 class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 1 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -246,12 +236,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -265,11 +254,12 @@
     void enter_()
     {
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
@@ -277,31 +267,31 @@
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
             holder< Result > hldr_to( & caller);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -313,10 +303,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -326,10 +316,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -340,48 +330,44 @@
     coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }
@@ -397,6 +383,7 @@
     typename Result
>
 class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 1 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -408,12 +395,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -427,11 +413,12 @@
     void enter_()
     {
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
@@ -439,31 +426,31 @@
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
             holder< Result > hldr_to( & caller);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -475,10 +462,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -488,10 +475,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -502,48 +489,44 @@
     coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( const reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }

Modified: trunk/boost/coroutine/detail/coroutine_object_result_arity.ipp
==============================================================================
--- trunk/boost/coroutine/detail/coroutine_object_result_arity.ipp (original)
+++ trunk/boost/coroutine/detail/coroutine_object_result_arity.ipp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -11,6 +11,7 @@
     typename Result, int arity
>
 class coroutine_object :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -22,12 +23,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -41,11 +41,12 @@
     void enter_()
     {
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
@@ -53,31 +54,31 @@
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
             holder< Result > hldr_to( & caller);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -89,10 +90,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -102,10 +103,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -117,109 +118,97 @@
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( forward< Fn >( fn) ),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( forward< Fn >( fn) ),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 #else
     coroutine_object( Fn fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 #endif
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }
@@ -235,6 +224,7 @@
     typename Result, int arity
>
 class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, arity > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -246,12 +236,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -265,11 +254,12 @@
     void enter_()
     {
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
@@ -277,31 +267,31 @@
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
             holder< Result > hldr_to( & caller);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -313,10 +303,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -326,10 +316,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -340,48 +330,44 @@
     coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }
@@ -397,6 +383,7 @@
     typename Result, int arity
>
 class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, arity > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -408,12 +395,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -427,11 +413,12 @@
     void enter_()
     {
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
@@ -439,31 +426,31 @@
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< Result > * hldr_from(
- reinterpret_cast< holder< Result > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         this->result_ = hldr_from->data;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
             holder< Result > hldr_to( & caller);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -475,10 +462,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -488,10 +475,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -502,48 +489,44 @@
     coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( const reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }

Modified: trunk/boost/coroutine/detail/coroutine_object_void_0.ipp
==============================================================================
--- trunk/boost/coroutine/detail/coroutine_object_void_0.ipp (original)
+++ trunk/boost/coroutine/detail/coroutine_object_void_0.ipp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -10,6 +10,7 @@
     typename Caller
>
 class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, void, 0 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -20,12 +21,11 @@
>::other allocator_t;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -39,27 +39,27 @@
     void enter_()
     {
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
             holder< void > hldr_to( & caller);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -71,10 +71,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -84,10 +84,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< void > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -99,58 +99,52 @@
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( forward< Fn >( fn) ),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 #else
     coroutine_object( Fn fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->pbase_type::stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 #endif
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
@@ -164,6 +158,7 @@
     typename Caller
>
 class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 0 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -174,12 +169,11 @@
>::other allocator_t;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -193,27 +187,27 @@
     void enter_()
     {
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
             holder< void > hldr_to( & caller);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -225,10 +219,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -238,10 +232,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< void > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -252,27 +246,25 @@
     coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
@@ -286,6 +278,7 @@
     typename Caller
>
 class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 0 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -296,12 +289,11 @@
>::other allocator_t;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -315,27 +307,27 @@
     void enter_()
     {
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
             holder< void > hldr_to( & caller);
- context::jump_fcontext(
- hldr_to.ctx, callee,
+ caller.jump(
+ callee,
                 reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
@@ -347,10 +339,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -360,10 +352,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< void > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -374,27 +366,25 @@
     coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 

Modified: trunk/boost/coroutine/detail/coroutine_object_void_1.ipp
==============================================================================
--- trunk/boost/coroutine/detail/coroutine_object_void_1.ipp (original)
+++ trunk/boost/coroutine/detail/coroutine_object_void_1.ipp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -10,6 +10,7 @@
     typename Caller
>
 class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, void, 1 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -21,12 +22,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -40,42 +40,43 @@
     void enter_()
     {
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- holder< void > hldr( & caller);
- context::jump_fcontext(
- hldr.ctx, callee,
- ( intptr_t) & hldr,
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
         }
@@ -86,10 +87,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -99,10 +100,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -114,109 +115,97 @@
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( forward< Fn >( fn) ),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( forward< Fn >( fn) ),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 #else
     coroutine_object( Fn fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 #endif
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }
@@ -231,6 +220,7 @@
     typename Caller
>
 class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 1 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -242,12 +232,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -261,42 +250,43 @@
     void enter_()
     {
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- holder< void > hldr( & caller);
- context::jump_fcontext(
- hldr.ctx, callee,
- ( intptr_t) & hldr,
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
         }
@@ -307,10 +297,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -320,10 +310,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -334,15 +324,13 @@
     coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
@@ -350,33 +338,31 @@
                       typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }
@@ -391,6 +377,7 @@
     typename Caller
>
 class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 1 > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -402,12 +389,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -421,42 +407,43 @@
     void enter_()
     {
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- holder< void > hldr( & caller);
- context::jump_fcontext(
- hldr.ctx, callee,
- ( intptr_t) & hldr,
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
         }
@@ -467,10 +454,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -480,10 +467,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -494,15 +481,13 @@
     coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
@@ -510,33 +495,31 @@
                       typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }

Modified: trunk/boost/coroutine/detail/coroutine_object_void_arity.ipp
==============================================================================
--- trunk/boost/coroutine/detail/coroutine_object_void_arity.ipp (original)
+++ trunk/boost/coroutine/detail/coroutine_object_void_arity.ipp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -11,6 +11,7 @@
     int arity
>
 class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, void, arity > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -22,12 +23,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -41,42 +41,43 @@
     void enter_()
     {
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- holder< void > hldr( & caller);
- context::jump_fcontext(
- hldr.ctx, callee,
- ( intptr_t) & hldr,
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
         }
@@ -87,10 +88,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -100,10 +101,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -115,109 +116,97 @@
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( forward< Fn >( fn) ),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( forward< Fn >( fn) ),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 #else
     coroutine_object( Fn fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 #endif
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }
@@ -233,6 +222,7 @@
     int arity
>
 class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, arity > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -244,12 +234,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -263,42 +252,43 @@
     void enter_()
     {
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- holder< void > hldr( & caller);
- context::jump_fcontext(
- hldr.ctx, callee,
- ( intptr_t) & hldr,
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
         }
@@ -309,10 +299,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -322,10 +312,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -336,48 +326,44 @@
     coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }
@@ -393,6 +379,7 @@
     int arity
>
 class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, arity > :
+ private stack_tuple< StackAllocator >,
     public coroutine_base< Signature >
 {
 public:
@@ -404,12 +391,11 @@
     typedef typename arg< Signature >::type arg_type;
 
 private:
+ typedef stack_tuple< StackAllocator > pbase_type;
     typedef coroutine_base< Signature > base_type;
 
- Fn fn_;
- context::stack_t stack_;
- StackAllocator stack_alloc_;
- allocator_t alloc_;
+ Fn fn_;
+ allocator_t alloc_;
 
     static void destroy_( allocator_t & alloc, coroutine_object * p)
     {
@@ -423,42 +409,43 @@
     void enter_()
     {
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( this),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void enter_( typename detail::param< arg_type >::type arg)
     {
         tuple< coroutine_object *,
- typename detail::param< arg_type >::type
+ typename detail::param< arg_type >::type
> tpl( this, arg);
         holder< void > * hldr_from(
- reinterpret_cast< holder< void > * >( context::jump_fcontext(
- & this->caller_, this->callee_,
- reinterpret_cast< intptr_t >( & tpl),
- this->preserve_fpu() ) ) );
- this->callee_ = hldr_from->ctx;
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
         if ( this->except_) rethrow_exception( this->except_);
     }
 
     void run_( Caller & c)
     {
- context::fcontext_t * callee( 0);
- context::fcontext_t caller;
+ coroutine_context callee;
+ coroutine_context caller;
         try
         {
             fn_( c);
             this->flags_ |= flag_complete;
             callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- holder< void > hldr( & caller);
- context::jump_fcontext(
- hldr.ctx, callee,
- ( intptr_t) & hldr,
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
                 this->preserve_fpu() );
             BOOST_ASSERT_MSG( false, "coroutine is complete");
         }
@@ -469,10 +456,10 @@
 
         this->flags_ |= flag_complete;
         callee = c.impl_->callee_;
- BOOST_ASSERT( callee);
- context::jump_fcontext(
- & caller, callee,
- reinterpret_cast< intptr_t >( & caller),
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         BOOST_ASSERT_MSG( false, "coroutine is complete");
     }
@@ -482,10 +469,10 @@
         BOOST_ASSERT( ! this->is_complete() );
 
         this->flags_ |= flag_unwind_stack;
- holder< arg_type > hldr( & this->caller_, true);
- context::jump_fcontext(
- hldr.ctx, this->callee_,
- reinterpret_cast< intptr_t >( & hldr),
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
             this->preserve_fpu() );
         this->flags_ &= ~flag_unwind_stack;
 
@@ -496,48 +483,44 @@
     coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline1< coroutine_object >),
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_(); }
 
     coroutine_object( const reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
                       StackAllocator const& stack_alloc,
                       allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
         base_type(
- context::make_fcontext(
- stack_alloc.allocate( attr.size), attr.size,
- trampoline2< coroutine_object, typename detail::param< arg_type >::type >),
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
             stack_unwind == attr.do_unwind,
             fpu_preserved == attr.preserve_fpu),
         fn_( fn),
- stack_( base_type::callee_->fc_stack),
- stack_alloc_( stack_alloc),
         alloc_( alloc)
     { enter_( arg); }
 
     ~coroutine_object()
     {
- if ( ! this->is_complete() && this->force_unwind() ) unwind_stack_();
- stack_alloc_.deallocate( stack_.sp, stack_.size);
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
     }
 
     void run()
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         run_( c);
     }
 
     void run( typename detail::param< arg_type >::type arg)
     {
- Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
         c.impl_->result_ = arg;
         run_( c);
     }

Modified: trunk/boost/coroutine/detail/holder.hpp
==============================================================================
--- trunk/boost/coroutine/detail/holder.hpp (original)
+++ trunk/boost/coroutine/detail/holder.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -11,6 +11,8 @@
 #include <boost/config.hpp>
 #include <boost/optional.hpp>
 
+#include <boost/coroutine/detail/coroutine_context.hpp>
+
 #ifdef BOOST_HAS_ABI_HEADERS
 # include BOOST_ABI_PREFIX
 #endif
@@ -22,19 +24,19 @@
 template< typename Data >
 struct holder
 {
- context::fcontext_t * ctx;
+ coroutine_context * ctx;
     optional< Data > data;
     bool force_unwind;
 
- holder( context::fcontext_t * ctx_) :
+ explicit holder( coroutine_context * ctx_) :
         ctx( ctx_), data(), force_unwind( false)
     { BOOST_ASSERT( ctx); }
 
- holder( context::fcontext_t * ctx_, Data data_) :
+ explicit holder( coroutine_context * ctx_, Data data_) :
         ctx( ctx_), data( data_), force_unwind( false)
     { BOOST_ASSERT( ctx); }
 
- holder( context::fcontext_t * ctx_, bool force_unwind_) :
+ explicit holder( coroutine_context * ctx_, bool force_unwind_) :
         ctx( ctx_), data(), force_unwind( force_unwind_)
     {
         BOOST_ASSERT( ctx);
@@ -59,10 +61,10 @@
 template<>
 struct holder< void >
 {
- context::fcontext_t * ctx;
- bool force_unwind;
+ coroutine_context * ctx;
+ bool force_unwind;
 
- holder( context::fcontext_t * ctx_, bool force_unwind_ = false) :
+ explicit holder( coroutine_context * ctx_, bool force_unwind_ = false) :
         ctx( ctx_), force_unwind( force_unwind_)
     { BOOST_ASSERT( ctx); }
 

Added: trunk/boost/coroutine/detail/segmented_stack_allocator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/detail/segmented_stack_allocator.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -0,0 +1,51 @@
+
+// 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_COROUTINES_DETAIL_SEGMENTED_STACK_ALLOCATOR_H
+#define BOOST_COROUTINES_DETAIL_SEGMENTED_STACK_ALLOCATOR_H
+
+#include <cstddef>
+
+#include <boost/config.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+
+struct stack_context;
+
+namespace detail {
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+class segmented_stack_allocator
+{
+public:
+ static bool is_stack_unbound();
+
+ static std::size_t default_stacksize();
+
+ static std::size_t minimum_stacksize();
+
+ static std::size_t maximum_stacksize();
+
+ void allocate( stack_context &, std::size_t size);
+
+ void deallocate( stack_context &);
+};
+#endif
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_SEGMENTED_STACK_ALLOCATOR_H

Deleted: trunk/boost/coroutine/detail/stack_allocator_posix.hpp
==============================================================================
--- trunk/boost/coroutine/detail/stack_allocator_posix.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
+++ (empty file)
@@ -1,173 +0,0 @@
-
-// Copyright Oliver Kowalke 2009.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H
-#define BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H
-
-#include <boost/config.hpp>
-
-extern "C" {
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-}
-
-//#if _POSIX_C_SOURCE >= 200112L
-
-#include <algorithm>
-#include <cmath>
-#include <cstddef>
-#include <cstring>
-#include <stdexcept>
-
-#include <boost/assert.hpp>
-#include <boost/context/fcontext.hpp>
-#include <boost/context/detail/config.hpp>
-
-#if !defined (SIGSTKSZ)
-# define SIGSTKSZ (8 * 1024)
-# define UDEF_SIGSTKSZ
-#endif
-
-
-#ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_PREFIX
-#endif
-
-namespace boost {
-namespace coroutines {
-namespace detail {
-
-inline
-std::size_t pagesize()
-{
- // conform to POSIX.1-2001
- static std::size_t size = ::sysconf( _SC_PAGESIZE);
- return size;
-}
-
-inline
-rlimit stacksize_limit_()
-{
- rlimit limit;
- // conforming to POSIX.1-2001
-#if defined(BOOST_DISABLE_ASSERTS)
- ::getrlimit( RLIMIT_STACK, & limit);
-#else
- const int result = ::getrlimit( RLIMIT_STACK, & limit);
- BOOST_ASSERT( 0 == result);
-#endif
- return limit;
-}
-
-inline
-rlimit stacksize_limit()
-{
- static rlimit limit = stacksize_limit_();
- return limit;
-}
-
-inline
-std::size_t page_count( std::size_t stacksize)
-{
- return static_cast< std::size_t >(
- std::ceil(
- static_cast< float >( stacksize) / pagesize() ) );
-}
-
-class stack_allocator
-{
-public:
- static bool is_stack_unbound()
- { return RLIM_INFINITY == stacksize_limit().rlim_max; }
-
- static std::size_t default_stacksize()
- {
- std::size_t size = 8 * minimum_stacksize();
- if ( is_stack_unbound() ) return size;
-
- BOOST_ASSERT( maximum_stacksize() >= minimum_stacksize() );
- return maximum_stacksize() == size
- ? size
- : (std::min)( size, maximum_stacksize() );
- }
-
- static std::size_t minimum_stacksize()
- { return SIGSTKSZ + sizeof( context::fcontext_t) + 15; }
-
- static std::size_t maximum_stacksize()
- {
- BOOST_ASSERT( ! is_stack_unbound() );
- return static_cast< std::size_t >( stacksize_limit().rlim_max);
- }
-
- void * allocate( std::size_t size) const
- {
- BOOST_ASSERT( minimum_stacksize() <= size);
- BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) );
-
- const std::size_t pages( page_count( size) + 1); // add one guard page
- const std::size_t size_( pages * pagesize() );
- BOOST_ASSERT( 0 < size && 0 < size_);
-
- const int fd( ::open("/dev/zero", O_RDONLY) );
- BOOST_ASSERT( -1 != fd);
- // conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L)
- void * limit =
-# if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
- ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
-# else
- ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
-# endif
- ::close( fd);
- if ( ! limit) throw std::bad_alloc();
-
- std::memset( limit, size_, '\0');
-
- // conforming to POSIX.1-2001
-#if defined(BOOST_DISABLE_ASSERTS)
- ::mprotect( limit, pagesize(), PROT_NONE);
-#else
- const int result( ::mprotect( limit, pagesize(), PROT_NONE) );
- BOOST_ASSERT( 0 == result);
-#endif
-
- return static_cast< char * >( limit) + size_;
- }
-
- void deallocate( void * vp, std::size_t size) const
- {
- BOOST_ASSERT( vp);
- BOOST_ASSERT( minimum_stacksize() <= size);
- BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) );
-
- const std::size_t pages = page_count( size) + 1;
- const std::size_t size_ = pages * pagesize();
- BOOST_ASSERT( 0 < size && 0 < size_);
- void * limit = static_cast< char * >( vp) - size_;
- // conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L)
- ::munmap( limit, size_);
- }
-};
-
-}}}
-
-#ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_SUFFIX
-#endif
-
-#ifdef UDEF_SIGSTKSZ
-# undef SIGSTKSZ
-#endif
-
-//#endif
-
-#endif // BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H

Deleted: trunk/boost/coroutine/detail/stack_allocator_windows.hpp
==============================================================================
--- trunk/boost/coroutine/detail/stack_allocator_windows.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
+++ (empty file)
@@ -1,163 +0,0 @@
-
-// Copyright Oliver Kowalke 2009.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H
-#define BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H
-
-#include <boost/config.hpp>
-
-extern "C" {
-#include <windows.h>
-}
-
-//#if defined (BOOST_WINDOWS) || _POSIX_C_SOURCE >= 200112L
-
-#include <algorithm>
-#include <cmath>
-#include <cstddef>
-#include <cstring>
-#include <stdexcept>
-
-#include <boost/assert.hpp>
-#include <boost/context/detail/config.hpp>
-#include <boost/context/fcontext.hpp>
-
-# if defined(BOOST_MSVC)
-# pragma warning(push)
-# pragma warning(disable:4244 4267)
-# endif
-
-// x86_64
-// test x86_64 before i386 because icc might
-// define __i686__ for x86_64 too
-#if defined(__x86_64__) || defined(__x86_64) \
- || defined(__amd64__) || defined(__amd64) \
- || defined(_M_X64) || defined(_M_AMD64)
-
-// Windows seams not to provide a constant or function
-// telling the minimal stacksize
-# define MIN_STACKSIZE 8 * 1024
-#else
-# define MIN_STACKSIZE 4 * 1024
-#endif
-
-
-#ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_PREFIX
-#endif
-
-namespace boost {
-namespace coroutines {
-namespace detail {
-
-inline
-SYSTEM_INFO system_info_()
-{
- SYSTEM_INFO si;
- ::GetSystemInfo( & si);
- return si;
-}
-
-inline
-SYSTEM_INFO system_info()
-{
- static SYSTEM_INFO si = system_info_();
- return si;
-}
-
-inline
-std::size_t pagesize()
-{ return static_cast< std::size_t >( system_info().dwPageSize); }
-
-inline
-std::size_t page_count( std::size_t stacksize)
-{
- return static_cast< std::size_t >(
- std::ceil(
- static_cast< float >( stacksize) / pagesize() ) );
-}
-
-class stack_allocator
-{
-public:
- // Windows seams not to provide a limit for the stacksize
- static bool is_stack_unbound()
- { return true; }
-
- static std::size_t default_stacksize()
- {
- std::size_t size = 64 * 1024; // 64 kB
- if ( is_stack_unbound() )
- return (std::max)( size, minimum_stacksize() );
-
- BOOST_ASSERT( maximum_stacksize() >= minimum_stacksize() );
- return maximum_stacksize() == minimum_stacksize()
- ? minimum_stacksize()
- : ( std::min)( size, maximum_stacksize() );
- }
-
- // because Windows seams not to provide a limit for minimum stacksize
- static std::size_t minimum_stacksize()
- { return MIN_STACKSIZE; }
-
- // because Windows seams not to provide a limit for maximum stacksize
- // maximum_stacksize() can never be called (pre-condition ! is_stack_unbound() )
- static std::size_t maximum_stacksize()
- {
- BOOST_ASSERT( ! is_stack_unbound() );
- return 1 * 1024 * 1024 * 1024; // 1GB
- }
-
- void * allocate( std::size_t size) const
- {
- BOOST_ASSERT( minimum_stacksize() <= size);
- BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) );
-
- const std::size_t pages( page_count( size) + 1); // add one guard page
- const std::size_t size_ = pages * pagesize();
- BOOST_ASSERT( 0 < size && 0 < size_);
-
- void * limit = ::VirtualAlloc( 0, size_, MEM_COMMIT, PAGE_READWRITE);
- if ( ! limit) throw std::bad_alloc();
-
- std::memset( limit, size_, '\0');
-
- DWORD old_options;
-#if defined(BOOST_DISABLE_ASSERTS)
- ::VirtualProtect(
- limit, pagesize(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
-#else
- const BOOL result = ::VirtualProtect(
- limit, pagesize(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
- BOOST_ASSERT( FALSE != result);
-#endif
-
- return static_cast< char * >( limit) + size_;
- }
-
- void deallocate( void * vp, std::size_t size) const
- {
- BOOST_ASSERT( vp);
- BOOST_ASSERT( minimum_stacksize() <= size);
- BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) );
-
- const std::size_t pages = page_count( size) + 1;
- const std::size_t size_ = pages * pagesize();
- BOOST_ASSERT( 0 < size && 0 < size_);
- void * limit = static_cast< char * >( vp) - size_;
- ::VirtualFree( limit, 0, MEM_RELEASE);
- }
-};
-
-}}}
-
-#ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_SUFFIX
-#endif
-
-//#endif
-
-#endif // BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H

Added: trunk/boost/coroutine/detail/standard_stack_allocator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/detail/standard_stack_allocator.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -0,0 +1,49 @@
+
+// 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_COROUTINES_DETAIL_STANDARD_STACK_ALLOCATOR_H
+#define BOOST_COROUTINES_DETAIL_STANDARD_STACK_ALLOCATOR_H
+
+#include <cstddef>
+
+#include <boost/config.hpp>
+
+#include <boost/context/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+
+struct stack_context;
+
+namespace detail {
+
+class standard_stack_allocator
+{
+public:
+ static bool is_stack_unbound();
+
+ static std::size_t default_stacksize();
+
+ static std::size_t minimum_stacksize();
+
+ static std::size_t maximum_stacksize();
+
+ void allocate( stack_context &, std::size_t);
+
+ void deallocate( stack_context &);
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_STANDARD_STACK_ALLOCATOR_H

Modified: trunk/boost/coroutine/stack_allocator.hpp
==============================================================================
--- trunk/boost/coroutine/stack_allocator.hpp (original)
+++ trunk/boost/coroutine/stack_allocator.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -4,20 +4,34 @@
 // (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-#ifndef BOOST_COROUTINES_STACK_ALLOCATOR_H
-#define BOOST_COROUTINES_STACK_ALLOCATOR_H
+#ifndef BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H
+#define BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H
+
+#include <cstddef>
 
 #include <boost/config.hpp>
 
-#if defined (BOOST_WINDOWS)
-#include <boost/coroutine/detail/stack_allocator_windows.hpp>
-#else
-#include <boost/coroutine/detail/stack_allocator_posix.hpp>
+#include <boost/context/detail/config.hpp>
+#include <boost/coroutine/detail/segmented_stack_allocator.hpp>
+#include <boost/coroutine/detail/standard_stack_allocator.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
 #endif
 
 namespace boost {
 namespace coroutines {
-using detail::stack_allocator;
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+typedef detail::segmented_stack_allocator stack_allocator;
+#else
+typedef detail::standard_stack_allocator stack_allocator;
+#endif
+
 }}
 
-#endif // BOOST_COROUTINES_STACK_ALLOCATOR_H
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H

Added: trunk/boost/coroutine/stack_context.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/stack_context.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -0,0 +1,54 @@
+
+// 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_COROUTINES_STACK_CONTEXT_H
+#define BOOST_COROUTINES_STACK_CONTEXT_H
+
+#include <cstddef>
+
+#include <boost/config.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+struct stack_context
+{
+ typedef void * segments_context[BOOST_COROUTINES_SEGMENTS];
+
+ std::size_t size;
+ void * sp;
+ segments_context segments_ctx;
+
+ stack_context() :
+ size( 0), sp( 0), segments_ctx()
+ {}
+};
+#else
+struct stack_context
+{
+ std::size_t size;
+ void * sp;
+
+ stack_context() :
+ size( 0), sp( 0)
+ {}
+};
+#endif
+
+}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_STACK_CONTEXT_H

Added: trunk/libs/coroutine/build/Jamfile.v2
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/build/Jamfile.v2 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -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)
+
+import feature ;
+import modules ;
+import toolset ;
+
+project boost/coroutine
+ : requirements
+ <library>/boost/context//boost_context
+# <toolset>gcc-4.7:<cxxflags>-fsplit-stack
+# <toolset>gcc-4.7:<linkflags>"-static-libgcc"
+ <link>static
+ <threading>multi
+ : source-location ../src
+ : usage-requirements
+ <link>shared:<define>BOOST_COROUTINES_DYN_LINK=1
+ ;
+
+alias allocator_sources
+ : detail/standard_stack_allocator_windows.cpp
+ detail/segmented_stack_allocator.cpp
+ : <target-os>windows
+ ;
+
+alias allocator_sources
+ : detail/standard_stack_allocator_posix.cpp
+ detail/segmented_stack_allocator.cpp
+ ;
+
+explicit yield_sources ;
+
+lib boost_coroutine
+ : allocator_sources
+ detail/coroutine_context.cpp
+ : <link>shared:<define>BOOST_COROUTINES_DYN_LINK=1
+ :
+ : <link>shared:<library>../../context/build//boost_context
+ ;
+
+boost-install boost_coroutine ;

Added: trunk/libs/coroutine/detail/coroutine_context.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/detail/coroutine_context.cpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -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)
+
+#define BOOST_COROUTINES_SOURCE
+
+#include "boost/coroutine/detail/coroutine_context.hpp"
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+extern "C" {
+
+void __splitstack_getcontext( void * [BOOST_COROUTINES_SEGMENTS]);
+
+void __splitstack_setcontext( void * [BOOST_COROUTINES_SEGMENTS]);
+
+void __splitstack_releasecontext (void * [BOOST_COROUTINES_SEGMENTS]);
+
+void __splitstack_block_signals_context( void * [BOOST_COROUTINES_SEGMENTS], int *, int *);
+
+}
+#endif
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+coroutine_context::coroutine_context() :
+ fcontext_t(), stack_ctx_( this), ctx_( this)
+{
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+ __splitstack_getcontext( stack_ctx_->segments_ctx);
+#endif
+}
+
+coroutine_context::coroutine_context( ctx_fn fn, stack_context * stack_ctx) :
+ fcontext_t(), stack_ctx_( stack_ctx),
+ ctx_( context::make_fcontext( stack_ctx_->sp, stack_ctx_->size, fn) )
+{}
+
+coroutine_context::coroutine_context( coroutine_context const& other) :
+ fcontext_t(),
+ stack_ctx_( other.stack_ctx_),
+ ctx_( other.ctx_)
+{}
+
+coroutine_context &
+coroutine_context::operator=( coroutine_context const& other)
+{
+ if ( this == & other) return * this;
+
+ stack_ctx_ = other.stack_ctx_;
+ ctx_ = other.ctx_;
+
+ return * this;
+}
+
+intptr_t
+coroutine_context::jump( coroutine_context & other, intptr_t param, bool preserve_fpu)
+{
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+ if ( stack_ctx_)
+ __splitstack_getcontext( stack_ctx_->segments_ctx);
+ if ( other.stack_ctx_)
+ __splitstack_setcontext( other.stack_ctx_->segments_ctx);
+#endif
+ return context::jump_fcontext( ctx_, other.ctx_, param, preserve_fpu);
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+ if ( stack_ctx_)
+ __splitstack_setcontext( stack_ctx_->segments_ctx);
+#endif
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif

Added: trunk/libs/coroutine/detail/segmented_stack_allocator.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/detail/segmented_stack_allocator.cpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -0,0 +1,93 @@
+
+// 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)
+
+#define BOOST_COROUTINES_SOURCE
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+
+#include <boost/coroutine/detail/segmented_stack_allocator.hpp>
+
+#include <boost/assert.hpp>
+#include <boost/context/fcontext.hpp>
+
+#include <boost/coroutine/stack_context.hpp>
+
+extern "C" {
+
+void *__splitstack_makecontext( std::size_t,
+ void * [BOOST_COROUTINES_SEGMENTS],
+ std::size_t *);
+
+void __splitstack_releasecontext( void * [BOOST_COROUTINES_SEGMENTS]);
+
+void __splitstack_resetcontext( void * [BOOST_COROUTINES_SEGMENTS]);
+
+void __splitstack_block_signals_context( void * [BOOST_COROUTINES_SEGMENTS],
+ int * new_value, int * old_value);
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+#if !defined (SIGSTKSZ)
+# define SIGSTKSZ (8 * 1024)
+# define UDEF_SIGSTKSZ
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+bool
+segmented_stack_allocator::is_stack_unbound()
+{ return true; }
+
+std::size_t
+segmented_stack_allocator::minimum_stacksize()
+{ return SIGSTKSZ + sizeof( context::fcontext_t) + 15; }
+
+std::size_t
+segmented_stack_allocator::default_stacksize()
+{ return minimum_stacksize(); }
+
+std::size_t
+segmented_stack_allocator::maximum_stacksize()
+{
+ BOOST_ASSERT_MSG( false, "segmented stack is unbound");
+ return 0;
+}
+
+void
+segmented_stack_allocator::allocate( stack_context & ctx, std::size_t size)
+{
+ BOOST_ASSERT( default_stacksize() <= size);
+
+ void * limit = __splitstack_makecontext( size, ctx.segments_ctx, & ctx.size);
+ BOOST_ASSERT( limit);
+ ctx.sp = static_cast< char * >( limit) + ctx.size;
+
+ int off = 0;
+ __splitstack_block_signals_context( ctx.segments_ctx, & off, 0);
+}
+
+void
+segmented_stack_allocator::deallocate( stack_context & ctx)
+{
+ __splitstack_releasecontext( ctx.segments_ctx);
+}
+
+}}}
+
+#ifdef UDEF_SIGSTKSZ
+# undef SIGSTKSZ
+#endif
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif

Added: trunk/libs/coroutine/detail/standard_stack_allocator_posix.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/detail/standard_stack_allocator_posix.cpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -0,0 +1,163 @@
+
+// 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)
+
+#define BOOST_COROUTINES_SOURCE
+
+#include "boost/coroutine/detail/standard_stack_allocator.hpp"
+
+extern "C" {
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+}
+
+//#if _POSIX_C_SOURCE >= 200112L
+
+#include <algorithm>
+#include <cmath>
+#include <cstring>
+#include <stdexcept>
+
+#include <boost/assert.hpp>
+#include <boost/context/fcontext.hpp>
+
+#include <boost/coroutine/stack_context.hpp>
+
+#if !defined (SIGSTKSZ)
+# define SIGSTKSZ (8 * 1024)
+# define UDEF_SIGSTKSZ
+#endif
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+std::size_t pagesize()
+{
+ // conform to POSIX.1-2001
+ static std::size_t size = ::sysconf( _SC_PAGESIZE);
+ return size;
+}
+
+rlimit stacksize_limit_()
+{
+ rlimit limit;
+ // conforming to POSIX.1-2001
+#if defined(BOOST_DISABLE_ASSERTS)
+ ::getrlimit( RLIMIT_STACK, & limit);
+#else
+ const int result = ::getrlimit( RLIMIT_STACK, & limit);
+ BOOST_ASSERT( 0 == result);
+#endif
+ return limit;
+}
+
+rlimit stacksize_limit()
+{
+ static rlimit limit = stacksize_limit_();
+ return limit;
+}
+
+std::size_t page_count( std::size_t stacksize)
+{
+ return static_cast< std::size_t >(
+ std::ceil(
+ static_cast< float >( stacksize) / pagesize() ) );
+}
+
+bool
+standard_stack_allocator::is_stack_unbound()
+{ return RLIM_INFINITY == detail::stacksize_limit().rlim_max; }
+
+std::size_t
+standard_stack_allocator::default_stacksize()
+{
+ std::size_t size = 8 * minimum_stacksize();
+ if ( is_stack_unbound() ) return size;
+
+ BOOST_ASSERT( maximum_stacksize() >= minimum_stacksize() );
+ return maximum_stacksize() == size
+ ? size
+ : (std::min)( size, maximum_stacksize() );
+}
+
+std::size_t
+standard_stack_allocator::minimum_stacksize()
+{ return SIGSTKSZ + sizeof( context::fcontext_t) + 15; }
+
+std::size_t
+standard_stack_allocator::maximum_stacksize()
+{
+ BOOST_ASSERT( ! is_stack_unbound() );
+ return static_cast< std::size_t >( detail::stacksize_limit().rlim_max);
+}
+
+void
+standard_stack_allocator::allocate( stack_context & ctx, std::size_t size)
+{
+ BOOST_ASSERT( minimum_stacksize() <= size);
+ BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) );
+
+ const std::size_t pages( detail::page_count( size) + 1); // add one guard page
+ const std::size_t size_( pages * detail::pagesize() );
+ BOOST_ASSERT( 0 < size && 0 < size_);
+
+ const int fd( ::open("/dev/zero", O_RDONLY) );
+ BOOST_ASSERT( -1 != fd);
+ // conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L)
+ void * limit =
+# if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+ ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+# else
+ ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+# endif
+ ::close( fd);
+ if ( ! limit) throw std::bad_alloc();
+
+ std::memset( limit, '\0', size_);
+
+ // conforming to POSIX.1-2001
+#if defined(BOOST_DISABLE_ASSERTS)
+ ::mprotect( limit, detail::pagesize(), PROT_NONE);
+#else
+ const int result( ::mprotect( limit, detail::pagesize(), PROT_NONE) );
+ BOOST_ASSERT( 0 == result);
+#endif
+
+ ctx.size = size_;
+ ctx.sp = static_cast< char * >( limit) + ctx.size;
+}
+
+void
+standard_stack_allocator::deallocate( stack_context & ctx)
+{
+ BOOST_ASSERT( ctx.sp);
+ BOOST_ASSERT( minimum_stacksize() <= ctx.size);
+ BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= ctx.size) );
+
+ void * limit = static_cast< char * >( ctx.sp) - ctx.size;
+ // conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L)
+ ::munmap( limit, ctx.size);
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#ifdef UDEF_SIGSTKSZ
+# undef SIGSTKSZ
+#endif

Added: trunk/libs/coroutine/detail/standard_stack_allocator_windows.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/detail/standard_stack_allocator_windows.cpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -0,0 +1,155 @@
+
+// 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)
+
+#define BOOST_COROUTINES_SOURCE
+
+#include "boost/coroutine/detail/standard_stack_allocator.hpp"
+
+extern "C" {
+#include <windows.h>
+}
+
+//#if defined (BOOST_WINDOWS) || _POSIX_C_SOURCE >= 200112L
+
+#include <algorithm>
+#include <cmath>
+#include <cstddef>
+#include <cstring>
+#include <stdexcept>
+
+#include <boost/assert.hpp>
+#include <boost/context/detail/config.hpp>
+#include <boost/context/fcontext.hpp>
+
+#include <boost/coroutine/stack_context.hpp>
+
+# if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4244 4267)
+# endif
+
+// x86_64
+// test x86_64 before i386 because icc might
+// define __i686__ for x86_64 too
+#if defined(__x86_64__) || defined(__x86_64) \
+ || defined(__amd64__) || defined(__amd64) \
+ || defined(_M_X64) || defined(_M_AMD64)
+
+// Windows seams not to provide a constant or function
+// telling the minimal stacksize
+# define MIN_STACKSIZE 8 * 1024
+#else
+# define MIN_STACKSIZE 4 * 1024
+#endif
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+SYSTEM_INFO system_info_()
+{
+ SYSTEM_INFO si;
+ ::GetSystemInfo( & si);
+ return si;
+}
+
+SYSTEM_INFO system_info()
+{
+ static SYSTEM_INFO si = system_info_();
+ return si;
+}
+
+std::size_t pagesize()
+{ return static_cast< std::size_t >( system_info().dwPageSize); }
+
+std::size_t page_count( std::size_t stacksize)
+{
+ return static_cast< std::size_t >(
+ std::ceil(
+ static_cast< float >( stacksize) / pagesize() ) );
+}
+
+// Windows seams not to provide a limit for the stacksize
+bool
+standard_stack_allocator::is_stack_unbound()
+{ return true; }
+
+std::size_t
+standard_stack_allocator::default_stacksize()
+{
+ std::size_t size = 64 * 1024; // 64 kB
+ if ( is_stack_unbound() )
+ return (std::max)( size, minimum_stacksize() );
+
+ BOOST_ASSERT( maximum_stacksize() >= minimum_stacksize() );
+ return maximum_stacksize() == minimum_stacksize()
+ ? minimum_stacksize()
+ : ( std::min)( size, maximum_stacksize() );
+}
+
+// because Windows seams not to provide a limit for minimum stacksize
+std::size_t
+standard_stack_allocator::minimum_stacksize()
+{ return MIN_STACKSIZE; }
+
+// because Windows seams not to provide a limit for maximum stacksize
+// maximum_stacksize() can never be called (pre-condition ! is_stack_unbound() )
+std::size_t
+standard_stack_allocator::maximum_stacksize()
+{
+ BOOST_ASSERT( ! is_stack_unbound() );
+ return 1 * 1024 * 1024 * 1024; // 1GB
+}
+
+void
+standard_stack_allocator::allocate( stack_context & ctx, std::size_t size)
+{
+ BOOST_ASSERT( minimum_stacksize() <= size);
+ BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) );
+
+ const std::size_t pages( detail::page_count( size) + 1); // add one guard page
+ const std::size_t size_ = pages * detail::pagesize();
+ BOOST_ASSERT( 0 < size && 0 < size_);
+
+ void * limit = ::VirtualAlloc( 0, size_, MEM_COMMIT, PAGE_READWRITE);
+ if ( ! limit) throw std::bad_alloc();
+
+ std::memset( limit, '\0', size_);
+
+ DWORD old_options;
+#if defined(BOOST_DISABLE_ASSERTS)
+ ::VirtualProtect(
+ limit, detail::pagesize(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
+#else
+ const BOOL result = ::VirtualProtect(
+ limit, detail::pagesize(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
+ BOOST_ASSERT( FALSE != result);
+#endif
+
+ ctx.size = size_;
+ ctx.sp = static_cast< char * >( limit) + ctx.size;
+}
+
+void
+standard_stack_allocator::deallocate( stack_context & ctx)
+{
+ BOOST_ASSERT( ctx.sp);
+ BOOST_ASSERT( minimum_stacksize() <= ctx.size);
+ BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= ctx.size) );
+
+ void * limit = static_cast< char * >( ctx.sp) - ctx.size;
+ ::VirtualFree( limit, 0, MEM_RELEASE);
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif

Modified: trunk/libs/coroutine/doc/Jamfile.v2
==============================================================================
--- trunk/libs/coroutine/doc/Jamfile.v2 (original)
+++ trunk/libs/coroutine/doc/Jamfile.v2 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -3,12 +3,18 @@
 # 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)
 
-xml coro : coro.qbk ;
+project coroutine/doc ;
 
-boostbook standalone
+import boostbook ;
+import quickbook ;
+import modules ;
+
+boostbook coro
     :
- coro
+ coro.qbk
     :
+ # Path for links to Boost:
+ <xsl:param>boost.root=../../../..
         # HTML options first:
         # How far down we chunk nested sections, basically all of them:
         <xsl:param>chunk.section.depth=3
@@ -20,6 +26,4 @@
         <xsl:param>toc.max.depth=3
         # How far down we go with TOC's
         <xsl:param>generate.section.toc.level=10
- # Path for links to Boost:
- <xsl:param>boost.root=../../../..
     ;

Modified: trunk/libs/coroutine/doc/coro.qbk
==============================================================================
--- trunk/libs/coroutine/doc/coro.qbk (original)
+++ trunk/libs/coroutine/doc/coro.qbk 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -43,6 +43,7 @@
 [def __coros__ ['coroutines]]
 [def __not_a_coro__ ['not-a-coroutine]]
 [def __signature__ ['Signature]]
+[def __segmented_stack__ ['segemented-stack]]
 [def __stack_allocator__ ['stack-allocator]]
 [def __stack_allocator_concept__ ['stack-allocator concept]]
 [def __stack__ ['stack]]
@@ -67,6 +68,7 @@
 [def __io_service__ ['boost::asio::io_sevice]]
 [def __server__ ['server]]
 [def __session__ ['session]]
+[def __stack_context__ ['boost::coroutines::stack_context]]
 [def __start__ ['session::start()]]
 [def __thread__ ['boost::thread]]
 [def __tie__ ['boost::tie]]

Modified: trunk/libs/coroutine/doc/stack.qbk
==============================================================================
--- trunk/libs/coroutine/doc/stack.qbk (original)
+++ trunk/libs/coroutine/doc/stack.qbk 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -15,20 +15,19 @@
 [heading __stack_allocator_concept__]
 A __stack_allocator__ must satisfy the __stack_allocator_concept__ requirements
 shown in the following table, in which `a` is an object of a
-__stack_allocator__ type, `p` is a `void *`, and `s` is a `std::size_t`:
+__stack_allocator__ type, `sctx` is a `stack_context`, and `size` is a `std::size_t`:
 
 [table
     [[expression][return type][notes]]
     [
- [`a.allocate( s)`]
- [`void *`]
- [returns a pointer to `s` bytes allocated from the stack]
+ [`a.allocate( sctx, size)`]
+ [`void`]
+ [creates a stack of at least `size` bytes and stores both values in `sctx`]
     ]
     [
- [`a.deallocate( p, s)`]
+ [`a.deallocate( sctx)`]
         [`void`]
- [deallocates `s` bytes of memory beginning at `p`,
- a pointer previously returned by `a.allocate()`]
+ [deallocates the stack created by `a.allocate()`]
     ]
 ]
 
@@ -68,9 +67,9 @@
 
             static std::size_t minimum_stacksize();
 
- void * allocate( std::size_t size);
+ void allocate( stack_context &, std::size_t size);
 
- void deallocate( void * sp, std::size_t size);
+ void deallocate( stack_context &);
         }
 
 [heading `static bool is_stack_unbound()`]
@@ -97,24 +96,69 @@
 environment (Win32 4kB/Win64 8kB, defined by rlimit on POSIX).]]
 ]
 
-[heading `void * allocate( std::size_t size)`]
+[heading `void allocate( stack_context & sctx, std::size_t size)`]
 [variablelist
 [[Preconditions:] [`minimum_stacksize() > size` and
 `! is_stack_unbound() && ( maximum_stacksize() < size)`.]]
-[[Effects:] [Allocates memory of `size` Bytes and appends one guard page at the
-end of the allocated memory.]]
+[[Effects:] [Allocates memory of at least `size` Bytes and stores a pointer
+to the stack and its actual size in `sctx`.]]
 [[Returns:] [Returns pointer to the start address of the new stack. Depending
 on the architecture the stack grows downwards/upwards the returned address is
 the highest/lowest address of the stack.]]
 ]
 
-[heading `void deallocate( void * sp, std::size_t size)`]
+[heading `void deallocate( stack_context & sctx)`]
 [variablelist
-[[Preconditions:] [`sp` is valid, `minimum_stacksize() > size` and
+[[Preconditions:] [`sctx.sp` is valid, `minimum_stacksize() > sctx.size` and
 `! is_stack_unbound() && ( maximum_stacksize() < size)`.]]
 [[Effects:] [Deallocates the stack space.]]
 ]
 
 [endsect]
 
+
+[section:stack_context Class ['stack_context]]
+
+__boost_coroutine__ provides the class __stack_context__ which will contain
+the stack pointer and the size of the stack.
+In case of a __segmented_stack__ __stack_context__ contains some extra controll
+structures.
+
+ struct stack_context
+ {
+ void * sp;
+ std::size_t size;
+
+ // might contain addition controll structures
+ // for instance for segmented stacks
+ }
+
+[heading `void * sp`]
+[variablelist
+[[Value:] [Pointer to the beginning of the stack.]]
+]
+
+[heading `std::size_t size`]
+[variablelist
+[[Value:] [Actual size of the stack.]]
+]
+
+[endsect]
+
+
+[section:segmented_stack Segmented stacks]
+
+__boost_coroutine__ supports usage of a __segmented_stack__, e. g. the size of the
+stack of a coroutine grows on demand. The coroutine is created with a stack with
+an minimal stack and if the coroutine is execute the stack size is increased as
+required.
+
+Segmented stack are currently only supported by [*gcc] from version [*4.7] onwards.
+n order to use __segmented_stack__ compile __boost_coroutine__ with
+[*cxxflags="-fsplit-stack -DBOOST_USE_SEGMENTED_STACKS" linkflags="-static-libgcc"]
+at b2/bjam command-line and compile the application using __boost_coroutine__ with
+[*cxxflags="-fsplit-stack -DBOOST_USE_SEGMENTED_STACKS"].
+
+[endsect]
+
 [endsect]

Modified: trunk/libs/coroutine/example/Jamfile.v2
==============================================================================
--- trunk/libs/coroutine/example/Jamfile.v2 (original)
+++ trunk/libs/coroutine/example/Jamfile.v2 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -31,23 +31,19 @@
 
 project boost/coroutine/example
     : requirements
- <library>/boost/context//boost_context
+ <library>../build//boost_coroutine
       <library>/boost/program_options//boost_program_options
       <library>/boost/system//boost_system
       <library>/boost/thread//boost_thread
- <define>BOOST_ALL_NO_LIB=1
+# <toolset>gcc-4.7:<cxxflags>-fsplit-stack
       <threading>multi
- <os>SOLARIS:<library>socket
- <os>SOLARIS:<library>nsl
- <os>NT:<define>_WIN32_WINNT=0x0501
- <os>NT,<toolset>gcc:<library>ws2_32
- <os>NT,<toolset>gcc:<library>mswsock
- <os>NT,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
- <os>HPUX,<toolset>gcc:<define>_XOPEN_SOURCE_EXTENDED
- <os>HPUX:<library>ipv6
       <link>static
     ;
 
+exe segmented_stack
+ : segmented_stack.cpp
+ ;
+
 exe fibonacci
     : fibonacci.cpp
     ;

Modified: trunk/libs/coroutine/example/fibonacci.cpp
==============================================================================
--- trunk/libs/coroutine/example/fibonacci.cpp (original)
+++ trunk/libs/coroutine/example/fibonacci.cpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -7,14 +7,10 @@
 #include <cstdlib>
 #include <iostream>
 
-#include <boost/assert.hpp>
 #include <boost/range.hpp>
 #include <boost/coroutine/all.hpp>
 
-typedef boost::coroutines::coroutine< int() > coro_t;
-typedef boost::range_iterator< coro_t >::type iterator_t;
-
-void fibonacci( coro_t::caller_type & c)
+void fibonacci( boost::coroutines::coroutine< void( int) > & c)
 {
     int first = 1, second = 1;
     while ( true)
@@ -28,9 +24,41 @@
 
 int main()
 {
- coro_t c( fibonacci);
- iterator_t it( boost::begin( c) );
- BOOST_ASSERT( boost::end( c) != it);
+ boost::coroutines::coroutine< int() > c( fibonacci);
+ boost::range_iterator<
+ boost::coroutines::coroutine< int() >
+ >::type it( boost::begin( c) );
+ for ( int i = 0; i < 10; ++i)
+ {
+ std::cout << * it << " ";
+ ++it;
+ }
+
+ std::cout << "\nDone" << std::endl;
+
+ return EXIT_SUCCESS;
+}
+
+// C++11
+#if 0
+int main()
+{
+ boost::coroutines::coroutine< int() > c(
+ [&]( boost::coroutines::coroutine< void( int) > & c) {
+ int first = 1, second = 1;
+ while ( true)
+ {
+ int third = first + second;
+ first = second;
+ second = third;
+ c( third);
+ }
+ });
+
+ boost::range_iterator<
+ boost::coroutines::coroutine< int() >
+ >::type it( boost::begin( c) );
+
     for ( int i = 0; i < 10; ++i)
     {
         std::cout << * it << " ";
@@ -41,3 +69,4 @@
 
     return EXIT_SUCCESS;
 }
+#endif

Added: trunk/libs/coroutine/example/segmented_stack.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/example/segmented_stack.cpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -0,0 +1,64 @@
+
+// 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 <iostream>
+
+#include <boost/assert.hpp>
+#include <boost/coroutine/all.hpp>
+#include <boost/thread.hpp>
+
+typedef boost::coroutines::coroutine< void() > coro_t;
+
+int count = 20;
+
+void access( char *buf) __attribute__ ((noinline));
+void access( char *buf)
+{
+ buf[0] = '\0';
+}
+void bar( int i)
+{
+ char buf[4 * 1024];
+
+ if ( i > 0)
+ {
+ access( buf);
+ std::cout << i << ". iteration" << std::endl;
+ bar( i - 1);
+ }
+}
+
+void foo( coro_t & c)
+{
+ bar( count);
+ c();
+}
+
+void thread_fn()
+{
+ {
+ coro_t c( foo);
+ c();
+ int i = 7;
+ }
+}
+
+int main( int argc, char * argv[])
+{
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+ std::cout << "using segmented stacks: allocates " << count << " * 4kB on stack, ";
+ std::cout << "initial stack size = " << boost::coroutines::stack_allocator::default_stacksize() / 1024 << "kB" << std::endl;
+ std::cout << "application should not fail" << std::endl;
+#else
+ std::cout << "using standard stacks: allocates " << count << " * 4kB on stack, ";
+ std::cout << "initial stack size = " << boost::coroutines::stack_allocator::default_stacksize() / 1024 << "kB" << std::endl;
+ std::cout << "application might fail" << std::endl;
+#endif
+
+ boost::thread( thread_fn).join();
+
+ return 0;
+}

Modified: trunk/libs/coroutine/performance/Jamfile.v2
==============================================================================
--- trunk/libs/coroutine/performance/Jamfile.v2 (original)
+++ trunk/libs/coroutine/performance/Jamfile.v2 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -16,9 +16,11 @@
 project boost/context/performance
     : requirements
       <library>/boost/context//boost_context
+ <library>/boost/coroutine//boost_coroutine
+ <toolset>gcc-4.7.2:<cxxflags>-fsplit-stack
       <link>static
       <linkflags>"-lrt"
- <threading>single
+ <threading>multi
     ;
 
 alias sources

Modified: trunk/libs/coroutine/performance/performance.cpp
==============================================================================
--- trunk/libs/coroutine/performance/performance.cpp (original)
+++ trunk/libs/coroutine/performance/performance.cpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -26,7 +26,6 @@
 #endif
 
 namespace coro = boost::coroutines;
-namespace ctx = boost::context;
 
 typedef coro::coroutine< void() > coro_t;
 
@@ -41,8 +40,12 @@
 #ifdef BOOST_CONTEXT_CYCLE
 cycle_t test_cycles( cycle_t ov, coro::flag_fpu_t preserve_fpu)
 {
- ctx::simple_stack_allocator< 8 * 1024 * 1024, 64 * 1024, 8 * 1024 > alloc;
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+ coro_t c( fn, coro::attributes( preserve_fpu) );
+#else
+ coro::simple_stack_allocator< 8 * 1024 * 1024, 64 * 1024, 8 * 1024 > alloc;
     coro_t c( fn, coro::attributes( preserve_fpu), alloc);
+#endif
 
     // cache warum-up
 BOOST_PP_REPEAT_FROM_TO( 0, COUNTER, CALL_COROUTINE, ~)
@@ -63,8 +66,12 @@
 #if _POSIX_C_SOURCE >= 199309L
 zeit_t test_zeit( zeit_t ov, coro::flag_fpu_t preserve_fpu)
 {
- ctx::simple_stack_allocator< 8 * 1024 * 1024, 64 * 1024, 8 * 1024 > alloc;
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+ coro_t c( fn, coro::attributes( preserve_fpu) );
+#else
+ coro::simple_stack_allocator< 8 * 1024 * 1024, 64 * 1024, 8 * 1024 > alloc;
     coro_t c( fn, coro::attributes( preserve_fpu), alloc);
+#endif
 
     // cache warum-up
 BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_COROUTINE, ~)

Modified: trunk/libs/coroutine/performance/simple_stack_allocator.hpp
==============================================================================
--- trunk/libs/coroutine/performance/simple_stack_allocator.hpp (original)
+++ trunk/libs/coroutine/performance/simple_stack_allocator.hpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -15,13 +15,14 @@
 #include <boost/config.hpp>
 
 #include <boost/context/detail/config.hpp>
+#include <boost/coroutine/stack_context.hpp>
 
 #ifdef BOOST_HAS_ABI_HEADERS
 # include BOOST_ABI_PREFIX
 #endif
 
 namespace boost {
-namespace context {
+namespace coroutines {
 
 template< std::size_t Max, std::size_t Default, std::size_t Min >
 class simple_stack_allocator
@@ -36,7 +37,7 @@
     static std::size_t minimum_stacksize()
     { return Min; }
 
- void * allocate( std::size_t size) const
+ void allocate( stack_context & ctx, std::size_t size)
     {
         BOOST_ASSERT( minimum_stacksize() <= size);
         BOOST_ASSERT( maximum_stacksize() >= size);
@@ -44,16 +45,17 @@
         void * limit = std::calloc( size, sizeof( char) );
         if ( ! limit) throw std::bad_alloc();
 
- return static_cast< char * >( limit) + size;
+ ctx.size = size;
+ ctx.sp = static_cast< char * >( limit) + ctx.size;
     }
 
- void deallocate( void * vp, std::size_t size) const
+ void deallocate( stack_context & ctx)
     {
- BOOST_ASSERT( vp);
- BOOST_ASSERT( minimum_stacksize() <= size);
- BOOST_ASSERT( maximum_stacksize() >= size);
+ BOOST_ASSERT( ctx.sp);
+ BOOST_ASSERT( minimum_stacksize() <= ctx.size);
+ BOOST_ASSERT( maximum_stacksize() >= ctx.size);
 
- void * limit = static_cast< char * >( vp) - size;
+ void * limit = static_cast< char * >( ctx.sp) - ctx.size;
         std::free( limit);
     }
 };

Added: trunk/libs/coroutine/src/detail/coroutine_context.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/src/detail/coroutine_context.cpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -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)
+
+#define BOOST_COROUTINES_SOURCE
+
+#include "boost/coroutine/detail/coroutine_context.hpp"
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+extern "C" {
+
+void __splitstack_getcontext( void * [BOOST_COROUTINES_SEGMENTS]);
+
+void __splitstack_setcontext( void * [BOOST_COROUTINES_SEGMENTS]);
+
+void __splitstack_releasecontext (void * [BOOST_COROUTINES_SEGMENTS]);
+
+void __splitstack_block_signals_context( void * [BOOST_COROUTINES_SEGMENTS], int *, int *);
+
+}
+#endif
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+coroutine_context::coroutine_context() :
+ fcontext_t(), stack_ctx_( this), ctx_( this)
+{
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+ __splitstack_getcontext( stack_ctx_->segments_ctx);
+#endif
+}
+
+coroutine_context::coroutine_context( ctx_fn fn, stack_context * stack_ctx) :
+ fcontext_t(), stack_ctx_( stack_ctx),
+ ctx_( context::make_fcontext( stack_ctx_->sp, stack_ctx_->size, fn) )
+{}
+
+coroutine_context::coroutine_context( coroutine_context const& other) :
+ fcontext_t(),
+ stack_ctx_( other.stack_ctx_),
+ ctx_( other.ctx_)
+{}
+
+coroutine_context &
+coroutine_context::operator=( coroutine_context const& other)
+{
+ if ( this == & other) return * this;
+
+ stack_ctx_ = other.stack_ctx_;
+ ctx_ = other.ctx_;
+
+ return * this;
+}
+
+intptr_t
+coroutine_context::jump( coroutine_context & other, intptr_t param, bool preserve_fpu)
+{
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+ if ( stack_ctx_)
+ __splitstack_getcontext( stack_ctx_->segments_ctx);
+ if ( other.stack_ctx_)
+ __splitstack_setcontext( other.stack_ctx_->segments_ctx);
+#endif
+ return context::jump_fcontext( ctx_, other.ctx_, param, preserve_fpu);
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+ if ( stack_ctx_)
+ __splitstack_setcontext( stack_ctx_->segments_ctx);
+#endif
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif

Added: trunk/libs/coroutine/src/detail/segmented_stack_allocator.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/src/detail/segmented_stack_allocator.cpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -0,0 +1,93 @@
+
+// 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)
+
+#define BOOST_COROUTINES_SOURCE
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+
+#include <boost/coroutine/detail/segmented_stack_allocator.hpp>
+
+#include <boost/assert.hpp>
+#include <boost/context/fcontext.hpp>
+
+#include <boost/coroutine/stack_context.hpp>
+
+extern "C" {
+
+void *__splitstack_makecontext( std::size_t,
+ void * [BOOST_COROUTINES_SEGMENTS],
+ std::size_t *);
+
+void __splitstack_releasecontext( void * [BOOST_COROUTINES_SEGMENTS]);
+
+void __splitstack_resetcontext( void * [BOOST_COROUTINES_SEGMENTS]);
+
+void __splitstack_block_signals_context( void * [BOOST_COROUTINES_SEGMENTS],
+ int * new_value, int * old_value);
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+#if !defined (SIGSTKSZ)
+# define SIGSTKSZ (8 * 1024)
+# define UDEF_SIGSTKSZ
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+bool
+segmented_stack_allocator::is_stack_unbound()
+{ return true; }
+
+std::size_t
+segmented_stack_allocator::minimum_stacksize()
+{ return SIGSTKSZ + sizeof( context::fcontext_t) + 15; }
+
+std::size_t
+segmented_stack_allocator::default_stacksize()
+{ return minimum_stacksize(); }
+
+std::size_t
+segmented_stack_allocator::maximum_stacksize()
+{
+ BOOST_ASSERT_MSG( false, "segmented stack is unbound");
+ return 0;
+}
+
+void
+segmented_stack_allocator::allocate( stack_context & ctx, std::size_t size)
+{
+ BOOST_ASSERT( default_stacksize() <= size);
+
+ void * limit = __splitstack_makecontext( size, ctx.segments_ctx, & ctx.size);
+ BOOST_ASSERT( limit);
+ ctx.sp = static_cast< char * >( limit) + ctx.size;
+
+ int off = 0;
+ __splitstack_block_signals_context( ctx.segments_ctx, & off, 0);
+}
+
+void
+segmented_stack_allocator::deallocate( stack_context & ctx)
+{
+ __splitstack_releasecontext( ctx.segments_ctx);
+}
+
+}}}
+
+#ifdef UDEF_SIGSTKSZ
+# undef SIGSTKSZ
+#endif
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif

Added: trunk/libs/coroutine/src/detail/standard_stack_allocator_posix.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/src/detail/standard_stack_allocator_posix.cpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -0,0 +1,163 @@
+
+// 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)
+
+#define BOOST_COROUTINES_SOURCE
+
+#include "boost/coroutine/detail/standard_stack_allocator.hpp"
+
+extern "C" {
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+}
+
+//#if _POSIX_C_SOURCE >= 200112L
+
+#include <algorithm>
+#include <cmath>
+#include <cstring>
+#include <stdexcept>
+
+#include <boost/assert.hpp>
+#include <boost/context/fcontext.hpp>
+
+#include <boost/coroutine/stack_context.hpp>
+
+#if !defined (SIGSTKSZ)
+# define SIGSTKSZ (8 * 1024)
+# define UDEF_SIGSTKSZ
+#endif
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+std::size_t pagesize()
+{
+ // conform to POSIX.1-2001
+ static std::size_t size = ::sysconf( _SC_PAGESIZE);
+ return size;
+}
+
+rlimit stacksize_limit_()
+{
+ rlimit limit;
+ // conforming to POSIX.1-2001
+#if defined(BOOST_DISABLE_ASSERTS)
+ ::getrlimit( RLIMIT_STACK, & limit);
+#else
+ const int result = ::getrlimit( RLIMIT_STACK, & limit);
+ BOOST_ASSERT( 0 == result);
+#endif
+ return limit;
+}
+
+rlimit stacksize_limit()
+{
+ static rlimit limit = stacksize_limit_();
+ return limit;
+}
+
+std::size_t page_count( std::size_t stacksize)
+{
+ return static_cast< std::size_t >(
+ std::ceil(
+ static_cast< float >( stacksize) / pagesize() ) );
+}
+
+bool
+standard_stack_allocator::is_stack_unbound()
+{ return RLIM_INFINITY == detail::stacksize_limit().rlim_max; }
+
+std::size_t
+standard_stack_allocator::default_stacksize()
+{
+ std::size_t size = 8 * minimum_stacksize();
+ if ( is_stack_unbound() ) return size;
+
+ BOOST_ASSERT( maximum_stacksize() >= minimum_stacksize() );
+ return maximum_stacksize() == size
+ ? size
+ : (std::min)( size, maximum_stacksize() );
+}
+
+std::size_t
+standard_stack_allocator::minimum_stacksize()
+{ return SIGSTKSZ + sizeof( context::fcontext_t) + 15; }
+
+std::size_t
+standard_stack_allocator::maximum_stacksize()
+{
+ BOOST_ASSERT( ! is_stack_unbound() );
+ return static_cast< std::size_t >( detail::stacksize_limit().rlim_max);
+}
+
+void
+standard_stack_allocator::allocate( stack_context & ctx, std::size_t size)
+{
+ BOOST_ASSERT( minimum_stacksize() <= size);
+ BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) );
+
+ const std::size_t pages( detail::page_count( size) + 1); // add one guard page
+ const std::size_t size_( pages * detail::pagesize() );
+ BOOST_ASSERT( 0 < size && 0 < size_);
+
+ const int fd( ::open("/dev/zero", O_RDONLY) );
+ BOOST_ASSERT( -1 != fd);
+ // conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L)
+ void * limit =
+# if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+ ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+# else
+ ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+# endif
+ ::close( fd);
+ if ( ! limit) throw std::bad_alloc();
+
+ std::memset( limit, '\0', size_);
+
+ // conforming to POSIX.1-2001
+#if defined(BOOST_DISABLE_ASSERTS)
+ ::mprotect( limit, detail::pagesize(), PROT_NONE);
+#else
+ const int result( ::mprotect( limit, detail::pagesize(), PROT_NONE) );
+ BOOST_ASSERT( 0 == result);
+#endif
+
+ ctx.size = size_;
+ ctx.sp = static_cast< char * >( limit) + ctx.size;
+}
+
+void
+standard_stack_allocator::deallocate( stack_context & ctx)
+{
+ BOOST_ASSERT( ctx.sp);
+ BOOST_ASSERT( minimum_stacksize() <= ctx.size);
+ BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= ctx.size) );
+
+ void * limit = static_cast< char * >( ctx.sp) - ctx.size;
+ // conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L)
+ ::munmap( limit, ctx.size);
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#ifdef UDEF_SIGSTKSZ
+# undef SIGSTKSZ
+#endif

Added: trunk/libs/coroutine/src/detail/standard_stack_allocator_windows.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/src/detail/standard_stack_allocator_windows.cpp 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -0,0 +1,155 @@
+
+// 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)
+
+#define BOOST_COROUTINES_SOURCE
+
+#include "boost/coroutine/detail/standard_stack_allocator.hpp"
+
+extern "C" {
+#include <windows.h>
+}
+
+//#if defined (BOOST_WINDOWS) || _POSIX_C_SOURCE >= 200112L
+
+#include <algorithm>
+#include <cmath>
+#include <cstddef>
+#include <cstring>
+#include <stdexcept>
+
+#include <boost/assert.hpp>
+#include <boost/context/detail/config.hpp>
+#include <boost/context/fcontext.hpp>
+
+#include <boost/coroutine/stack_context.hpp>
+
+# if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4244 4267)
+# endif
+
+// x86_64
+// test x86_64 before i386 because icc might
+// define __i686__ for x86_64 too
+#if defined(__x86_64__) || defined(__x86_64) \
+ || defined(__amd64__) || defined(__amd64) \
+ || defined(_M_X64) || defined(_M_AMD64)
+
+// Windows seams not to provide a constant or function
+// telling the minimal stacksize
+# define MIN_STACKSIZE 8 * 1024
+#else
+# define MIN_STACKSIZE 4 * 1024
+#endif
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+SYSTEM_INFO system_info_()
+{
+ SYSTEM_INFO si;
+ ::GetSystemInfo( & si);
+ return si;
+}
+
+SYSTEM_INFO system_info()
+{
+ static SYSTEM_INFO si = system_info_();
+ return si;
+}
+
+std::size_t pagesize()
+{ return static_cast< std::size_t >( system_info().dwPageSize); }
+
+std::size_t page_count( std::size_t stacksize)
+{
+ return static_cast< std::size_t >(
+ std::ceil(
+ static_cast< float >( stacksize) / pagesize() ) );
+}
+
+// Windows seams not to provide a limit for the stacksize
+bool
+standard_stack_allocator::is_stack_unbound()
+{ return true; }
+
+std::size_t
+standard_stack_allocator::default_stacksize()
+{
+ std::size_t size = 64 * 1024; // 64 kB
+ if ( is_stack_unbound() )
+ return (std::max)( size, minimum_stacksize() );
+
+ BOOST_ASSERT( maximum_stacksize() >= minimum_stacksize() );
+ return maximum_stacksize() == minimum_stacksize()
+ ? minimum_stacksize()
+ : ( std::min)( size, maximum_stacksize() );
+}
+
+// because Windows seams not to provide a limit for minimum stacksize
+std::size_t
+standard_stack_allocator::minimum_stacksize()
+{ return MIN_STACKSIZE; }
+
+// because Windows seams not to provide a limit for maximum stacksize
+// maximum_stacksize() can never be called (pre-condition ! is_stack_unbound() )
+std::size_t
+standard_stack_allocator::maximum_stacksize()
+{
+ BOOST_ASSERT( ! is_stack_unbound() );
+ return 1 * 1024 * 1024 * 1024; // 1GB
+}
+
+void
+standard_stack_allocator::allocate( stack_context & ctx, std::size_t size)
+{
+ BOOST_ASSERT( minimum_stacksize() <= size);
+ BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) );
+
+ const std::size_t pages( detail::page_count( size) + 1); // add one guard page
+ const std::size_t size_ = pages * detail::pagesize();
+ BOOST_ASSERT( 0 < size && 0 < size_);
+
+ void * limit = ::VirtualAlloc( 0, size_, MEM_COMMIT, PAGE_READWRITE);
+ if ( ! limit) throw std::bad_alloc();
+
+ std::memset( limit, '\0', size_);
+
+ DWORD old_options;
+#if defined(BOOST_DISABLE_ASSERTS)
+ ::VirtualProtect(
+ limit, detail::pagesize(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
+#else
+ const BOOL result = ::VirtualProtect(
+ limit, detail::pagesize(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
+ BOOST_ASSERT( FALSE != result);
+#endif
+
+ ctx.size = size_;
+ ctx.sp = static_cast< char * >( limit) + ctx.size;
+}
+
+void
+standard_stack_allocator::deallocate( stack_context & ctx)
+{
+ BOOST_ASSERT( ctx.sp);
+ BOOST_ASSERT( minimum_stacksize() <= ctx.size);
+ BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= ctx.size) );
+
+ void * limit = static_cast< char * >( ctx.sp) - ctx.size;
+ ::VirtualFree( limit, 0, MEM_RELEASE);
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif

Modified: trunk/libs/coroutine/test/Jamfile.v2
==============================================================================
--- trunk/libs/coroutine/test/Jamfile.v2 (original)
+++ trunk/libs/coroutine/test/Jamfile.v2 2013-02-12 14:01:29 EST (Tue, 12 Feb 2013)
@@ -17,6 +17,8 @@
     : requirements
       <library>../../test/build//boost_unit_test_framework
       <library>/boost/context//boost_context
+ <library>/boost/coroutine//boost_coroutine
+# <toolset>gcc-4.7:<cxxflags>-fsplit-stack
       <link>static
     ;
 


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