$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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
     ;